Com Ibm Etools Egl PG PDF

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 630

Rational Business Developer 

EGL Programmer’s Guide


Version 7 Release 5.1
Rational Business Developer 

EGL Programmer’s Guide


Version 7 Release 5.1
Note
Before using this information and the product it supports, read the information in “Notices,” on page 609.

This edition applies to version 7.1 of Rational Business Developer and to all subsequent releases and modifications
until otherwise indicated in new editions.
© Copyright International Business Machines Corporation 1996, 2008.
US Government Users Restricted Rights – Use, duplication or disclosure restricted by GSA ADP Schedule Contract
with IBM Corp.
Contents
Introduction . . . . . . . . . . . . . 1 Introduction to data parts . . . . . . . . 97
Using EGL with the Eclipse IDE . . . . . . . . 1 Introduction to logic parts . . . . . . . . 105
A typical EGL development workbench . . . . 2 Introduction to build parts . . . . . . . . 120
Other windows EGL developers commonly use. . 4 Renaming parts . . . . . . . . . . . 120
Other views and editors EGL developers Moving parts . . . . . . . . . . . . 121
commonly use . . . . . . . . . . . . . 5 Properties . . . . . . . . . . . . . . 122
How the workbench is organized . . . . . . 9 Import and use statements . . . . . . . . . 124
Other information on the workbench . . . . . 11
Enabling EGL capabilities. . . . . . . . . . 11 Working with EGL code . . . . . . . 127
What’s new in EGL V7.5 . . . . . . . . . . 12 Common programming tasks . . . . . . . . 127
What’s new in EGL V7.1 . . . . . . . . . . 13 Turning lines of code into comment lines . . . 128
Language changes in EGL V7.1 . . . . . . . 14 Calling Java . . . . . . . . . . . . . 128
Changes to parts in EGL V7.1 . . . . . . . 14 Calling C functions with the call statement . . 131
Changes to system libraries and variables in EGL Calling C functions through EGL libraries . . . 133
V7.1 . . . . . . . . . . . . . . . . 15 Working with substrings . . . . . . . . 146
Changes to build descriptor options in EGL V7.1 16 Encrypting passwords . . . . . . . . . 146
User interface changes in EGL V7.1 . . . . . 17 Handling errors . . . . . . . . . . . 148
What’s new in EGL V7.0 . . . . . . . . . . 18 Customizing runtime messages . . . . . . 152
Language changes in EGL V7.0 . . . . . . . 19 The EGL editor . . . . . . . . . . . . . 155
Validation changes in EGL V7.0 . . . . . . 24 Content assist . . . . . . . . . . . . . 157
Validation changes in EGL V7.0 . . . . . . 26 Code templates. . . . . . . . . . . . 158
Changes to parts in EGL V7.0 . . . . . . . 28 Code snippets . . . . . . . . . . . . . 164
Changes to system libraries and variables in EGL Inserting code snippets into EGL and JSP files 165
V7.0 . . . . . . . . . . . . . . . . 32 Using cheat sheets. . . . . . . . . . . . 166
Changes to build descriptor options in EGL V7.0 35 Editing DataItem parts with the source assistant 167
Changes to exception handling in EGL V7.0 . . 36 Searching for EGL files and parts . . . . . . . 168
Changes to services in EGL V7.0 . . . . . . 36 Searching for parts . . . . . . . . . . 168
User interface changes in EGL V7.0 . . . . . 37 Viewing lists of parts . . . . . . . . . . 169
Migrating from a previous version of EGL . . . . 38 Viewing part references . . . . . . . . . 171
Setting EGL-to-EGL migration preferences . . . 42 Locating an EGL source file in the Project
Migrating EGL code to EGL V7.0 . . . . . . 43 Explorer view . . . . . . . . . . . . 172
Migrating EGL code to EGL V6.0 iFix 001 . . . 56 Preferences . . . . . . . . . . . . . . 172
Setting general preferences . . . . . . . . 173
Contents of an EGL application . . . . 67 Setting build descriptor preferences . . . . . 174
Introduction to EGL projects . . . . . . . . . 70 Setting preferences for the EGL editor . . . . 175
Creating an EGL project . . . . . . . . . 71 Setting the fonts used in the EGL editor . . . 176
Creating an EGL Web project . . . . . . . 73 Setting preferences for folding in the EGL editor 176
Creating an EGL plug-in project . . . . . . 74 Setting preferences for formatting in the EGL
Renaming an EGL project. . . . . . . . . 75 editor . . . . . . . . . . . . . . . 177
Features and facets of EGL projects . . . . . 76 Setting preferences for organizing import
Sharing projects . . . . . . . . . . . . 79 statements in the EGL editor . . . . . . . 178
The EGL build path . . . . . . . . . . 83 Setting preferences for source styles . . . . . 179
Source folders . . . . . . . . . . . . . 86 Setting generation preferences . . . . . . . 180
Creating source folders . . . . . . . . . 87 Setting preferences for EGL text . . . . . . 180
Introduction to EGL packages . . . . . . . . 87
Creating an EGL package . . . . . . . . . 89 Accessing data with EGL code . . . . 183
Introduction to EGL files . . . . . . . . . . 89 Common data access tasks . . . . . . . . . 183
Creating EGL source files . . . . . . . . . 90 Reading and writing records . . . . . . . 184
Renaming a source file . . . . . . . . . 91 Writing and reading to files . . . . . . . 186
Moving a source file . . . . . . . . . . 92 Specifying database options at project creation 189
Deleting a source file . . . . . . . . . . 93 Accessing an LDAP-compliant server . . . . 190
Creating EGL build files . . . . . . . . . 94 Working with SQL data . . . . . . . . . . 190
Creating a deployment descriptor . . . . . . 94 Best practices . . . . . . . . . . . . 191
Introduction to EGL parts . . . . . . . . . 95 Result-set processing . . . . . . . . . . 192
Generatable parts and non-generatable parts . . 96 SQL records and their uses . . . . . . . . 193

© Copyright IBM Corp. 1996, 2008 iii


Compatibility . . . . . . . . . . . . 196 Transfer to a non-EGL program using either
Creating an SQL database connection . . . . 197 transfer to program or transfer to transaction. . 271
Supported SQL database managers . . . . . 200 Transfer from a non-EGL program to an EGL
Using an SQL database connection at run time 202 program using OS XCTL . . . . . . . . 272
Editing or deleting an SQL database connection 205 Reference information for transfers . . . . . 272
Retrieving SQL table data . . . . . . . . 205 Transferring control in the IMS/VS environment 275
Creating a data access application . . . . . 208 Transferring between conversational programs 276
Working with SQL statements . . . . . . . 211 Transferring between nonconversational
Setting preferences for SQL database programs . . . . . . . . . . . . . . 281
connections . . . . . . . . . . . . . 219 Interfacing through serial files in IMS . . . . 284
Setting preferences for SQL retrieve . . . . . 220 Reference information for IMS/VS transfers . . 286
Working with DL/I data . . . . . . . . . 221 Transferring to and from IMSADF II programs . . 293
Example DL/I database . . . . . . . . . 223 IMSADF II conversational processing . . . . 294
DL/I examples . . . . . . . . . . . . 227 Transferring with conversational programs in
Working with MQ message queues . . . . . . 235 ADF mode . . . . . . . . . . . . . 295
Defining messages in EGL . . . . . . . . 236 Transferring control in the iSeries COBOL
Defining resource associations for message environment. . . . . . . . . . . . . . 299
queues . . . . . . . . . . . . . . 237 Transferring control in the iSeries RPG
Reading from and writing to message queues 238 environment. . . . . . . . . . . . . . 300
Using direct MQ API calls . . . . . . . . 240 Calling to and from Java programs . . . . . . 300
Using linkage options for MQ run-time library EGL-generated Java program to EGL-generated
selection . . . . . . . . . . . . . . 242 Java program . . . . . . . . . . . . 300
Working with iSeries objects . . . . . . . . 244 Non-EGL Java program to EGL program . . . 300
Working with bidirectional data . . . . . . . 245 EGL-generated Java program to non-EGL Java
Creating a bidirectional runtime file . . . . . 247 program . . . . . . . . . . . . . . 301
Creating a bidirectional conversion table . . . 249 EGL-generated Java program to DLL . . . . 301
EGL-generated Java program to .EXE or .BAT
Transfer of control across programs 251 file . . . . . . . . . . . . . . . . 301
Reference information for special parameters on Calling an IMS program from EGL-generated
call or transfer statement . . . . . . . . . 252 Java code . . . . . . . . . . . . . . 301
Format of a text or print form passed on a call 252
Format of the dliLib.psbData structure . . . . 253 Developing EGL programs for the
Format of a PCBRecord . . . . . . . . . 253 VSE environment. . . . . . . . . . 305
Calling programs in CICS environments . . . . 254
Format of call statement parameters for CICS 256 Developing EGL programs for the IMS
Calls from an EGL program to an EGL program 259
Calls from an EGL program to a non-EGL
environment . . . . . . . . . . . . 307
program . . . . . . . . . . . . . . 259 Generating for the MPP region . . . . . . . 307
Calls from a non-EGL program to an EGL Text UI programs . . . . . . . . . . . 307
program . . . . . . . . . . . . . . 261 Basic programs . . . . . . . . . . . . 308
Transferring control in CICS environments . . . 261 Generating for the MPP IMS FastPath region . . . 308
Transfer to program . . . . . . . . . . 262 Generating for the IMS BMP region . . . . . . 309
Transfer to transaction . . . . . . . . . 263 Effect of build descriptor options . . . . . . . 310
Transfer using show . . . . . . . . . . 265 EGL support for runtime PSBs and PCBs . . . . 310
Using asynchronous tasks . . . . . . . . 265 Requirements for the PSB record part . . . . 313
Calling programs in IMS and z/OS batch Interacting with terminals in IMS. . . . . . . 315
environments . . . . . . . . . . . . . 267 Defining forms for IMS programs . . . . . . 317
Calls from an EGL program to an EGL program 268 Estimating the size of MFS blocks for a
Calls from an EGL program to a non-EGL formGroup . . . . . . . . . . . . . 318
program . . . . . . . . . . . . . . 268 Using serial and print files in IMS . . . . . . 319
Calls from a non-EGL program to an EGL Using serial files as GSAM files . . . . . . 319
program . . . . . . . . . . . . . . 268 Using serial files as message queues . . . . . 320
Calling a CICS program from an EGL z/OS Defining records to use with message queues 321
batch program . . . . . . . . . . . . 269 Checking the results of serial file I/O statements 321
Transferring control in IMS BMP and z/OS batch Using print files as message queues . . . . . 322
environments . . . . . . . . . . . . . 270 Example IMS program code . . . . . . . . 322
Transfer from an EGL program to an EGL Example of output to a serial file associated
program using transfer to program . . . . . 271 with a message queue . . . . . . . . . 322
Transfer from an EGL program to an EGL Example of IMS batch processing. . . . . . 324
program using transfer to transaction . . . . 271 Mutliple users and message queues . . . . . 324

iv EGL Programmer’s Guide


Overview of EGL Rich UI . . . . . . 327 Inter-Portlet Communication . . . . . . . . 470
Starting to work with EGL Rich UI . . . . . . 329 J2EELib . . . . . . . . . . . . . . . 471
Understanding how browsers handle a Rich UI Creating a Web Page . . . . . . . . . . . 471
application . . . . . . . . . . . . . . 334 Adding a Portlet to the Application . . . . . . 472
Introduction to the EGL Rich UI editor . . . . . 337 Adding Support for Additional Portlet Modes . . 473
Opening the EGL Rich UI editor . . . . . . 339
Creating a Web interface in the Rich UI editor 340 Overview of service-oriented
Running a Web application in the EGL Rich UI architecture (SOA) . . . . . . . . . 475
editor . . . . . . . . . . . . . . . 344 Elements of a service-oriented application . . . . 478
Setting preferences for Rich UI . . . . . . . 345 Types of services . . . . . . . . . . . . 481
Setting preferences for Rich UI appearance . . 347 Calling a local service . . . . . . . . . . 483
Setting preferences for Rich UI bidirectional text 349 Calling a remote service . . . . . . . . . . 485
Setting preferences for Rich UI deployment . . 351 Adding service client binding information for an
Securing a Rich UI application . . . . . . . 352 EGL service . . . . . . . . . . . . . . 487
Overview of Rich UI security . . . . . . . 352 Adding service client binding information from a
Resources to secure . . . . . . . . . . 355 WSDL file . . . . . . . . . . . . . . 489
JSF versus Rich UI applications . . . . . . 357 Creating a service-access variable and binding it to
Using Web container-managed (JEE) a service . . . . . . . . . . . . . . . 491
authentication . . . . . . . . . . . . 357 Exposing a service to other applications . . . . 493
Using application-managed (custom) Adding Web service deployment information to
authentication . . . . . . . . . . . . 362 the deployment descriptor . . . . . . . . 496
Authentication summary . . . . . . . . 367 Creating and using a shared protocol . . . . . 497
Authorization . . . . . . . . . . . . 368 Setting preferences for service generation . . . . 498
JEE security example . . . . . . . . . . 369
Sample login and error pages for JEE
Building EGL Text User Interface
form-based authentication . . . . . . . . 374
Preventing client-side security threats . . . . 376 applications . . . . . . . . . . . . 499
Overview of SSL . . . . . . . . . . . 377 Example . . . . . . . . . . . . . . . 499
IBM Rational AppScan . . . . . . . . . 386 Elements of a text user interface application . . . 500
Building EGL Text User Interface applications with
the Text Form editor . . . . . . . . . . . 500
Building EGL JSF Web applications 389
Creating a simple text or print form . . . . . 502
Elements of a JSF Web application . . . . . . 389
Creating a constant field. . . . . . . . . 502
Common tasks in Web applications . . . . . . 391
Creating a variable field . . . . . . . . . 503
Creating a Web page . . . . . . . . . . 392
Creating a form from a template . . . . . . 505
Localizing text in Web applications . . . . . 426
Filtering the editor . . . . . . . . . . 509
Updating portions of a Web page with AJAX
Display options for the EGL Text Form editor 510
requests . . . . . . . . . . . . . . 432
Setting preferences for the Text Form editor . . 510
Running a Web page on a server . . . . . . 448
Setting bidirectional text preferences for the Text
Using the i5/OS integrated Web application
Form editor . . . . . . . . . . . . . 511
server . . . . . . . . . . . . . . . 449
Setting preferences for the Text Form editor
Using JEE container-managed security . . . . . 452
palette entries . . . . . . . . . . . . 512
Accessing the JSF component tree with the source
assistant . . . . . . . . . . . . . . . 454
Changing the target of a JSF link . . . . . . 457 Building EGL Console User Interface
Changing the style of a JSF control . . . . . 458 applications . . . . . . . . . . . . 513
Changing the style class of a JSF control . . . 459 Elements of a Console UI application . . . . . 513
Setting event handlers for a JSF control. . . . 460 Creating a Console User Interface . . . . . . 516
Setting the size of a JSF image. . . . . . . 461 Adding rich client widgets to a Console UI
Enabling or disabling JSF controls . . . . . 462 program . . . . . . . . . . . . . . . 519
Setting JSF data table properties . . . . . . 463 Adding a button widget . . . . . . . . . 520
Adding JSF component interface support to an Adding a check box widget . . . . . . . 522
EGL Web project . . . . . . . . . . . . 464 Adding a single-selection widget . . . . . . 524
Setting preferences for Web projects . . . . . . 465 Running Console UI applications . . . . . . . 528
Console UI modes . . . . . . . . . . . . 529
Building EGL portlet applications. . . 467
Portlet overview . . . . . . . . . . . . 467 Creating reports with EGL . . . . . . 531
Prerequisites. . . . . . . . . . . . . . 468 JasperReports engine . . . . . . . . . . . 531
Elements of a Portlet Application . . . . . . . 468 BIRT engine . . . . . . . . . . . . . . 531
JSF Handler part . . . . . . . . . . . 468 EGL text report engine . . . . . . . . . . 531
Managing Portlet Sessions . . . . . . . . . 469 Creating reports with JasperReports . . . . . . 532

Contents v
Elements of an EGL JasperReport application 533 Using breakpoints in the EGL debugger . . . . 584
Creating the JasperReport design file . . . . 534 Viewing variables in the EGL debugger . . . . 585
Writing code to drive a report of type Prerequisites. . . . . . . . . . . . . 585
JasperReport. . . . . . . . . . . . . 538 Variables and breakpoints . . . . . . . . 585
Creating an EGL JasperReport handler . . . . 541 Displaying and changing values . . . . . . 585
Running a report of type JasperReport . . . . 545 Buttons in the Variables view . . . . . . . 586
Using JasperReport templates . . . . . . . 546 Making code updates while debugging an
Creating JasperReport subreports . . . . . . 547 application . . . . . . . . . . . . . . 587
Adding support for Jasper reports to a project 549 Starting the EGL debugger for EGL projects . . . 588
Creating reports with BIRT . . . . . . . . . 551 Creating a launch configuration in the EGL
Adding support for BIRT reports to a project 553 debugger . . . . . . . . . . . . . . 588
Creating an EGL BIRT handler . . . . . . 555 Creating an EGL Listener launch configuration 589
Creating EGL text reports . . . . . . . . . 556 Starting a non-JEE application in the EGL
Handler events for a text report . . . . . . 557 debugger . . . . . . . . . . . . . . 590
Writing code to print a text report . . . . . 558 Invoking the EGL debugger from generated
Java code . . . . . . . . . . . . . . 591
Working with Web transaction Debugging Web projects with the EGL debugger 592
applications in EGL. . . . . . . . . 561 Configuring a server for EGL Web debugging 592
Starting an EGL Web debugging session . . . 594
Customizing JSP files . . . . . . . . . . . 561
Debugging services with the EGL debugger . . . 595
Adding Web transaction support to an EGL Web
Prerequisites. . . . . . . . . . . . . 595
project. . . . . . . . . . . . . . . . 562
Debugging a local service . . . . . . . . 595
Web transaction configuration files . . . . . . 563
Debugging IMS and DL/I applications . . . . . 596
Running VGWebTransaction programs . . . . . 564
Prerequisites. . . . . . . . . . . . . 596
Using VGUIRecord properties . . . . . . . . 564
Host configuration . . . . . . . . . . 597
Other controls . . . . . . . . . . . . 566
Local workspace configuration . . . . . . 599
Using JavaServer pages with Web transactions . . 567
Starting the DLI Debug Server on the z/OS host 601
Transferring control between JSF Handlers and
Character encoding options for the EGL debugger 603
Web transactions . . . . . . . . . . . . 569
Setting preferences for the EGL debugger . . . . 604
UI record bean API . . . . . . . . . . . 570
General preferences . . . . . . . . . . 605
Debug behavior mapping . . . . . . . . 606
Debugging EGL applications . . . . . 573
Stepping through an application in the EGL
Appendix. Notices . . . . . . . . . 609
debugger . . . . . . . . . . . . . . . 575
Programming interface information . . . . . . 611
Debugging an EGL batch program . . . . . . 579
Trademarks and service marks. . . . . . . . 611
EGL debugger commands . . . . . . . . . 580
How build descriptor settings affect the EGL
debugger . . . . . . . . . . . . . . . 583 Index . . . . . . . . . . . . . . . 613

vi EGL Programmer’s Guide


Introduction
These topics explain the fundamentals of using EGL in the Eclipse IDE, as well as
changes to the EGL language and IDE in this version.
Related concepts
“Using EGL with the Eclipse IDE”
The Eclipse IDE offers a graphical user interface (GUI) called the workbench, in
which users perform work by pointing and clicking objects on the screen as
well as by typing code. In this way, when you are working with EGL, you are
using the Eclipse workbench, so it is worth taking a minute to look at the tools
in the workbench.
“Enabling EGL capabilities” on page 11
Capabilities keep the workbench menus from becoming cluttered by hiding
items you do not use. You can always perform these tasks, but to make them
appear in the menus, you must enable the capability for that area of
functionality.
“What’s new in EGL V7.1” on page 13
“What’s new in EGL V7.0” on page 18
“Migrating from a previous version of EGL” on page 38

Using EGL with the Eclipse IDE


The Eclipse IDE offers a graphical user interface (GUI) called the workbench, in
which users perform work by pointing and clicking objects on the screen as well as
by typing code. In this way, when you are working with EGL, you are using the
Eclipse workbench, so it is worth taking a minute to look at the tools in the
workbench.

While developing EGL applications, you use the workbench to manage your files,
write your code, and test and deploy your application. The workbench includes
code editors similar to editors for other programming languages, but it also
includes a range of graphical tools for working with EGL code and the many other
types of code and files that the workbench understands.

Eclipse gives you the ability to change the set of tools that it offers and choose
which tools appear in the interface. Each different tool set is called a perspective,
and the windows within a perspective are called views and editors. You will learn
more about these concepts later in this topic.

© Copyright IBM Corp. 1996, 2008 1


A typical EGL development workbench

Menu bar
Functions in a GUI are typically listed in a menu bar at the top of the window.
In the picture above, the menu bar lists menus beginning with File, Edit, and
Navigate. The menus drop down when you click the menu item with the
mouse. The Eclipse menu bar contains global options for the workbench, such
as the location of the workspace, commands for importing and exporting files,
search commands, and help menus.
With the menu bar, you can also open and close views and perspectives. You
can click Window → Show View to open a view or Window → Open
Perspective to open a perspective.
Perspectives bar
The Perspectives bar lists the currently active perspectives. You can click the
name and icon of a perspective to switch to that perspective. In the picture
above, the Debug, EGL, and Web perspectives are active, and the EGL
perspective is open.
Toolbars
The workbench displays various toolbars below the menu bar depending on
the open perspective, views, and files. If you position the cursor over an icon,
hover help shows the function provided by that icon. Some icons also have a
drop-down list with additional options. For example, the tool bar for the EGL

2 EGL Programmer’s Guide


perspective contains icons that start the EGL wizards to create a new EGL
project, a new EGL package, or a new EGL source file. Some views and editors
also have their own toolbar.
The icons on these toolbars are shortcuts for commands found elsewhere in the
workbench, such as in the menu bar or on the popup menu that appears when
you right-click a file. You can customize the toolbars shown by clicking
Window → Customize Perspective and selecting or clearing check boxes on the
Commands tab.
EGL editor
The EGL editor looks and works like a standard text editor or code editor for
other languages, but it has additional features to help you edit EGL code. The
code editor highlights invalid syntax, provides an explanation for problems in
the code, and colors keywords and strings.
The EGL editor also includes content assist, which attempts to complete code
that you have begun to type. To use content assist, type the first few characters
of a variable name, library name, or EGL keyword and press CTRL + Space. A
content assist window opens, listing valid EGL code phrases that begin with
the code you have typed. Select a code phrase from the list by highlighting it
and pressing Enter or double-clicking it.
EGL Rich UI editor
The EGL Rich UI editor includes the functionality of the EGL editor, as well as
a Design surface and Preview view for fast development of client-side Web
applications. For details, see Overview of EGL Rich UI and Introduction to the
EGL Rich UI editor.
Project Explorer view
The Project Explorer view shows all of your files and projects. Within the
projects, this view shows your files in a hierarchical arrangement. Click a plus
sign to expand a package or folder and expose the files inside. Double-click a
file to open it in its default editor. Right-click a file, project, or folder to display
a context-sensitive menu of options. From this menu, you can delete or rename
files, among many other options. You can also click and drag files from place
to place in the view. You can group projects in this view by defining working
sets, or groups of projects or other elements. See Working sets.
Outline view
The Outline view shows a hierarchical representation of the file you are
currently editing. For example, if the file contains a Program part and a Record
part, the Outline view shows the file’s package at the top of the hierarchy,
followed by any import statements in the file, and then the Program part and
Record part. Variables and functions in the Program part appear under the
Program part in the Outline view, and fields in the Record part appear as
nodes under the Record part. You can click any of the entries in the Outline
view to go to the matching location in the EGL source file.
Problems view
The Problems view shows syntax errors or warnings in your code or other
files. You can double-click on an error to show the location of the error in the
file.
Generation Results view
EGL updates the Generation Results view each time you generate parts. If any
of your EGL parts do not generate correctly, this window shows which parts
did not generate and why. This view also shows which parts generated
successfully.

Introduction 3
In the previous image, the Generation Results view is ″stacked,″ or hidden behind
the Problems view. You can switch to a hidden view by clicking the tab with the
name of the view you want, which brings that view to the top of the stack. You
can also double-click the name of a view to expand that view to fill the
workbench. Double-clicking the name again will return the view to its original
size.

Other windows EGL developers commonly use


Aside from the main workbench window, EGL developers will often need to use
other windows. Following are some examples:
EGL Preferences window

With the Preferences window, you can set global options for the workbench.
This illustration shows the EGL page of the Preferences window. To set EGL
preferences, click Window → Preferences and click EGL. See “Preferences” on
page 172 for links to information on the particular EGL preferences you can
set.
Search window

4 EGL Programmer’s Guide


In the Search window, not to be confused with the Search view, you can search
for EGL parts or for other information in your workspace. The search results
appear in the Search view. See “Searching for parts” on page 168 for details.
Properties window

Most types of projects and files have a Properties window, not to be confused
with the Properties view. The Properties window sets individual options for
the artifact. Access the Properties window for a project or file by right-clicking
it and then clicking Properties.

Other views and editors EGL developers commonly use


EGL build parts editor
The build parts editor is used for editing build parts, including build
descriptors.

Introduction 5
EGL Parts Reference view

The EGL Parts Reference view shows a hierarchical view of the parts
referenced in a generatable logic part. To open a part in the Parts Reference
view, right-click the file that contains the part in the Project Explorer view and
then click Open in Parts Reference. See “Viewing part references” on page 171
for details.
EGL Parts List view

6 EGL Programmer’s Guide


The EGL Parts List view shows a list of EGL parts that you can sort or filter
for reference purposes. See “Viewing lists of parts” on page 169 for details.
Page Designer Editor

Page Designer is a what-you-see-is-what-you-get (WYSIWYG) editor for Web


pages. Page Designer can work with EGL to create a Web interface for an EGL
application.
Properties view

The Properties view provides detailed information on a specific object that you
have selected in an editor. For example, if you have a Web page open in Page
Designer and you select a text output field on that Web page, the Properties

Introduction 7
view shows you information such as the style applied to the field, where its
content comes from, and its other characteristics.
Palette view

The Palette view works alongside WYSIWYG editors. The Palette lists objects
that you can drag into the editor, creating new objects in the open file.
Snippets view

The Snippets view works alongside code editors. The Snippets view holds
reusable pieces of code that you can drag into your code. You can also create
new snippets for code that you use often.
Console view

8 EGL Programmer’s Guide


The Console view shows logged messages that are related to running your
applications. For example, if you run an application and it causes an error, that
error is listed in the Console view.
Navigator view

The Navigator view is similar to the Project Explorer view in that both show
the projects and files in your workspace. However, the Navigator view is a
pure view of the folders and files in your workspace, without any formatting
or filtering done by EGL. As such, it shows every folder and file in the
workspace based on the actual location of those artifacts. The Project Explorer
reduces clutter by automatically hiding metadata files (such as the .eglproject
file) and directories that you do not normally need to access (such as the
EGLbin directory). Also, the Navigator view does not support refactoring EGL
parts and files, such as renaming or moving them, like the Project Explorer
view does.

How the workbench is organized


The workbench contains a large number of tools and options. For this reason, it
organizes the tools into a hierarchy of categories. From most general to most
specific, these groups are capabilities, perspectives, views, and editors.
Capabilities
Capabilities are the broadest category of functionality in the workbench.
Capabilities are organized by major functional areas, such as ″Web
developer″ or ″Tester.″
Capabilities can be enabled or disabled to display or hide functionality. For
example, if the Tester capability is disabled, perspectives and views related
to testing will not be available. You can manually enable a capability in the
Preferences window by clicking Window → Preferences → General →
Capabilities and then selecting the check boxes next to the capabilities you
want to enable. Alternately, when you try to create a file or open a
perspective that is associated with a disabled capability, the workbench
will prompt you to enable the associated capability.
The main capability that EGL developers use is the EGL Developer
capability. Enabling this capability makes EGL-related perspectives

Introduction 9
available, which in turn makes tools available for working with EGL code.
See “Enabling EGL capabilities” on page 11.
Perspectives
A perspective is a group of views and editors that are all shown on the
screen at once. For example, when you open the Web perspective by
clicking Window → Open Perspective → Other → Web, you see tools for
building Web sites. There are other perspectives for working with data
sources, debugging code, and testing.
The perspectives available to you depend on the capabilities enabled in
your workbench. For example, if the Tester capability is disabled, you will
not see the Test perspective as an option in Window → Open Perspective →
Other.
You can switch perspectives at any time without losing your work, and
you can have as many perspectives open as you want. Often, developers
switch between perspectives as they perform different tasks. To switch
between perspectives, open the perspectives you want with Window →
Open Perspective → Other or click a perspective’s icon in the Perspectives
bar, which is typically at the top right corner of the workbench.
You can also create customized perspectives that show only the tools you
want. To create a customized perspective, open an already existing
perspective and tailor it to your needs by repositioning its views and
editors and opening or closing views and editors. Then, click Window →
Save Perspective As and type a name.
Views When you open a perspective, the views associated with that perspective
are displayed in the workbench. Each view performs a specific purpose,
such as displaying certain information or giving access to a specific tool.
The purpose of each view varies widely, but in general, views give you
access to a specific area of your workspace. Some views, such as the
Project Explorer, Navigator, and Package Explorer views, show the files,
projects, and packages in your workspace, enabling you to open files or
reorganize projects. Other views, such as the Outline and Properties views,
give information about a file you are currently viewing in an editor.
Finally, some views, such as the Problems view and the Console view,
display information about the status of your projects.
Views are flexible; you can move them around the workbench, resize them,
minimize or maximize them, stack them on top of other views, or close
them. To close a view, click the X at the top of the view. To open a view,
either open a perspective that contains that view or click Window → Show
View and click the name of a view. You can have as many views open as
you want, but it is best to organize your views into one or more
perspectives.
Editors
Editors look like views, but editors are designed to change a particular
type of file. Some editors, like the EGL code editor, look and work just like
code editors for many other programming languages, although the EGL
code editor has additional features for working with EGL code.
Other editors are graphical, with drag-and-drop tools or
what-you-see-is-what-you-get (WYSIWYG) preview tools. For example,
with Page Designer you can edit a Web page by clicking and typing
directly in the Web page. You can also drag Web page elements onto the
page from views such as the Palette view.

10 EGL Programmer’s Guide


Still other editors are tabular and provide tables in which you enter values.
For example, the EGL build parts editor enables you to edit a build
descriptor part by entering the values for build descriptor options in a
table.
In general, when you double-click a file in a view that displays files, such
as the Project Explorer or Navigator, that file opens in its default editor.
You can also right-click the file, and then click Open With to see a list of
editors that can open that file, or you can click Open With → System
Editor to open the file outside of the workbench, in the default editor for
that type of file in the operating system.

Other information on the workbench


For more information on using the workbench effectively, see these sources:
v Help topics on the following subjects:
– Workbench
– Capabilities
– Perspectives
– Views
– Editors
v “Enabling EGL capabilities”
v “Setting general preferences” on page 173
v “Working with EGL code” on page 127
v “Overview of EGL Rich UI” on page 327
v “Introduction to the EGL Rich UI editor” on page 337
v The tutorial Understand the workbench environment.

Enabling EGL capabilities


Capabilities keep the workbench menus from becoming cluttered by hiding items
you do not use. You can always perform these tasks, but to make them appear in
the menus, you must enable the capability for that area of functionality.

For EGL, capabilities hide the EGL-related views and the EGL perspective, items in
the pop-up menus and menus for creating new files, and the code templates
available when you use content assist.

To enable EGL capabilities, follow these steps:


1. From the main menu, click Window → Preferences.
2. In the Preferences window, expand General in the tree and then click
Capabilities.
In the Capabilities list, the EGL Developer folder represents the EGL
capabilities. You may have other capabilities in the list.
3. To enable all EGL capabilities, select the check box next to EGL Developer.
4. To select a few EGL capabilities to enable, follow these steps:
a. Click Advanced. The Advanced window opens.
b. Expand EGL Developer.
c. Under EGL Developer, select the check boxes next to the capabilities that
you want to enable.
Each capability enables a different set of EGL functionality. The EGL Core
Language capability is required for EGL functionality.

Introduction 11
d. Click OK.
5. Normally, the workbench warns you before you use functionality that belongs
to a disabled capability. If you clear the check box labeled Prompt when
enabling capabilities, the workbench will automatically enable any capabilities
that you try to use.
6. To save your changes, click Apply, then click OK.

Some capabilities have prerequisites. For this reason, enabling EGL capabilities
may automatically enable other capabilities that are required to develop and debug
EGL applications.
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.

What’s new in EGL V7.5


Rich UI leads the list of new features for this release of EGL.

Rich UI applications

Rich UI is a new technology for writing Web 2.0 applications. You can use the EGL
Rich UI interface to write an EGL Rich UI application, which is converted
automatically into JavaScript™. EGL Rich UI applications can invoke remote
services and interact with public Web sites. Rich UI supports Internet Explorer
versions 6 through 8, Firefox versions 2 and 3, and Safari versions 2 and 3. Because
Rich UI supports Safari, Rich UI applications work on the iPhone.

Additional support for IBM® CICS® channels and containers

EGL generated programs for CICS can be called with channels and containers.
Batch applications can now use remote CICSEXCI calls to communicate with CICS.

VSE support

You can purchase an extension that enables the generation of EGL as COBOL
source that can be compiled and deployed to z/VSE™.

Runtime improvements for COBOL programs


The runtime now runs in AMODE 31/RMODE ANY mode, instead of RMODE 24.
This mode uses more above-the-line memory to create a transaction throughput.

Update of supported platforms

Rational® Business Developer now supports the following products:


v IBM WebSphere® Application Server Version 7.0
v Apache Tomcat Version 6
v IBM WebSphere® Portal Server Version 6.

Rational Business Developer no longer supports WebSphere Application Server


Version 5.1.

12 EGL Programmer’s Guide


Related information
“What’s new in EGL V7.1”
Related concepts

What’s new in EGL V7.1


Return of features that were unsupported in V7.0

The following areas of functionality that were removed in V7.0 are returned in this
version:
v Text User Interface, including FormGroups, the Text Form editor, the system
library ConverseLib, and the ConverseVar system variable
v DL/I, IMS™, and GSAM data access, including the system library DLILib and
the DLIVar system variable
v WebSphere MQ data access
v Web transactions
v VisualAge® Generator migration tool
v The statement exit stack
v Java™ wrapper generation, including the ejbCall type of the callLink element of
the linkage options part

Build descriptor options related to these areas of functionality are returned; see
“Changes to build descriptor options in EGL V7.1” on page 16.

System libraries and variables related to these areas of functionality are returned;
see “Changes to system libraries and variables in EGL V7.1” on page 15.

EGL assumes that EGL V6 users with forms did not migrate to V7, so there is no
migration program to move from V7 to V7.1. However, if you use forms and you
migrated to V7, you must make the following changes in your code by hand:
v Add the @ operator to all printFloatingArea and screenFloatingArea properties.
v Place all of the @printFloatingArea complex properties for a form inside the
new printFloatingAreas property.
v Place all of the @screenFloatingArea complex properties for a form inside the
new screenFloatingAreas property.

For more information, see Form part.

BIRT reports

EGL can now generate reports with BIRT. See “Creating reports with BIRT” on
page 551.

J2EE security

New functions in J2EELib allow you to secure a JSF application through


container-manages security. See “Using JEE container-managed security” on page
452.

Introduction 13
LDAP data access

EGL provides a code sample that you can customize to retrieve security or other
details from a server accessed by way of Lightweight Directory Access Protocol
(LDAP). See Sample: EGL LDAP access.
Related concepts
“Language changes in EGL V7.1”
This topic lists the changes to the EGL language in version 7.1.
“Changes to build descriptor options in EGL V7.1” on page 16
“Changes to system libraries and variables in EGL V7.1” on page 15
“Changes to parts in EGL V7.1”
This topic lists the major changes to EGL parts in this version.
“User interface changes in EGL V7.1” on page 17

Language changes in EGL V7.1


This topic lists the changes to the EGL language in version 7.1.
New operators
The bitwise xor (xor) operator performs a bitwise exclusive or operation on
two operands of type HEX(2), HEX(4), HEX(8), INT, or SMALLINT.
Change in goTo restrictions.
In earlier versions, the goTo statement could not transfer control to a label
within a conditional block. To accommodate migration from RPG, the
restrictions have changed:
v The label must be in the current block, in a block that fully contains the
current block, or outside all conditional blocks at the top of the function.
v The label cannot be with the scope of an OpenUI statement.
Limits removed for SQL table labels
SQL table labels formerly were limited to four characters, and by
convention were generally two characters, as in the following example:
record CustomerRecord type SQLRecord
{tableNames = [["ADMINISTRATOR.CUSTOMER", "L1"]],
keyItems = [customerNumber]}

The restriction was required by an older version of DB2®. DB2 Version 7


supports table labels up to 18 characters long; DB2 Version 8 has no limits
on table label length. EGL no longer limits the length of SQL table labels.

Changes to parts in EGL V7.1


This topic lists the major changes to EGL parts in this version.

The following Record part stereotypes are new in this version:


CSVRecord stereotype
The new CSVRecord stereotype is for Record parts that hold information
with fields delimited by a character such as a comma.
DLIException stereotype
The new DLIException exception record is for handling errors in DL/I
data access applications.

The VGUIRecord stereotype is available in this version, as explained in “Return of


features that were unsupported in V7.0” on page 13. This record can have
additional properties that it could not have in previous versions:

14 EGL Programmer’s Guide


v handleHardIOErrors
v i4glItemsNullable
v localSQLScope
v textLiteralDefaultIsString
v throwNrEofExceptions
See VGUIRecord properties.

The syntax for floating area properties in FormGroups has changed. A new
property, printFloatingAreas, now contains multiple @printFloatingArea complex
properties. Similarly, the new screenFloatingAreas property now contains multiple
@screenFloatingArea complex properties.

Changes to system libraries and variables in EGL V7.1


Returned system libraries and variables

The following system libraries and variables are available in this version. See
“Return of features that were unsupported in V7.0” on page 13.
v ConverseLib
v ConverseVar
v DLILib
v DLIVar
See the EGL Language Reference for information on these libraries and variables.

New system functions


SysLib.convertNumberToUnsignedUnicodeNum
See convertNumberToUnsignedUnicodeNum()
SysLib.convertUnsignedUnicodeNumToNumber
See convertUnsignedUnicodeNumToNumber()
J2EELib.getAuthenticationType
See getAuthenticationType()
J2EELib.getRemoteUser
See getRemoteUser()
J2EELib.isUserInRole
See isUserInRole()
ConsoleLib.openFileDialog
See openFileDialog()

Changed system functions and variables


sysVar.formConversionTable and sysVar.callConversionTable
These system variables are now a CHAR(256) rather than a CHAR(8).
Related Concepts
“What’s new in EGL V7.1” on page 13
“Language changes in EGL V7.1” on page 14
This topic lists the changes to the EGL language in version 7.1.
“Changes to parts in EGL V7.1” on page 14
This topic lists the major changes to EGL parts in this version.
“Changes to build descriptor options in EGL V7.1” on page 16

Introduction 15
“Changes to system libraries and variables in EGL V7.0” on page 32

Changes to build descriptor options in EGL V7.1


Returned build descriptor options

The following build descriptor options were not available in version 7.0 but are
available in version 7.1. For details on the functionality that was returned, see
“Return of features that were unsupported in V7.0” on page 13.

Options related to Java wrappers:


v enableJavaWrapperGen
v sessionBeanID
v wrapperPackageName

Options related to Text User Interface:


v fillWithNulls
v formServicePgmType
v genFormGroup
v genHelpFormGroup
v leftAlign
v oneFormItemCopybook
v printDestination
v restartTransactionID
v setFormItemFull
v validateOnlyIfModified
v workDBType

Options related to IMS and DL/I data access:


v errorDestination
v imsFastPath
v imsLogID
v mfsDevice
v mfsExtendedAttr
v mfsIgnore
v mfsUseTestLibrary
v restoreCurrentMsgOnError
v spaADF
v spaSize
v spaStatusBytePosition
v synchOnPgmTransfer

Options related to Web transactions:


v genResourceBundle
v genVGUIRecords
v msgTablePrefix
v resourceBundleLocale

16 EGL Programmer’s Guide


New build descriptor options

The following build descriptor options are new in this version:


wrapperJNDIPrefix
See wrapperJNDIPrefix.
wrapperCompatibility
See wrapperCompatibility.
birtEngineHome
See birtEngineHome.
imsID
See ″imsID″ in the EGL Generation Guide.
Related Concepts
“What’s new in EGL V7.1” on page 13
“Language changes in EGL V7.1” on page 14
This topic lists the changes to the EGL language in version 7.1.
“Changes to system libraries and variables in EGL V7.1” on page 15
“Changes to build descriptor options in EGL V7.0” on page 35

User interface changes in EGL V7.1


New EGL project wizard
The wizards for creating the different types of EGL project have been
combined into a single wizard which prompts you to choose a type of
project. See “Creating an EGL project” on page 71.
EGL Runtime Data Source page
You can now create a connection and use that connection both at design
time and at run time through the EGL Runtime Data Source property page.
Open this page by right-clicking an EGL Web project, clicking Preferences,
and then clicking EGL Runtime Data Source. See “Using an SQL database
connection at run time” on page 202.
Services enhancements
The process of creating a service application in the workbench has been
simplified in several ways, including:
v The New EGL Project wizard can create an EGL deployment descriptor
for the new project and automatically set the deploymentDescriptor
build descriptor option to the name of that deployment descriptor.
v When creating a new Service part, you can specify to create the Service
part as a Web service, in which case EGL will automatically add Web
service deployment information to the deployment descriptor.
v The EGL deployment descriptor editor has been simplified and
enhanced, including tools to set attributes on multiple Web services.
EGL editor
The EGL editor now highlights syntax errors as you type. It can also
format your source code. See “The EGL editor” on page 155.
Related Concepts
“What’s new in EGL V7.1” on page 13
“Language changes in EGL V7.1” on page 14
This topic lists the changes to the EGL language in version 7.1.

Introduction 17
What’s new in EGL V7.0
Several new features have been added in this version:
v Language enhancements
v Expanded support for services, including iSeries® COBOL and CICS services
v Support for model-driven development, including the ability to transform UML
to EGL
v Addition of rich client widgets to EGL Console UI
v Improvements to the user interface
v Improvements to the documentation
v Improved performance, particularly for building projects, generating Java or
COBOL, and Java runtime.
v Libraries can now be generated for iSeries COBOL
v Support for AJAX requests (version 7.0.0.3)

Model-driven development

This version of EGL allows you to plan an application with a UML model and
then create starter EGL code from the UML model. Generally, model-driven
development with EGL follows these steps:
1. You plan your application with a UML model. EGL does not include
functionality for editing UML models graphically.
2. You associate the UML model with a transformation parameters model (TPM)
file. This file specifies which transformations will be used on the UML model
and how those transformations will be applied. The EGL Application
Transformation allows you to transform UML into EGL. Depending on what
products you have installed, you may have other transformations available, but
these transformations will not create EGL code.
3. Using the transformation parameters editor, you edit the parameters associated
with the EGL application transformation to describe what the resulting EGL
code will look like. Depending on what products you have installed, you may
have other transformations available, but these transformations will not create
EGL code.
4. You run the transformation to apply the transformation parameters to the UML
model and create EGL code.

For information on the transformation parameters editor and working with


transformations in general, see Generating source code from UML models.For
information on the transformation parameters editor and working with
transformations in general, see ″Generating source code from UML models″ in the
online help system.

For information on the EGL Application Transformation, see Model driven


development of EGL code.For information on the EGL Application Transformation,
see ″Model driven development of EGL code″ in the online help system.

Console User Interface rich client widgets

In this release, EGL contains support for rich client widgets in Console UI. These
widgets allow you to add mouse support to your Console UI applications, as well
as graphical input fields like check boxes and buttons. Developing an application
with these widgets is similar to developing an ordinary Console UI application,
but you must run the application in RCP mode, rather than the standard mode for

18 EGL Programmer’s Guide


Console UI applications. See “Adding rich client widgets to a Console UI
program” on page 519.

AJAX support

Beginning with version 7.0.0.3, EGL-controlled Web pages can issue AJAX requests,
allowing you to update a portion of a page without refreshing the entire page. To
create an AJAX request, you indicate an area on the page to be updated, specify a
user action to trigger the update, and add code to the page’s JSF Handler to
process the update. See “Updating portions of a Web page with AJAX requests” on
page 432.

The following topics deal with major changes in this version of EGL.
Related Concepts
“Language changes in EGL V7.0”
This topic lists the changes to the EGL language in version 7.0.
“Validation changes in EGL V7.0” on page 24
“Changes to parts in EGL V7.0” on page 28
This topic lists the EGL parts and describes their major changes in this version.
“Changes to system libraries and variables in EGL V7.0” on page 32
“Changes to build descriptor options in EGL V7.0” on page 35
“Changes to exception handling in EGL V7.0” on page 36
This topic covers changes to the way EGL deals with exceptions in version 7.0.
“Changes to services in EGL V7.0” on page 36
“User interface changes in EGL V7.0” on page 37
Documentation changes in EGL V7.0
Related tasks
“Migrating from a previous version of EGL” on page 38

Language changes in EGL V7.0


This topic lists the changes to the EGL language in version 7.0.

Major changes
Reference variables
EGL now uses the concept of reference variables, variables that do not hold a
value themselves but act as a reference to another value. For example,
arrays, Dictionaries, consoleForms, and the ANY, BLOB, and CLOB
primitives are reference types. See Reference variables.
Nullable types
The way EGL handles nullable variables, variables that can point to a null
or empty value, has changed.
v You can declare a nullable variable by appending a question mark ? to
the variable type specification. For example, the following code declares
a nullable integer variable:
myNullableVariable int?;

Variables declared to be nullable in this way contain null until you


assign a value to them.
v You can now set a nullable variable to null by assigning it the value
NULL, as in this example:
myVar int? = NULL;

Introduction 19
Similarly, you can test to see whether a variable is null by comparing it
to the value NULL:
if (myVar == NULL)
...
end

Because you can now assign a null value and compare to a null value,
the following expressions are no longer used:
– SET myVar NULL
– if (myVar is NULL)
v NIL is no longer a valid literal to represent a null value. Use NULL
instead.
v The itemsNullable build descriptor option is no longer used. In its place
is the I4GLItemsNullable property, which can be put on programs,
libraries, handlers, and records for migration purposes. This property
places an implicit question mark on each primitive variable, constant,
and parameter in the part, making them all nullable.
v When a variable is made nullable with an explicit question mark, that
variable is initially null. When a variable is made nullable by
I4GLItemsNullable, the initial value of that variable depends on the
type of variable.
v The nullable modifier on function parameters is now sqlNullable.
v The isNullable property is now isSQLNullable.
v System functions have rules to deal with nullable variables. In most
cases, if you pass a null variable to a system function, the function will
return a null value. However, the behavior of each function differs with
respect to nullable parameters and return values. See the reference
information for the specific function for information on how it deals
with nullable variables.
v When concatenating string variables, a null value is treated as an empty
string.
For more information on nullable variables, see the topics ″Null values and
the nullable type″ and ″i4glItemsNullable″ in the EGL Language Reference.

Statements
New operators
v The new concatenation operator (::) concatenates two variables as
though those variables were strings. When used with text variables, it
works like the + operator:
myString1 string = "Hello ";
myString2 string = "everyone!";
SysLib.writeStderr(myString1 :: myString2);
SysLib.writeStderr(myString1 + myString2);
//writes "Hello everyone!" to the console twice

When used with numeric variables, the concatenation operator treats


those variables like strings:
myInt1, myInt2, myInt3 int;
myInt1 = 5;
myInt2 = 6;
myInt3 = myInt1 :: myInt2;
SysLib.writeStderr(myInt3);
//writes "56" to the console.

20 EGL Programmer’s Guide


v The as operator temporarily assigns, or casts, a value to a specified type.
The following example uses as to temporarily cast a variable of the ANY
primitive type to the INT primitive type:
myVar1 ANY = "5";
myVar2 int = 6;
myVar3 int = myVar2+myVar1 as int;
SysLib.writeStderr(myVar3);
//Writes "11" to the console.
v The bitwise and (&) and bitwise or (|) operators perform a bitwise
operation on two operands of type HEX(2), HEX(4), HEX(8), INT, or
SMALLINT.
Change to the in operator
You now use the from keyword with arrays rather than using an index to
limit the search. The following example shows the old syntax for searching
an array beginning with the fourth element:
if(a in myArray[4])

The following example shows the new syntax for the same task:
if(a in myArray from 4)
Conversion enhancements
You can now assign a STRING directly to a DECIMAL, FLOAT, or INT.
This ability removes the need for functions such as
MathLib.stringAsDecimal().
Change in rounding behavior
In previous versions, when you assigned a variable to a target variable
with fewer decimal places, EGL truncated the source variable to fit into the
target variable. In EGL V7.0, these extra decimal places are rounded, not
truncated, when either of the following criteria is true:
v The truncateExtraDecimals build descriptor option is set to NO
v The type of the source variable is FLOAT or SMALLFLOAT, and the
type of the target variable is not FLOAT or SMALLFLOAT
If both of these criteria are false, EGL truncates the source variable to the
number of decimal places available in the target variable, as it did in
V6.0.1.1.
In previous versions, for the MathLib.round() system function, the second
argument (the power of 10) was optional. In EGL V7.0, the second
argument is required.
The migration tool uses the MathLib.assign() system function to replace
MathLib.round() in situations in which the power of 10 parameter was not
used.
Changes to syntax of call, transfer, and show
You can now specify the name of the target program or transaction in
these statements as a direct program reference, as a literal (in quotes), or as
a variable. The statements also use braces to group their keyword
modifiers. In addition, the call statement now uses parentheses to group
arguments. For example:
call "xxx" (1, 2) { IsNoRefresh = yes, IsExternal = yes };
transfer to program "xxx" passing yyy { IsExternal = yes};

Introduction 21
Variables
Scope of variables within functions
In previous versions of EGL, if you declared a variable within a function,
that variable was in scope for the entire function, even for statements that
preceded the variable declaration. Now, variables are in scope only for
statements that follow their declaration.
Format specifiers for INTERVAL variables
You must include a format specifier when creating an INTERVAL variable:
intval1 interval("yyyyMM");
Default representation for text literals
By default, text literals (such as "Hello!") are treated as of the type
STRING in the generated source. If you want EGL to interpret these as a
different type instead, set the new textLiteralDefaultIsString property to
NO. See textLiteralDefaultIsString.
ANY type is no longer limited to the type of its first assigned value
In previous versions of EGL, if you created a variable of the ANY type and
assigned a value to that variable, the ANY variable was permanently
limited to the type of that value. The ANY variable could store only values
compatible with that first value. In this version, the ANY variable can
accept any EGL type, regardless of what you have assigned to it
previously. You can use the as operator to cast an ANY variable
temporarily to another type, and you can use the isa operator to test what
type of data the ANY variable contains.

Web applications
Validating variables when their values change
With the onValueChangeFunction property, you can specify a function to
validate user input for a variable in a JSF Handler automatically when the
value of the variable changes. For example, the following code creates a
variable and specifies its validation function:
myInteger int {onValueChangeFunction = validateMyInt};

The function specified by onValueChangeFunction accepts a parameter of


the same type, which you use to test the value:
function validateMyInt(intToCheck int in)
if (intToCheck >= 500)
SysLib.setError("Number must be less than 500");
end
end

General changes
Some property values are no longer quoted strings
When assigning values to properties in set value blocks, EGL no longer
uses quotes around names of fields, variables, or parts. For example, the
following code is correct for version 6.0:
Record CustomerRecord type SQLRecord {
keyItems = ["customerNumber"]}
customerNumber INT; //key field
customerName STRING;
end

The following code is correct for version 7.0:

22 EGL Programmer’s Guide


Record CustomerRecord type SQLRecord {
keyItems = [customerNumber]}
customerNumber INT; //key field
customerName STRING;
end

File names, aliases, and other values continue to require quotes, as in the
following example:
Record XferLog type SerialRecord {fileName = "MYFILE1"}
10 entry CHAR(60);
end

The following properties have changed from a quoted string to an


unquoted reference to a variable:
v commandValueItem
v inputForm
v inputRecord
v inputUIRecord
v keyItem
v keyItems
v lengthItem
v msgField
v numElementsItem
v onPageLoadFunction, which is now split into the properties
onConstructionFunction, onPreRenderFunction, and
onPostRenderFunction
v parentRecord
v pcbParms
v psb
v psbParm
v redefines
v segmentRecord
v selectedIndexItem
v selectFromListItem
v validationByPassFunctions
v validatorDataTable
v validatorFunction
v valueRef
v viewRootVar
New reserved words
The following words are now reserved words in EGL:
v CONSTRUCTOR
v DELEGATE
v ENUMERATION
v EXTERNALTYPE
v NOCURSOR
v NULL
v RUNUNIT
v SQLNULLABLE

Introduction 23
v THROW
v WITHV60COMPAT
Importing from the default package is no longer allowed
In previous versions, you could define a part in the default package (that
is, a part in the root of an EGL source folder, with no named package
containing it) and import that part for use in a part in another package.
Now you can import parts in the default package only into other parts in
the default package.
Naming conflicts between functions and variables
Within a part, no function may have the same name as a variable.
Name resolution between fields and properties
You can use the ″at″ symbol (@) to distinguish between fields and
properties with the same name.
For example, assume an EGL Dictionary part, which a list of name-value
pairs. You use a set-value block to assign those name-value pairs; you can
use the same set-value block to assign values to properties of the
dictionary itself. The following is a declaration of a new Dictionary part:
myRef Dictionary {
displayName = "myNewDictionary"
};
Because of part resolution rules, EGL assumes that displayName =
"myNewDictionary" is a name-value pair in the new dictionary. If you want
to assign a value to the displayName property for the dictionary, you must
use an @ operator, as in the following example:
myRef Dictionary {
@displayName {"myNewDictionary"}
};
See EGL part resolution rules for more information.
Related Concepts
“What’s new in EGL V7.0” on page 18
“Validation changes in EGL V7.0”
“Changes to parts in EGL V7.0” on page 28
This topic lists the EGL parts and describes their major changes in this version.
“Changes to system libraries and variables in EGL V7.0” on page 32
“Changes to build descriptor options in EGL V7.0” on page 35
“Changes to exception handling in EGL V7.0” on page 36
This topic covers changes to the way EGL deals with exceptions in version 7.0.
“Changes to services in EGL V7.0” on page 36
“User interface changes in EGL V7.0” on page 37
Documentation changes in EGL V7.0

Validation changes in EGL V7.0


Some pieces of code that appeared to be valid in previous releases will be marked
as invalid in this version. In most cases, these validation changes do not reflect
language changes; instead, the EGL editor is identifying code that was accepted in
previous versions but did not run as expected in the generated code. Following are
updates to code validation that you may encounter in this version of EGL:

24 EGL Programmer’s Guide


Variables and constants
isBoolean property on variables with no non-decimal places
You can apply the isBoolean property to a numeric variable with decimal
places, such as DECIMAL(3,2). However, the variable must have at least one
non-decimal place. For this reason, variable declarations such as myVar
decimal(2,2){isBoolean=yes} are invalid. Use a BOOLEAN primitive or a
numeric type with places to the left of the decimal.
Assigning a literal with too many decimal places for the target constant
Validation now recognizes an attempt to assign too many decimal places to
a constant, as in these examples:
const c1 decimal(5,3) = 1.2345; //validation error
const c2 decimal(5,3) = 123.456; //validation error

Statements
Size of arrays within an isa expression
You cannot specify a size for an array in an isa expression, as in this
example:
library myLibrary type basicLibrary

function func(parameterOne any)


if (parameterOne isa int[5]) //validation error
end
end

end
into clauses with ANY types
You cannot use into to put data into an ANY variable:
program myProgram

myRecord recordType;
myVariable any;

function main()
foreach(from myRecord into myVariable);// validation error
end
end

end

record recordType type SQLRecord


item1 int;
end
Operations with incompatible INTERVAL variables
Validation now recognizes an attempt to perform assignment or a
mathematical operation between two INTERVAL variables with
incompatible formats, as in this example:
Program pgm
msInterval interval("yyyymm");
ssInterval interval("mmss");

function main()
msInterval = msInterval + ssInterval; //validation error
end
end

Introduction 25
Parts
Service parts must have a function for every function prototype in the interfaces
it implements
When a Service part implements an Interface part, the Service part must
contain a function matching each function prototype in the Interface part.
The function names, parameter lists, and return values must match.
position property required on consoleForms that do not specify segments
property
If a Record part with the stereotype consoleForm does not specify the
position property, that Record part must specify the segments property.

JSF Handlers
Variables in JSF Handler parts with insufficient length to be displayed
Validation now recognizes variables in JSF Handlers that are not long
enough to fit the pattern specified in properties such as dateFormat and
timeFormat, as in this example:
handler myPage type JSFHandler
{view="myPage.jsp"}

myField decimal(1)
{dateFormat = "MM/dd/yyyy"}; //validation error
end
BLOB and HEX used as the value of selectFromListItem
Validation now recognizes an attempt to use BLOB and HEX variables as
the value of the selectFromListItem property in a JSF Handler.
selectFromListItem specifying a variable in another part
Validation now recognizes an attempt to use a variable in a library rather
than a variable in the same JSF Handler part as the value of the
selectFromListItem property.
Value of fillCharacter for DBCHAR and UNICODE variables
Validation now requires that the fillCharacter property be set to null or
blank on DBCHAR and UNICODE variables used in a JSF Handler
Type matching between variables in a JSF Handler and validation tables
Validation now ensures that the variables in a JSF Handler match the type
of the first column in their validation tables.
Related Concepts
“What’s new in EGL V7.0” on page 18
“Language changes in EGL V7.0” on page 19
This topic lists the changes to the EGL language in version 7.0.
“Changes to parts in EGL V7.0” on page 28
This topic lists the EGL parts and describes their major changes in this version.
Related tasks
“Migrating from a previous version of EGL” on page 38

Validation changes in EGL V7.0


Some pieces of code that appeared to be valid in previous releases will be marked
as invalid in this version. In most cases, these validation changes do not reflect
language changes; instead, the EGL editor is identifying code that was accepted in
previous versions but did not run as expected in the generated code. Following are
updates to code validation that you may encounter in this version of EGL:

26 EGL Programmer’s Guide


Variables and constants
isBoolean property on variables with no non-decimal places
You can apply the isBoolean property to a numeric variable with decimal
places, such as DECIMAL(3,2). However, the variable must have at least one
non-decimal place. For this reason, variable declarations such as myVar
decimal(2,2){isBoolean=yes} are invalid. Use a BOOLEAN primitive or a
numeric type with places to the left of the decimal.
Assigning a literal with too many decimal places for the target constant
Validation now recognizes an attempt to assign too many decimal places to
a constant, as in these examples:
const c1 decimal(5,3) = 1.2345; //validation error
const c2 decimal(5,3) = 123.456; //validation error

Statements
Size of arrays within an isa expression
You cannot specify a size for an array in an isa expression, as in this
example:
library myLibrary type basicLibrary

function func(parameterOne any)


if (parameterOne isa int[5]) //validation error
end
end

end
into clauses with ANY types
You cannot use into to put data into an ANY variable:
program myProgram

myRecord recordType;
myVariable any;

function main()
foreach(from myRecord into myVariable);// validation error
end
end

end

record recordType type SQLRecord


item1 int;
end
Operations with incompatible INTERVAL variables
Validation now recognizes an attempt to perform assignment or a
mathematical operation between two INTERVAL variables with
incompatible formats, as in this example:
Program pgm
msInterval interval("yyyymm");
ssInterval interval("mmss");

function main()
msInterval = msInterval + ssInterval; //validation error
end
end

Introduction 27
Parts
Service parts must have a function for every function prototype in the interfaces
it implements
When a Service part implements an Interface part, the Service part must
contain a function matching each function prototype in the Interface part.
The function names, parameter lists, and return values must match.
position property required on consoleForms that do not specify segments
property
If a Record part with the stereotype consoleForm does not specify the
position property, that Record part must specify the segments property.

JSF Handlers
Variables in JSF Handler parts with insufficient length to be displayed
Validation now recognizes variables in JSF Handlers that are not long
enough to fit the pattern specified in properties such as dateFormat and
timeFormat, as in this example:
handler myPage type JSFHandler
{view="myPage.jsp"}

myField decimal(1)
{dateFormat = "MM/dd/yyyy"}; //validation error
end
BLOB and HEX used as the value of selectFromListItem
Validation now recognizes an attempt to use BLOB and HEX variables as
the value of the selectFromListItem property in a JSF Handler.
selectFromListItem specifying a variable in another part
Validation now recognizes an attempt to use a variable in a library rather
than a variable in the same JSF Handler part as the value of the
selectFromListItem property.
Value of fillCharacter for DBCHAR and UNICODE variables
Validation now requires that the fillCharacter property be set to null or
blank on DBCHAR and UNICODE variables used in a JSF Handler
Type matching between variables in a JSF Handler and validation tables
Validation now ensures that the variables in a JSF Handler match the type
of the first column in their validation tables.
Related Concepts
“What’s new in EGL V7.0” on page 18
“Language changes in EGL V7.0” on page 19
This topic lists the changes to the EGL language in version 7.0.
“Changes to parts in EGL V7.0”
This topic lists the EGL parts and describes their major changes in this version.
Related tasks
“Migrating from a previous version of EGL” on page 38

Changes to parts in EGL V7.0


This topic lists the EGL parts and describes their major changes in this version.

New primitive

Like Boolean types in other languages, the BOOLEAN EGL primitive accepts a
value of TRUE or FALSE. You can also use YES to represent TRUE and NO to

28 EGL Programmer’s Guide


represent FALSE. The isBoolean property is still supported on other primitive
variables. See Primitive data types.

New parts

The following parts are new in this version:


ExternalType
An ExternalType part represents a mapping from EGL to another
language. This part replaces an Interface part with the stereotype
JavaObject in previous versions. For more information, see the following
topics:
v ExternalType part
v “Calling Java” on page 128
Delegate
This new type of part provides a model for a function. For more
information, see Delegate part

Changed parts

The following parts have changed in this version:


pageHandler
The pageHandler part is now a Handler part with the stereotype
JSFHandler. JSF Handlers perform all the same tasks as a pageHandler did
in previous versions, with some differences in properties:
v The onPageLoadFunction property, which designated a function to run
when the page loads, has been divided into the
onConstructionFunction, onPreRenderFunction, and
onPostRenderFunction functions. onConstructionFunction is the most
similar to onPageLoadFunction.
v The default value for a JSFHandler scope property is now session.
v The cancelOnPageTransition property determines whether the page
bean is removed from the session scope when the user’s browser loads a
new page. This property was added in version 6.0.1.1.
v You can apply the onValueChangeFunction property to a variable in a
JSF Handler to specify a function that validates the new value when
user input changes the value of the variable.
v You can apply the properties selectedRowItem and selectedValueItem
to variables within JSF Handlers. These properties behave in a way
similar to the properties selectFromListItem and selectType.
selectedRowItem indicates a variable that holds the index (or indexes)
for the row (or rows) the user selects from a screen display.
selectedValueItem holds the value or values from those rows instead of
the index or indexes.
v If variable in a JSF Handler has the selectType property set to index,
that variable must be an INT type.
v If a variable in a JSF Handler has the selectFromListItem property, the
property’s value cannot be a record array or an array of primitive
variables within a record. Valid types are a data table column or an
array of primitive variables not within a record. To use a record array or
an array of primitive variables within a record as a list of selection
options, use the properties selectedRowItem or selectedValueItem
instead.

Introduction 29
For more information, see the following topics:
v “Executing commands when a page loads” on page 411
v JSF Handler part
v onConstructionFunction
v onPreRenderFunction
v onPostRenderFunction
v cancelOnPageTransition
v onValueChangeFunction
v selectType
v selectFromListItem
v selectedRowItem
v selectedValueItem
Service
The way EGL uses services has changed significantly in this version. See
“Changes to services in EGL V7.0” on page 36
The properties of the Service part have changed as follows:
v The @WSDL property is no longer used. Use @XML to interact with
WSDL files.
v The @XSD property is no longer used.
v The properties allowUnqualifiedItemReferences and
includeReferencedFunctions are now valid on Service parts.
For more information, see the following topics:
v “Changes to services in EGL V7.0” on page 36
v Service part
v Overview of EGL deployment descriptor file
v “Overview of service-oriented architecture (SOA)” on page 475
v @xml
v @bindService
Library
The serviceBindingLibrary type of Library part is no longer used. The
runtimeBind property, which was used only on this type of Library part, is
no longer needed. See the information on services and the Service part, or
one of the following topics:
v Library part
v Service part
v “Overview of service-oriented architecture (SOA)” on page 475
Interface
The Interface part no longer has stereotypes such as BasicInterface and
JavaObject. Instead of BasicInterface, use an Interface part with no
stereotype. Instead of JavaObject, use an ExternalType part. For more
information, see the following topics:
v Interface part
v ExternalType part

30 EGL Programmer’s Guide


Program
Programs that are the target of a call statement must have a parameter list.
This parameter list can be empty, but the parentheses denoting the
parameter list are now required.
Record
Record parts have the new @SelectionList property, which specifies fields
in the record to use for the label and value when using the record in a JSF
selection list. For more information, see:
v @SelectionList
v “Binding a JSF single-select control to a variable” on page 401
Record parts have the new stereotype Exception, which is used to define a
custom exception. See “Changes to exception handling in EGL V7.0” on
page 36.
Record parts with the stereotype ConsoleForm
Record parts with the stereotype ConsoleForm are now considered
generatable parts. See “Generatable parts and non-generatable parts” on
page 96.
Record parts with the SQLRecord stereotype
The isNullable property for fields within SQLRecord parts is now the
isSQLNullable property. See isSQLNullable.
Record parts with the RelativeRecord stereotype
The keyItem property for this type of Record part is now the
recordNumItem property. See recordNumItem.

New properties

The following table lists new properties that can be used on multiple parts:
Table 1. New properties
Property Applicable parts
The v60ExceptionCompatibility property v Program
specifies whether the logic part uses a form
v Handler
of exception handling for compatibility with
a previous version. See v Library
v60ExceptionCompatibility. v Service
The textLiteralDefaultIsString property tells v Program
EGL how to deal with text literals to
v Handler
promote compatibility with VisualAge
Generator. See textLiteralDefaultIsString. v Library
v Service
v Record
The i4glItemsNullable property determines v Program
whether a record emulates the behavior of
v Handler
I4GL in creating variables as nullable by
default. It replaces the itemsNullable build v Library
descriptor option. See i4glItemsNullable. v Record

Related Concepts
“What’s new in EGL V7.0” on page 18
“Language changes in EGL V7.0” on page 19
This topic lists the changes to the EGL language in version 7.0.
“Changes to services in EGL V7.0” on page 36

Introduction 31
“Changes to exception handling in EGL V7.0” on page 36
This topic covers changes to the way EGL deals with exceptions in version 7.0.
Related tasks
“Migrating from a previous version of EGL” on page 38

Changes to system libraries and variables in EGL V7.0


Global changes

Most system functions have been updated to accept null values for parameters. In
general, if you pass a null value to a system function, it returns a null value.
However, each function behaves differently; see the help topic on the specific
function for information.

Some system functions and libraries were removed from V7.0 but are returned in
V7.1; see “Changes to system libraries and variables in EGL V7.1” on page 15.

Removed system functions

The following system functions are no longer necessary because you can now
assign a string directly to a decimal, floating-point, or integer type:
v MathLib.stringAsDecimal
v MathLib.stringAsFloat
v MathLib.stringAsInt

New system libraries and variables

The new system library sqlLib contains some functions moved from sysLib and
consoleLib that deal with SQL data access. For more information on sqlLib, see
EGL library sqlLib.

Similarly, the SQL-related system variables in sysVar and VGVar have been moved
into the new sqlLib.sqlData and sysVar.sqlData system variables, which are both
structured records. sqlLib.sqlData contains information that is global to the entire
application, while sysVar.sqlData contains information that is local to the program.
See sysVar system variable (core fields) and sqlLib.sqlData (EGL system variable).

New system functions

The following system functions and variables are new in this version:
j2eeLib.clearApplicationAttr
See clearApplicationAttr()
j2eeLib.clearEGLSessionAttrs
See clearEGLSessionAttrs()
j2eeLib.getApplicationAttr
See getApplicationAttr()
j2eeLib.setApplicationAttr
See setApplicationAttr()
MathLib.decimals
See decimals()

32 EGL Programmer’s Guide


StrLib.booleanAsString
See booleanAsString()
StrLib.getTokenCount
See getTokenCount()
StrLib.indexOf
See indexOf()
StrLib.intAsUnicode
See intAsUnicode()
StrLib.unicodeAsInt
See unicodeAsInt()
SysLib.convertNumberToUnicodeNum
See convertNumberToUnicodeNum()
SysLib.convertUnicodeNumToNumber
See convertUnicodeNumToNumber()
SysLib.setErrorForComponentID
See setErrorForComponentID()

Changed system functions and variables

The following system functions have new names:


Table 2. Renamed system functions
Old name New name
ConsoleLib.constructQuery SqlLib.constructQuery
MathLib.compareNum VGLib.compareNum
MathLib.FloatingAssign MathLib.assign
MathLib.FloatingDifference VGLib.FloatingDifference
MathLib.FloatingMod VGLib.FloatingMod
MathLib.FloatingProduct VGLib.FloatingProduct
MathLib.FloatingQuotient VGLib.FloatingQuotient
MathLib.FloatingSum VGLib.FloatingSum
MathLib.maximum MathLib.max
MathLib.minimum MathLib.min
ServiceLib.getWebEndPoint ServiceLib.getWebServiceLocation
ServiceLib.setWebEndPoint ServiceLib.setWebServiceLocation
StrLib.characterAsInt StrLib.charAsInt
StrLib.compareStr VGLib.compareStr
StrLib.concatenate VGLib.concatenate
StrLib.concatenateWithSeparator VGLib.concatenateWithSeparator
StrLib.copyStr VGLib.copyStr
StrLib.findStr VGLib.findStr
StrLib.integerAsChar StrLib.intAsChar
StrLib.setSubStr VGLib.setSubStr
StrLib.strLen StrLib.byteLen
StrLib.textLen StrLib.characterLen

Introduction 33
Table 2. Renamed system functions (continued)
Old name New name
SysLib.beginDatabaseTransaction SqlLib.beginDatabaseTransaction
SysLib.connect SqlLib.connect
SysLib.defineDatabaseAlias SqlLib.defineDatabaseAlias
SysLib.disconnect SqlLib.disconnect
SysLib.disconnectAll SqlLib.disconnectAll
SysLib.loadTable SqlLib.loadTable
SysLib.queryCurrentDatabase SqlLib.queryCurrentDatabase
SysLib.setCurrentDatabase SqlLib.setCurrentDatabase
SysLib.startTransaction VGLib.startTransaction
SysLib.unloadTable SqlLib.unloadTable

The following system functions have changed significantly in this version:


MathLib.round
In previous versions this function had a required parameter (the number to
be rounded) and an optional parameter (the power of ten to which to
round the number). In this version, both parameters are required. See
round().
SysLib.convert
This direction argument of this function was formerly an ″L″ or ″R″ literal
value. In this version, the function cannot accept a literal; instead, it
requires an argument of ConvertDirection.remote or
ConvertDirection.local. See convert().
SqlLib.Connect
This function was formerly SysLib.Connect, and its parameters have
changed:
v The fourth parameter, commitScope, is no longer used. The fifth, sixth,
and seventh parameters are now the fourth, fifth, and sixth parameters.
v When the isolationLevel parameter is not specified or is set to default,
the function uses the JDBC driver’s default isolation level, unless VAGen
compatibility mode is enabled.
v The default value of the isolationLevel parameter default, not
serializableTransaction.
See connect().
Change in casting syntax
In past versions, certain arguments in certain functions in JavaLib could
accept a casting operator in parentheses. Now, use the as keyword to cast a
variable, as in variable as "type".
Related Concepts
“What’s new in EGL V7.0” on page 18
“Language changes in EGL V7.0” on page 19
This topic lists the changes to the EGL language in version 7.0.
“Changes to build descriptor options in EGL V7.0” on page 35
“Changes to system libraries and variables in EGL V7.1” on page 15

34 EGL Programmer’s Guide


Changes to build descriptor options in EGL V7.0
New build descriptor options

The following build descriptor options are new in this version:


currencyLocation
See currencyLocation.
deploymentDescriptor
See Overview of EGL deployment descriptor file.
includeLineNumbers
See includeLineNumbers.
maxNumericDigits
See maxNumericDigits.
separatorSymbol
See separatorSymbol.
truncateExtraDecimals
See truncateExtraDecimals.
wrapperCompatibility
See wrapperCompatibility.

Removed build descriptor options

The following build descriptor options have been removed:


v initIORecords
v initNonIOData
v itemsNullable
Instead of the itemsNullable build descriptor option, use the
I4GLItemsNullable property. See the explanation of nullable types in “Language
changes in EGL V7.0” on page 19.
v serviceRuntime
v webServiceEncodingStyle

Some other build descriptor options were removed from V7.0 but are returned in
V7.1; see “Changes to build descriptor options in EGL V7.0.”

Changed build descriptor options

The following build descriptor options have changed significantly:


targetNLS
DES (Swiss German) is no longer a valid value for this build descriptor
option. Use DEU instead.
tempDirectory
This build descriptor option is now used to specify the directory in which
temporary files are stored when you generate with the EGL SDK.
Related Concepts
“What’s new in EGL V7.0” on page 18
“Language changes in EGL V7.0” on page 19
This topic lists the changes to the EGL language in version 7.0.
“Changes to system libraries and variables in EGL V7.0” on page 32

Introduction 35
“Changes to build descriptor options in EGL V7.1” on page 16

Changes to exception handling in EGL V7.0


This topic covers changes to the way EGL deals with exceptions in version 7.0.
Exception stereotype for Record parts
You can now define a Record with the type Exception, or use a number of
predefined Exception Records. The Exception stereotype is at the heart of a
new style of exception handling in EGL. Within a try block you can now
have multiple onException statements. Each onException statement must
include a declaration of an Exception record variable, as in the following
example:
try
get next mySerialRecord;
onException(myEx FileIOException)
myErrorHandler1(myEx);
onException(myEx AnyException)
myErrorHandler2(myEx);
end

The AnyException type is available to catch any exception not previously


specified.
When a function throws an exception that is not caught within the try
block or is not within a try block at all, control immediately returns to the
function that called it, if any, even if the exception occurs in a library
function. EGL passes the exception upward until an onException statement
catches it or the exception reaches the main function. If the main function
fails to catch the exception, the program ends immediately and writes the
message field of the exception to the log. When an exception occurs in a
called program, the calling program receives an InvocationException rather
than the original exception. Similarly, an exception in a service function
delivers a ServiceInvocationException to the calling program.
The Exception records contain various fields, depending on the exception
type. For a list of all system exception records and their fields, see EGL
core Exception records.
For more information about error handling, including throwing your own
exceptions, see “Handling errors” on page 148.
v60ExceptionCompatibility property
This new property allows you to continue to use the EGL version 6 style of
exception handling for backward compatibility. For more information, see
“V6 exception compatibility” on page 151.
Related Concepts
“What’s new in EGL V7.0” on page 18
“Language changes in EGL V7.0” on page 19
This topic lists the changes to the EGL language in version 7.0.
Related tasks
“Migrating from a previous version of EGL” on page 38

Changes to services in EGL V7.0


EGL’s service functionality has expanded significantly in this version. The way you
make a service available to other applications has changed, as has the way you

36 EGL Programmer’s Guide


make an EGL application act as a service requester. Also, you can now generate
services and requesters to iSeries COBOL and CICS.

Most important, the service binding library is no longer used. In its place is the
EGL deployment descriptor file, which defines both how your service requesters
access external services and how your service makes itself available to other
applications.

The Service part is essentially the same, except for some changes in properties, but
you now add Web service deployment information to the EGL deployment
descriptor file. Similarly, to act as a requester of a service (that is, to use the service
in one of your logic parts), you no longer call functions in the service binding
library. Instead, you create a variable to represent the service and then bind that
variable to the actual service using binding information in the EGL deployment
descriptor file. In this way, any logic part can now behave as a requester.
Related tasks
“Elements of a service-oriented application” on page 478
The major elements of an EGL service-oriented application are the service part,
interface part, and deployment descriptor file. In general, each of these files and
parts has a role in both services and service requesters.
“Overview of service-oriented architecture (SOA)” on page 475
Related reference
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.

User interface changes in EGL V7.0


Creating Web pages
The wizards used for creating different types of Web pages have been
consolidated into a single wizard. To create a Web page in an EGL Web
project, click File → New → Other → Web Page. In the New Web Page
window, be careful to select a WebContent folder in an EGL Web project
and to specify that you want a JSP file, either by selecting a JSP template
or adding the .jsp extension to the file name. See “Creating a Web page”
on page 392.
General workbench enhancements
Refactoring support is enhanced so you can move and rename parts
without having to make as many manual corrections. See “Moving parts”
on page 121 or “Renaming parts” on page 120.
EGL editor
The EGL editor now supports folding to temporarily hide sections of code,
and it has an ″Organize Imports″ option to order and simplify the import
statements in your code. The editor also provides context-sensitive help for
many EGL keywords if you highlight the keyword and press F1. See “The
EGL editor” on page 155, “Setting preferences for folding in the EGL
editor” on page 176, or “Setting preferences for organizing import
statements in the EGL editor” on page 178.
EGL debugger
When debugging an application, you can now jump to a specific line in the
code or run the application until a certain line in the code. See “EGL
debugger commands” on page 580. Also, you can set the debugger to use

Introduction 37
either the generated source or the EGL source for a called program or
service. See “Setting preferences for the EGL debugger” on page 604.
Cheat sheets
EGL offers a set of cheat sheets to lead you through common tasks. See
“Using cheat sheets” on page 166.
Generation options
You can now set which parts you want to generate automatically when
you save a file. See “Setting generation preferences” on page 180.
Transforming UML to EGL
You can design an application in UML and use the transformation
parameters editor to specify how that UML model should be transformed
into EGL source. See Generating source code from UML models and UML
Elements to EGL Transformation .
Data Access Application wizard
The Parts and Pages wizard and Data Parts wizard have been combined
into the Data Access Application wizard, which offers more flexibility in
creating data parts, logic parts, and Web pages to use with a database
connection. See “Creating a data access application” on page 208.
Build parts editor
The build parts editor is enhanced to enable you to automatically set build
descriptor options based on an existing database connection in the
workbench. See Editing build descriptor options in the build descriptor
part.
EGL deployment descriptor editor
EGL provides a graphical editor for working with the new EGL
deployment descriptor file. See “Changes to services in EGL V7.0” on page
36
Password encryption
EGL now encrypts your passwords in certain situations and provides a
utility for encrypting passwords manually. See “Encrypting passwords” on
page 146.
Related Concepts
“What’s new in EGL V7.0” on page 18
“Language changes in EGL V7.0” on page 19
This topic lists the changes to the EGL language in version 7.0.

Migrating from a previous version of EGL


This topic covers migration from an earlier version of EGL to the current version.
You can also migrate to the current version of EGL from other languages:
v For details on migrating source code written in VisualAge Generator, see the
IBM VisualAge Generator to EGL Migration Guide. This document is available
on the EGL Web site. A local copy is available at the topic Migrating from
VisualAge Generator to EGL.
v For details on migrating source code written in Informix® 4GL, see the IBM
Informix 4GL to EGL Conversion Utility User’s Guide. This document is
available on the EGL Web site. A local copy is available at the topic Converting
from IBM Informix 4GL to EGL.

38 EGL Programmer’s Guide


Everyone running a version of EGL earlier than version 7.0 must go through a
migration process before using EGL version 7.0 or later. Some minor migration
changes are required to move from version 7.0 to version 7.5.

EGL provides tools for these migration processes. You can migrate entire projects at
a time or select individual packages or files to migrate, but you must migrate JSP
files and their associated pageHandler parts at the same time. The tool corrects
syntax changes, updates invocations of system libraries that have changed, corrects
the names of properties that have changed, and makes other updates as described
in “Changes made by the V7.0 migration tool” on page 44.

Important: Do not use the migration tool on code that has already been updated
to EGL V7. Doing so can create errors in your code.

Before you begin, take these steps to prepare for migration:


v You may need to install APARs or PTFs or both to bring your runtime
environment (the environment in which you generate Java or COBOL from EGL)
to the correct level for EGL version 7.
v Back up your code.
v Set preferences before importing projects into your new workspace. For example,
if you use the VisualAge Generator compatibility preference, you must set it
before you bring in the files you want to convert.
v Import all projects referenced by the project that you are migrating into your
workspace. The migration tool attempts to resolve references to parts in the
migrated code. You do not have to migrate the referenced projects at the same
time, but they must be present for the tool to work properly.
v All Eclipse Web projects, not just EGL Web projects, are updated automatically
to work in the new version of the workbench. This does not mean that your
EGL code is migrated automatically, just that your Web projects are updated to
the current standard.
You can determine whether your Web projects are being updated by watching
for the Project Migration window when you open and build a Web project from
a previous version in the V7.0 workspace. If you do not have automatic builds
enabled, build the project manually by clicking the project and then clicking
Project → Build Project.
v Determine the current version level of your code, because the steps for
migration are different depending on your current version. Migration paths are
provided for code at the following levels:
– Version 5.1.2, up to but not including version 6.0 with iFix 001
– Version 6.0 with iFix 001, up to but not including version 6.0.1
– Version 6.0.1, up to but not including version 7.0
– Version 7.0 up to but not including version 7.1
– Version 7.1 up to but not including version 7.5

Follow the steps below to migrate EGL code to the current version, using the
section that represents your code’s current version:

Version 5.1.2, up to but not including version 6.0 with iFix 001
1. Migrate the code to version 6.0 iFix 001 as explained in “Migrating EGL code to
EGL V6.0 iFix 001” on page 56.
2. Make the following changes to the code manually to migrate the code to
version 6.0.1:

Introduction 39
v Make sure that none of your identifiers (such as variable or part names)
begins with the at symbol (@), which is now an operator.
v Change invocations of the following system functions, but only if the last
argument in the invocation is a numeric value, as evidenced by an error
message that indicates a problem with the argument’s primitive type.
Table 3. Manual changes to system functions
Old function New function
StrLib.compareStr VGLib.compareBytes
StrLib.CopyStr VGLib.copyBytes
StrLib.concatenate VGLib.concatenateBytes

3. Migrate the code from version 6.0.1 to version 7.0 as explained in “Migrating
EGL code to EGL V7.0” on page 43.

Version 6.0 with iFix 001, up to but not including version 6.0.1
1. Make the following changes to the code manually to migrate the code to
version 6.0.1:
v Make sure that none of your identifiers (such as variable or part names)
begins with the at symbol (@), which is now an operator.
v Change invocations of the following system functions, but only if the last
argument in the invocation is a numeric value, as evidenced by an error
message that indicates a problem with the argument’s primitive type.
Table 4. Manual changes to system functions
Old function New function
StrLib.compareStr VGLib.compareBytes
StrLib.CopyStr VGLib.copyBytes
StrLib.concatenate VGLib.concatenateBytes

2. Migrate the code from version 6.0.1 to version 7.0 as explained in “Migrating
EGL code to EGL V7.0” on page 43.

Version 6.0.1, up to but not including version 7.0


1. Migrate the code from version 6.0.1 to version 7.0 as explained in “Migrating
EGL code to EGL V7.0” on page 43.

Version 7.0 up to but not including version 7.1

No program is available to automate the migration from version 7.0 to version 7.1,
and in most cases no migration is necessary. Here are two exceptions:
v If you use forms and you migrated to V7, you must make changes in your code
by hand before you run V7.1. Most users with forms did not migrate to V7,
because forms are not supported in that version.
v If you are working with a Web project that was generated for V7.0 to 7.0.0.3 and
whose code will run in WebSphere Application Server and will access Web
services on any platform, you must change the project. However, no change is
necessary if the project is to run on a server other than WebSphere Application
Server.

The following changes are required to migrate forms from EGL V7 to V7.1:
v Add the @ operator to all printFloatingArea and screenFloatingArea properties.

40 EGL Programmer’s Guide


v Place all of the @printFloatingArea complex properties for a form inside the
new printFloatingAreas property.
v Place all of the @screenFloatingArea complex properties for a form inside the
new screenFloatingAreas property.

The following changes are necessary to the Web project mentioned earlier:
1. Switch the classloader for the WAR file in the associated EAR to
PARENT_FIRST as follows:
a. Double-click Deployment Descriptor: projectNameEAR found in the root of
the Web project, where projectName is the project name. This deployment
descriptor is a J2EE deployment descriptor, not an EGL deployment
descriptor.
b. In the deployment descriptor editor, go to the Deployment tab.
c. At the bottom of the Deployment page, find the Application section.
d. In the Applications list, select the .war file that represents the Web project.
e. Select PARENT_FIRST in the Classloader mode list.
f. Save and close the deployment descriptor.
2. Go to the Resource perspective (not to a Java, Web, or EGL perspective) and
remove the following jar files from projectName/WebContent/WEB-INF/lib:
axis.jar, commons-discovery-0.2.jar, commons-logging-1.0.4.jar, eglwsdl.jar,
jaxrpc.jar, saaj.jar, wsdl4j-1.5.1.jar
3. Regenerate the project, ensuring that the build descriptor option ServerType is
set to the appropriate version of WebSphere Application Server.

Version 7.1 up to but not including version 7.5

When you launch the product, all projects will be checked to see if migration is
needed. This check is also performed when you import a project or check a project
out of a source code manager. If you need to migrate, the Workspace will display a
message to that effect. You can then select the specific projects and resources to
migrate.

The following code changes require some files or projects to migrate from EGL
version 7.1 to version 7.5:
v ExternalType function parameters require the in modifier.
v The path to Apache jar files has changed.
v BIRT report files need ICU4J (International Components for Unicode for Java)
support.
Related concepts
“What’s new in EGL V7.0” on page 18
“Changes made by the V7.0 migration tool” on page 44
“Changes to exception handling in EGL V7.0” on page 36
This topic covers changes to the way EGL deals with exceptions in version 7.0.
“Changes to services in EGL V7.0” on page 36
“Changes not made by the V7.0 migration tool” on page 54
After migrating your code to V7.0, you might need to make manual changes.
Related tasks
“Setting EGL-to-EGL migration preferences” on page 42
“Migrating EGL code to EGL V6.0 iFix 001” on page 56
“Migrating EGL code to EGL V7.0” on page 43

Introduction 41
Setting EGL-to-EGL migration preferences
Preferences for the EGL-to-EGL migration wizard control how EGL code from prior
versions is migrated to the current version. Some of these preferences are
meaningful for both the version 6 and version 7 migration, and others apply only
to one migration. Follow these steps to set EGL migration preferences:
1. Enable the EGL V7.0 migration capability:
a. Click Window → Preferences.
b. Expand General and click Capabilities.
c. Click Advanced.
d. In the Advanced window, expand EGL Developer and select the EGL V7.0
Migration check box.
e. Click OK.
f. Click OK again.
2. Click Window → Preferences.
3. Expand EGL and click Migration. This page shows the settings for the
migration tool.
4. Choose how to resolve a naming conflict with a new reserved word by
clicking a radio button:
v Add suffix sets the migration tool to add a suffix to any words in the
source code that are now reserved words. In the text box by this radio
button, type the suffix you want the migration tool to add to the changed
word.
v Add prefix sets the migration tool to add a prefix to any words in the
source code that are now reserved words. In the text box by this radio
button, type the prefix you want the migration tool to add to the changed
word.
5. If your project has standalone functions, that is, functions that are not
contained by any other logic part, and those functions contain variables that
are now reference types (such as arrays), select the check box labeled Convert
assignment statements to move statements. See “Changes made by the V7.0
migration tool” on page 44 for more information on converting from
assignment statements to move statements for reference variables.
6. As explained in the section on nullable types in “Language changes in EGL
V7.0” on page 19, the itemsNullable build descriptor option has been
replaced with the I4GLItemsNullable property. The migration tool can add
this property to your logic parts automatically. Select the Add property
I4GLItemsNullable=yes if you want the migration tool to add this property.
7. The migration tool can set the new textLiteralDefaultIsString property to NO
for each part to preserve previous behavior in the way EGL treats text literals
(such as "Hello!"). See textLiteralDefaultIsString.
8. The migration tool can delete the Java files from your projects so that the Java
files can be re-generated from the EGL source. Select Prompt, Always, or
Never. This change affects only the Java files in the same project as EGL code
that you are migrating. If you are generating the EGL code into a different
project, delete those Java files manually.
9. The migration tool can set the deploymentDescriptor build descriptor option
to the name of an EGL deployment descriptor file in the project. It can update
all build descriptor files, just the default build descriptors, or none at all.
Select a radio button under Project build descriptors to update with the
deployment descriptor name.

42 EGL Programmer’s Guide


10. The migration tool can add Web service deployment information to the
project’s deployment descriptor file for each Service part it finds in the related
project. Select an option under Add a webservice element to the deployment
descriptor for every service.
11. The migration tool can remove Web service references from the J2EE
deployment descriptor because EGL now uses its own deployment descriptor
file for service references instead. If you want the migration tool to make this
change, select Remove Web Service references from the J2EE deployment
descriptor.
12. When migrating to V6.0, the migration tool adds level numbers to Record
parts that do not have level numbers. Set the default level number in the
Default level number for record structure field.
13. To add a qualifier to the values of properties that have a finite list of possible
values, select the Add qualifiers to enumeration property values check box.
If this box is checked, the migration tool will add the type of value to the
value name. This preference applies only to V6.0 migration.
14. Under Logging options, choose whether you want the tool to add a comment
to each file that it changes and whether you want the results of the migration
process saved to a log file.
15. When you are finished setting preferences, click OK to save your changes.
Related concepts
“Changes made by the V7.0 migration tool” on page 44
“Changes to exception handling in EGL V7.0” on page 36
This topic covers changes to the way EGL deals with exceptions in version 7.0.
“Changes to services in EGL V7.0” on page 36
“Language changes in EGL V7.0” on page 19
This topic lists the changes to the EGL language in version 7.0.
Related tasks
“Migrating from a previous version of EGL” on page 38

Migrating EGL code to EGL V7.0


Before migrating to EGL V7.0, ensure that you have followed the complete steps
for migration as explained in “Migrating from a previous version of EGL” on page
38.

Follow these steps to run the migration tool to migrate code from EGL version
6.0.1 or later to version 7.0:

Note: Do not use the migration tool on code that has already been updated to
EGL V7.0. Doing so can create errors in your code.
1. Enable the EGL V7.0 migration capability:
a. Click Window → Preferences.
b. Expand General and click Capabilities.
c. Click Advanced.
d. In the Advanced window, expand EGL Developer and select the check box
labeled EGL V7.0 Migration.
e. Click OK.
f. Click OK again.
2. Set the preferences for the migration process as described in “Setting
EGL-to-EGL migration preferences” on page 42.

Introduction 43
3. In the Project Explorer view, select the EGL projects, packages, folders, or files
that you want to migrate. You can select any number of EGL resources to
migrate. To select more than one resource at once, press and hold CTRL while
clicking the resources.
4. Right-click on a selected resource and then click EGL V7.0 Migration →
Migrate.
5. Inspect your code for errors and for places that do not comply with EGL V7.0.
You might need to make manual changes to your code as explained in
“Changes not made by the V7.0 migration tool” on page 54, “Changes to
services in EGL V7.0” on page 36, and “Changes to exception handling in EGL
V7.0” on page 36.
6. Optionally, you can disable the V7.0 migration capability to avoid migrating the
same code twice.

To review the changes that the tool made to the source code, do as follows:
1. In the Project Explorer view, right-click an EGL source file that has been
migrated and then click Compare With → Local History.
2. Examine the differences between the file in the workspace and the previous
version.
3. When you are finished reviewing the changes, click OK.
Related concepts
“Changes made by the V7.0 migration tool”
“Changes not made by the V7.0 migration tool” on page 54
After migrating your code to V7.0, you might need to make manual changes.
Related tasks
“Migrating from a previous version of EGL” on page 38
“Setting EGL-to-EGL migration preferences” on page 42

Changes made by the V7.0 migration tool


This topic lists the changes that the V7.0 migration tool makes. Some of these
changes can be controlled by the migration tool’s preferences. See “Setting
EGL-to-EGL migration preferences” on page 42 for more information.

General
Changes to projects
If you run the migration tool on an entire project and that project contains
a Service part or a Service Binding Library, the migration tool adds an EGL
Deployment Descriptor file to the project. See the section on changes to
services and service binding libraries later in this section.
If the preference to delete Java files is enabled, the migration tool deletes
the Java files from your projects so the Java files can be re-generated from
the EGL source. This change affects only the Java files that are in the same
project as the EGL code you are migrating. If you are generating the EGL
code into a different project, delete those Java files manually.
The migration tool updates project classpaths to reflect new names and
locations of JAR files, including removing JAR files that are no longer
used.
New reserved words
Depending on the preference settings, the migration tool adds a prefix or

44 EGL Programmer’s Guide


suffix to existing names that conflict with new reserved words. See ″New
reserved words″ in “Language changes in EGL V7.0” on page 19.

Properties
Changes to existing properties
The migration tool changes the values of properties that are no longer
quoted strings. See the section ″Some property values are no longer quoted
strings″ in “Language changes in EGL V7.0” on page 19. This change
includes the pcbParms property, in which case the migration tool changes
empty strings ("") to NULL.
The migration tool changes the keyItem property on records with the
stereotype relativeRecord to the recordNumItem property.
The migration tool changes the isNullable property to isSQLNullable.
The migration tool changes the value of the protect and outline property
on Text UI form fields to the ProtectKind and OutlineKind enumeration.
It puts the value of outline in brackets because this property is now an
array. The migration tool does not change the value of protect on fields in
a ConsoleForm record.
Table 5. Changes to the protect and outline properties on Text UI form fields
Old property and value New property and value
protect = yes protect = ProtectKind.protect
protect = no protect = ProtectKind.noProtect
protect = skip protect = ProtectKind.skipProtect
outline = box outline = [OutlineKind.box]
outline = noOutline outline = [OutlineKind.noOutline]

Exception compatibility
The migration tool sets v60ExceptionCompatibility to YES on the
following logic parts:
v Program
v Library
v Handler
v Service
Text literals
Depending on the preferences, the migration tool adds the code
textLiteralDefaultIsString = NO to the following parts to preserve
behavior from previous versions:
v Program
v Library
v Handler
v Service
v Records

Build descriptor options


wrapperCompatibility
If your .eglbld file does not include the wrapperCompatibility build
descriptor option, the migration process checks the value of the

Introduction 45
enableJavaWrapperGen build descriptor option. If enableJavaWrapperGen
is set to YES or ONLY, migration adds the wrapperCompatibility build
descriptor option and sets it to V6.
For more information on wrapperCompatibility, see wrapperCompatibility.

Variables
Variable scope within code blocks
As explained in ″Scope of variables within functions″ in “Language
changes in EGL V7.0” on page 19, variables are now in scope only after
their declaration, not before. The migration tool moves all local variable
declarations to the beginning of the code block. If that variable was
initialized, the migration tool converts the initializer into an assignment
statement and leaves the assignment statement where the original location
of the variable declaration was. If the variable was already at the beginning
of the code block, the migration tool moves its initializer into an
assignment statement and puts that assignment statement at the end of the
variable declarations.
Default specifier for INTERVAL variables
The migration tool adds a default format specifier to INTERVAL variables
without a specified format:
Table 6. Changes to INTERVAL variable declaration
Old code Migrated code
intval1 interval; intval1 interval("yyyyMM");

System functions and variables


General changes
v The migration tool changes uses of system functions and variables that
have changed names. See “Changes to system libraries and variables in
EGL V7.0” on page 32.
v The migration tool changes uses of the sysLib.convert() system function
to use the ConvertDirection enumeration, as in this example:
sysLib.convert(myOrderRec, ConvertDirection.local, myConvTable);

Values of ″L″ and ″R″ are changed to ConvertDirection.local and


ConvertDirection.remote, respectively.
v The fourth parameter of the SqlLib.Connect (formerlySysLib.Connect)
system function, commitScope, is no longer needed, so the migration tool
removes it. Also, the tool specifies the isolationLevel argument with a
value of serializableTransaction and the disconnectOption argument
with a value of explicit if these arguments are not already specified.
Some examples of how the migration tool deals with invocations of
SqlLib.Connect follow:
Table 7. Changes to calls to SqlLib.Connect
Old code Migrated code
SysLib.connect( a, b, c ); SQLLib.connect( a, b, c,
explicit,
serializableTransaction );
SysLib.connect( a, b, c, d ); SQLLib.connect( a, b, c,
explicit,
serializableTransaction );

46 EGL Programmer’s Guide


Table 7. Changes to calls to SqlLib.Connect (continued)
Old code Migrated code
SysLib.connect( a, b, c, d, e ); SQLLib.connect( a, b, c, e,
serializableTransaction );
SysLib.connect( a, b, c, d, e, f ); SQLLib.connect( a, b, c, e, f );
SysLib.connect( a, b, c, d, e, f, g ); SQLLib.connect( a, b, c, e, f, g );

v To maintain compatibility with rounding rules in previous versions, uses


of MathLib.round() with only one argument are changed to use
MathLib.assign(). Uses of MathLib.round() with two arguments are not
changed.
Table 8. Changes to uses of MathLib.round()
Old code Migrated code
result = round(x); assign(x, result);
result = round(x, powerOfTen); No change.

Also to maintain compatibility with rounding rules in previous versions,


the migration tool wraps calls to functions in MathLib within
MathLib.assign(). Some examples follow:
Table 9. Changes to uses of functions in MathLib
Old code Migrated code
result = abs(x); assign(abs(x), result);
result = pow(x, y); assign(pow(x, y), result);

This change affects the following functions:


– MathLib.abs()
– MathLib.acos()
– MathLib.asin()
– MathLib.atan()
– MathLib.atan2()
– MathLib.cos()
– MathLib.cosh()
– MathLib.exp()
– VGLib.floatingDifference()
– VGLib.floatingMod()
– VGLib.floatingProduct()
– VGLib.floatingQuotient()
– VGLib.floatingSum()
– MathLib.frexp()
– MathLib.ldexp()
– MathLib.log()
– MathLib.log10()
– MathLib.max()
– MathLib.min()
– MathLib.modf()
– MathLib.pow()

Introduction 47
– MathLib.sin()
– MathLib.sinh()
– MathLib.sqrt()
– MathLib.tan()
– MathLib.tanh()
Casting with system library JavaLib
In previous versions, certain arguments in certain functions in JavaLib
could accept a casting operator in parentheses. The migration tool changes
this casting to use the syntax variable as "type", as in these examples:
Table 10. Changes to casts in JavaLib functions
Old code Migrated code
(byte)myVar myVar as "java:byte"
(objId)myVar myVar as "objId:java"
(null)"java.lang.Integer" null as "java.lang.Integer"

Unnecessary conversion functions


The migration tool corrects uses of removed conversion functions. If the
conversion function is used as part of a mathematical expression, the tool
adds a cast as necessary:
Table 11. Migrated conversion functions
Old code Migrated code
result = stringAsInt(x); result = x;
result = stringAsInt(x) + 5; result = x as Int + 5;
result = stringAsFloat(x); result = x;
result = stringAsFloat(x) + 5; result = x as Float + 5;
result = stringAsDecimal(x); result = x;
result = stringAsDecimal(x) + 5; result = x as Decimal() + 5;

In the case of stringAsDecimal, the migration tool does not know what
length to give the resulting DECIMAL type, so you must manually enter a
length.

Reference types
Initializations for reference types
The migration tool adds an initial size to new arrays:
Table 12. Changes to array initializers
Old code Migrated code
newArray string[]; newArray string[0];

Also, the migration tool adds an initializer to reference variable


declarations without an initializer:
Table 13. Changes to console form initializers
Old code Migrated code
newForm consoleFormType; newForm consoleFormType{};

The migration tool initializes the following reference variables in this way:
v ArrayDictionary

48 EGL Programmer’s Guide


v BLOB
v CLOB
v Record parts with the stereotype consoleForm
v Dictionary
In a function definition containing an array with the out modifier, the
migration tool adds a new statement at the first line of the function to
initialize the array. For example, assume the following function definition:
function doSomething (myParam int[] out)
...
end

The migration tool changes this function definition to the following:


function doSomething (myParam int[] out)
myParam = new int[];
...
end

The migration tool makes this change only for arrays and only if the arrays
have the out modifier.
Assignment statements for reference types
When one reference variable is assigned to another, the migration tool
changes the assignment statement to a move statement to keep the
behavior consistent with previous versions. The following example
assumes that the variables array1 and array2 are arrays or other reference
variables:
Table 14. Changes to assignment statements for reference types
Old code Migrated code
array1 = array2; move array2 to array1;

The migration tool makes this change for the following types of variables:
v Array
v Dictionary
v ArrayDictionary
v Any
v Record parts with the stereotype ConsoleForm
For assignment statements in a standalone function part, that is, a function
that is not within a logic part, the migration tool attempts to change
assignment statements to move statements under the following conditions:
v If the migration tool can resolve both sides of an assignment statement
(that is, it can determine that the variables on both sides of the
assignment statement are created from a reference type), it changes the
assignment statement to a move statement as it does in any function.
v If the migration tool cannot resolve both sides of an assignment
statement, the associated migration preference takes effect. In this case, if
the migration preference is enabled, the tool changes the assignment
statement to a move statement as above. If the migration preference is
disabled, the tool makes no change to the assignment statement.

Nullable variables
Expressions with null values
The migration tool changes expressions with null values to the new

Introduction 49
nullability rules explained in “Language changes in EGL V7.0” on page 19.
Table 15. Migration of expressions with null values
Old code Migrated code
set myVar NULL; myVar = NULL;
myVar is NULL myVar == NULL

nullable modifier
The migration tool changes uses of the nullable modifier on function
parameters to sqlNullable.
itemsNullable build descriptor option
Depending on the preferences, the migration tool adds the
I4GLItemsNullable property to the following parts to replace the
itemsNullable build descriptor option:
v Program
v Handler
v Library
v Record

Other statements
move statements
To preserve the default behavior of the move statement in previous
versions, the migration tool adds the byName option to move statements
between two record or form variables.
For statements within a standalone function, the migration tool tries to
resolve the variables on both sides of the move statement before making a
change:
v If the migration tool can resolve both sides of a move statement (that is,
it can determine that the variables on both sides of the statement are
records or forms), it adds byName as it does in any function.
v If the migration tool cannot resolve both sides of the move statement, it
adds withV60Compat instead of byName to maintain compatibility with
the previous version.
The migration tool makes this change only if it can resolve both sides of
the assignment statement, or if the associated migration preference is
enabled. If it cannot resolve both sides of the assignment statement, and
the migration preference is disabled, the migration tool makes no change.
Changes to syntax of call, transfer, and show
The migration tool changes the uses of these three statements to comply
with their new syntax:
Table 16. Changes to call and transfer
Old code Migrated code
call xxx 1, 2 call "xxx" (1, 2)
norefresh {IsNoRefresh = yes,
externallyDefined; IsExternal = yes};
transfer to program xxx transfer to program "xxx"
passing yyy passing yyy
externallyDefined; {IsExternal = yes};

The migration tool makes a similar change to show statements.

50 EGL Programmer’s Guide


in array expression
The migration tool converts statements that use in with an array to use
from as well:
Table 17. Changes to in with an array
Old code Migrated code
if ( a in myArray[4] ) if ( a in myArray from 4 )

exit statement changes


In logic parts other than programs and standalone functions, the migration
tool changes the statement exit program to exit rununit. The tool makes
no change to exit statements within a program or standalone function.

Services
@WSDL and @XSD properties
The migration tool converts the @WSDL property to the @XML property
and removes the @XSD property. In the process, the tool converts the
elementName property field of the @WSDL property to the name property
field of the @XML property. The isLastParamReturnValue property field of
the @WSDL property is discarded.
Services and Service Binding Libraries
The migration tool removes the serviceBindingLibrary stereotype from
Library parts.
If the preference to add Web service elements to the deployment descriptor
is enabled, the migration tool creates an EGL deployment descriptor in the
project’s EGLSource folder and converts @EGLBinding and @WebBinding
properties from the interfaces in the service binding libraries into service
client binding information in that deployment descriptor. The tool copies
the WSDL file specified in the @WebBinding property to the EGLSource
folder of the current project
If the preference to add the deployment descriptor to the project’s build
descriptors is enabled, the migration tool sets the deploymentDescriptor
build descriptor option to the name of the new deployment descriptor,
which by default has the same name as the project.
If the preference to remove Web service references from the J2EE
deployment descriptor is enabled, the migration tool removes these
references.
The tool updates ServiceLib.getWebEndPoint and
ServiceLib.setWebEndPoint to ServiceLib.getWebServiceLocation and
ServiceLib.setWebServiceLocation, respectively.

PageHandler parts
Conversion to JSFHandler parts
v The migration tool changes pageHandler parts to Handler parts with the
stereotype JSFHandler.
v The tool converts the pageHandler onPageLoadFunction property to the
JSF Handler onConstructionFunction property.
v The tool adds cancelOnPageTransition = YES to all pageHandler parts
that do not have this property defined.
v The tool changes links to pages with the extension .jsp to .faces in
forward to URL statements and action properties. In forward to URL

Introduction 51
statements, the tool makes this change only if the target of the forward
to URL statement is a quoted string that ends with .jsp. In uses of the
action property, the tool makes this change only if the displayUse
property is set to hyperlink and the action property is a quoted string
that ends with .jsp. See “Running a Web page on a server” on page 448
for more information on file extensions of JSP files. Following are
examples of these changes:
Table 18. Changes to links in pageHandlers
Old code Migrated code
myLink string myLink string
{displayUse = hyperlink, {displayUse = hyperlink,
action="myPage.jsp"}; action="myPage.faces"};
forward to URL "myPage.jsp"; forward to URL "myPage.faces";

v The tool converts uses of value to initialization statements. If the


variable has both a value property and an initialization statement, the
migration tool uses the value of the value property, as in the following
examples:
Table 19. Changes to the value property in variables in PageHandler parts
Old code Migrated code
item1 string item1 string
{ value = "item1ValueProp" } {} = "item1ValueProp";
= "item1Initializer";
item2 string item2 string
{ value = "item3ValueProp" }; {} = "item3ValueProp";

v In some cases, the migration tool aliases variables or handler names


containing an underscore character to _005f.
JSP files
The migration tool makes changes to JSP files associated with pageHandler
parts to update references to variables in the JSF Handler. The tool makes
these changes only if you migrate the pageHandler parts at the same time
as you migrate the JSP files. These changes are in addition to the changes
that happen when the migration tool migrates the pageHandler parts to
JSF Handlers.
v For JSF tags such as <h:selectOneMenu> and any <h:selectItems> or
<h:selectItem> tag inside those tags, the migration tool updates the
value attribute to remove the EGL prefix and any suffix, such as
AsBoolean. The tool saves the changes only if the resulting value
attribute correctly references a variable in the JSF Handler.
For example, assume this <h:selectOneMenu> tag:
<h:selectOneMenu styleClass="selectOneMenu" id="menu1"
value="#{myPage.EGLmyComboBoxValue}">
<f:selectItems value="#{myPage.EGLmyComboBoxChoicesAsBoolean}"/>
</h:selectOneMenu>

The migration tool converts this tag to the following:


<h:selectOneMenu styleClass="selectOneMenu" id="menu1"
value="#{myPage.myComboBoxValue}">
<f:selectItems value="#{myPage.myComboBoxChoices}"/>
</h:selectOneMenu>
The migration tool makes this change for the following tags:
– <h:selectManyCheckboxlist>
52 EGL Programmer’s Guide
– <h:selectManyListbox>
– <h:selectManyMenu>
– <h:selectOneListbox>
– <h:selectOneMenu>
– <h:selectOneRadio>
It also makes the change for <f:selectItems> and <f:selectItem>
within these tags.
The migration tool removes the following suffixes:
– AsBoolean
– AsInteger
– AsIntegerArray
– AsReader
– AsSelectItemsList
– AsStream
In the case that the associated EGL variable is an array or data table
column and the properties selectFromListItem and selectType are set,
the migration tool makes additional changes to the value field:
– If the selectType property is set to index, the migration tool adds the
suffix _exeIdx.toArray.
– If the selectType property is set to value, the migration tool adds the
suffix .toArray.
v Similarly, the migration tool removes the EGL prefix and suffixes such as
AsBoolean from the value attribute of other tags on the page when the
value attribute is in the standard expression form for EGL variables in
the JSF Handler: #{beanName.variableName}. In this case, the tool also
adds a binding attribute with the following value:
#{beanName.variableName_Ref}

Where beanName is the name of the page bean (by default, the same
name as the JSF Handler) and variableName is the name of the variable
referred to in the value attribute.
v The migration tool updates any tags with actionListener attributes,
such as those on JSF command buttons. It changes
#{beanName.commandActionListener} to
#{beanName._commandActionListener}.
v For any other JSF attribute that contains an expression in the form
#{beanName.variableName}, the migration tool removes the EGL prefix
and any suffix such as AsBoolean or AsInteger from the list above.

Other parts
ConsoleForms
Because ConsoleForm parts are now generatable parts, the migration tool
checks each ConsoleForm to see if its name matches the name of its file. If
the file name does not match, and the file name is not already being used,
the tool creates a new file with the name of the ConsoleForm and moves
the ConsoleForm part into that new file, along with any necessary import
statements. If the file name is already being used, the migration tool makes
no change, and you will have to correct your ConsoleForm parts
accordingly.

Introduction 53
Interface parts
The migration tool removes the BasicInterface stereotype from Interface
parts. It also converts all Interface parts with the JavaObject stereotype to
ExternalType parts.
VGUIRecord parts
The migration tool sets the following properties on VGUIRecords:
v60ExceptionCompatibility = YES,
HandleHardIOErrors = NO,
ThrowNrfEofExceptions = YES
Related concepts
“Setting EGL-to-EGL migration preferences” on page 42
“Changes to build descriptor options in EGL V7.0” on page 35
“Language changes in EGL V7.0” on page 19
This topic lists the changes to the EGL language in version 7.0.
Related tasks
“Migrating from a previous version of EGL” on page 38

Changes not made by the V7.0 migration tool


After migrating your code to V7.0, you might need to make manual changes.
Project Builders
When importing a migrated project into a V7.0 workspace, the Generation
Results view might indicate that a part could not be generated due to a
missing default build descriptor even though you have set a default build
descriptor. To resolve this issue, update the builders for the project so that
the EGL Advanced Builder is listed after the EGL Build Parts Model
Builder and the EGL Validation Builder.
Follow these steps to edit the build order in this way:
1. In the Project Explorer view, right-click the project and then click
Properties.
2. In the Properties window, click Builders.
3. On the Builders page, select the EGL Advanced Builder.
4. Using the Down arrow button, move the EGL Advanced Builder
under the EGL Build Parts Model Builder and the EGL Validation
Builder.
5. Click OK.
Property resolution
If you define a part with the same name as an EGL property, EGL may
resolve references to that name with the user-defined part, rather than the
EGL property.
Casts in removed conversion functions
If you migrated a stringAsDecimal function, the migration tool may add a
cast to the DECIMAL type as necessary to maintain the behavior of the old
code. In this case, you will need to manually add a length.
For example, assume the following old code:
myStringNumber string = "5";
myResult decimal(7,2);
myResult = stringAsDecimal(myStringNumber) + 5;
The tool migrates this code to the following:

54 EGL Programmer’s Guide


myStringNumber string = "5";
myResult decimal(7,2);
myResult = myStringNumber as decimal() + 5;

You must add a length to the DECIMAL type, as in the following:


myStringNumber string = "5";
myResult decimal(7,2);
myResult = myStringNumber as decimal(7,2) + 5;
Naming conflicts between functions and variables
You cannot have a variable and a function within a logic part with the
same name. Rename the variable or the function.
Called programs without parameter lists
Programs that are the target of a call statement must have a parameter list.
This parameter list can be empty, but the parentheses denoting the
parameter list are now required.
Service migration with IBM WebSphere Application Server development tools
The migration tool attempts to remove outdated service references from
metadata files in the projects you migrate. However, it cannot remove the
references if either of the following circumstances apply:
v You did not install the IBM WebSphere Application Server development
tools optional component, or your version did not include IBM
WebSphere Application Server and the related development tools
v You are generating Java code into a project on which you did not run
the migration tool
In either of these cases, you must remove outdated service references from
your metadata files manually:
v For EGL Web projects, if you added service references to the Web
deployment descriptor file manually, delete any EGL-generated service
references from the file and retain any manually added references. If you
did not add any service references to the file manually, you must delete
the file. In most versions of J2EE, the Web deployment descriptor is
named web.xml and is located in the project’s WebContent/WEB-INF
folder. On J2EE 1.3, the file is named webservicesclient.xml and is
located in the same place.
v Similarly, remove any EGL-generated service references from the files
ibm-webservicesclient-ext.xmi and ibm-webservicesclient-bnd.xmi, also
found in WebContent/WEB-INF. If you added no references to these files
manually, you can delete the files, but you are not required to.
selectType property in JSF Handlers
If a variable in a JSF Handler has the selectType property set to index, that
variable must be an INT type.
selectFromListItem property
When a variable has the selectFromListItem property, the property’s value
cannot be a record array or an array of primitive variables within a record.
Valid types are a data table column or an array of primitive variables not
within a record. To use a record array or an array of primitive variables
within a record as a list of selection options, use the properties
selectedRowItem or selectedValueItem instead.
Related concepts
“Changes made by the V7.0 migration tool” on page 44
“Validation changes in EGL V7.0” on page 24
Related tasks
Introduction 55
“Migrating EGL code to EGL V7.0” on page 43
“Migrating from a previous version of EGL” on page 38
“Setting EGL-to-EGL migration preferences” on page 42

Migrating EGL code to EGL V6.0 iFix 001


The EGL V6.0 migration tool converts EGL source from versions V5.1.2 and V6.0 to
comply with EGL V6.0 iFix001.

Important: Do not use the migration tool on code that has already been updated
to EGL V6.0 iFix001. Doing so can create errors in your code.

The migration tool can be used on an entire project, a single file, or a selection of
files. Running the tool on a package or folder converts all of the EGL source files
in that package or folder. For more information on the code that is changed by the
migration tool, see “Changes made by the V6.0 iFix 001 migration tool” on page
57.

To migrate EGL code to EGL V6.0 iFix001, do as follows:


1. Enable the EGL migration capability:
a. Click Window → Preferences.
b. Expand General and click Capabilities.
c. Click Advanced.
d. In the Advanced window, expand EGL Developer and select the EGL V6.0
Migration check box.
e. Click OK.
f. Click OK again.
2. Set the preferences for the migration tool. See “Setting EGL-to-EGL migration
preferences” on page 42.
3. In the Project Explorer view, select the EGL projects, packages, folders, or files
that you want to migrate. You can select any number of EGL resources to
migrate. To select more than one resource at once, hold CTRL while clicking the
resources.
4. Right-click a selected resource and then click EGL V6.0 Migration → Migrate.
5. Optionally, you can disable the V6.0 migration capability to avoid migrating the
same code twice.

The migration tool converts the selected EGL source files to comply with EGL V6.0
iFix001. To review the changes that the tool made to the source code, do as follows:
1. In the Project Explorer view, right-click an EGL source file that has been
migrated and then click Compare With → Local History.
2. Examine the differences between the file in the workspace and the previous
version.
3. When you are finished reviewing the changes, click OK.
Related concepts
“Changes made by the V6.0 iFix 001 migration tool” on page 57
Related tasks
“Migrating from a previous version of EGL” on page 38
“Setting EGL-to-EGL migration preferences” on page 42

56 EGL Programmer’s Guide


Changes made by the V6.0 iFix 001 migration tool
The EGL V6.0 migration tool converts EGL source from V5.1.2 and V6.0 to comply
with EGL V6.0 iFix 001.

Important: Do not use the migration tool on code that has already been updated
to EGL V6.0 iFix 001. Doing so can create errors in your code.

The migration tool can add comments to each file it changes. It can also add
comments to the project’s log file. See “Setting EGL-to-EGL migration preferences”
on page 42.

The migration tool changes EGL code in these ways to comply with EGL V6.0 iFix
001 :
v The migration tool makes changes to the way properties are specified. For
information about the changes to properties, see “Changes to properties during
EGL V6.0 iFix 001 migration” on page 60.
v The migration tool searches for variables and part names that conflict with
reserved words. The migration tool changes those variable and part names by
adding a prefix or suffix as defined in the migration preferences. By default, the
tool adds the suffix _EGL to any name that is now a reserved word. The
migration tool does not rename objects of the CALL statement, and it does not
update references in EGL Build Part files. The following are examples of code
before and after using the migration tool.
Before migration:
Library Handler
boolean Bin(4);
End
After migration:
Library Handler_EGL
boolean_EGL Bin(4);
End
v The migration tool replaces the single equals sign (=) with the double equals
sign (==) when the single sign is used as a comparison operator. It does not
change the single equals sign when it is used as an assignment operator.
Before migration:
Function test(param int)
a int;
If(param = 3)
a = 0;
End
End
After migration:
Function test(param int)
a int;
If(param == 3)
a = 0;
End
End
v The migration tool adds level numbers to records that do not have level
numbers.
Before migration:
Record MyRecord
item1 int;
item2 int;
End

Introduction 57
After migration:
Record MyRecord
10 item1 int;
10 item2 int;
End
v The migration tool changes the declaration syntax of constants.
Before migration:
intConst 3;
After migration:
const intConst int = 3;
v The migration tool changes variables and function names that have been moved
to different libraries or renamed. This change affects variables and functions
from the sysLib and sysVar libraries.
Before migration:
sysLib.java();
clearRequestAttr();
After migration:
javaLib.invoke();
j2eeLib.clearRequestAttr();
A list of changed variables and function names from the sysLib and sysVar
libraries follows:
Table 20. Changed variable and function names from the sysLib and sysVar libraries
Before migration After migration
sysLib.dateValue dateTimeLib.dateValue()
sysLib.extendTimestampValue dateTimeLib.extend()
sysLib.formatDate strLib.formatDate()
sysLib.formatTime strLib.formatTime()
sysLib.formatTimestamp strLib.formatTimestamp()
sysLib.intervalValue dateTimeLib.intervalValue()
sysLib.timeValue dateTimeLib.timeValue()
sysLib.timestampValue dateTimeLib.timestampValue()
sysLib.java javaLib.invoke()
sysLib.javaGetField javaLib.getField()
sysLib.javaIsNull javaLib.isNull()
sysLib.javaIsObjID javaLib.isObjID()
sysLib.javaRemove javaLib.remove()
sysLib.javaRemoveAll javaLib.removeAll()
sysLib.javaSetField javaLib.setField()
sysLib.javaStore javaLib.store()
sysLib.javaStoreCopy javaLib.storeCopy()
sysLib.javaStoreField javaLib.storeField()
sysLib.javaStoreNew javaLib.storeNew()
sysLib.javaType javaLib.qualifiedTypeName()
sysLib.clearRequestAttr j2eeLib.clearRequestAttr()
sysLib.clearSessionAttr j2eeLib.clearSessionAttr()

58 EGL Programmer’s Guide


Table 20. Changed variable and function names from the sysLib and sysVar
libraries (continued)
Before migration After migration
sysLib.getRequestAttr j2eeLib.getRequestAttr()
sysLib.getSessionAttr j2eeLib.getSessionAttr()
sysLib.setRequestAttr j2eeLib.setRequestAttr()
sysLib.setSessionAttr j2eeLib.setSessionAttr()
sysLib.displayMsgNum converseLib.displayMsgNum()
sysLib.clearScreen converseLib.clearScreen()
sysLib.fieldInputLength converseLib.fieldInputLength()
sysLib.pageEject converseLib.pageEject()
sysLib.validationFailed converseLib.validationFailed()
sysLib.getVAGSysType vgLib.getVAGSysType()
sysLib.connectionService vgLib.connectionService()
sysVar.systemGregorianDateFormat vgVar.systemGregorianDateFormat
sysVar.systemJulianDateFormat vgVar.systemJulianDateFormat
sysVar.currentDate vgVar.currentGregorianDate
sysVar.currentFormattedDate vgVar.currentFormattedGregorianDate
sysVar.currentFormattedJulianDate vgVar.currentFormattedJulianDate
sysVar.currentFormattedTime vgVar.currentFormattedTime
sysVar.currentJulianDate vgVar.currentJulianDate
sysVar.currentShortDate vgVar.currentShortGregorianDate
sysVar.currentShortJulianDate vgVar.currentShortJulianDate
sysVar.currentTime dateTimeLib.currentTime
sysVar.currentTimeStamp dateTimeLib.currentTimeStamp
sysVar.handleHardIOErrors vgVar.handleHardIOErrors
sysVar.handlesysLibErrors vgVar.handlesysLibraryErrors
sysVar.handleOverflow vgVar.handleOverflow
sysVar.mqConditionCode vgVar.mqConditionCode
sysVar.sqlerrd vgVar.sqlerrd
sysVar.sqlerrmc vgVar.sqlerrmc
sysVar.sqlIsolationLevel vgVar.sqlIsolationLevel
sysVar.sqlWarn vgVar.sqlWarn
sysVar.commitOnConverse converseVar.commitOnConverse
sysVar.eventKey converseVar.eventKey
sysVar.printerAssociation converseVar.printerAssociation
sysVar.segmentedMode converseVar.segmentedMode
sysVar.validationMsgNum converseVar.validationMsgNum

v The migration tool sets the HandleHardIOErrors property to NO for all migrated
libraries, programs, and pageHandlers for which that property is not specified.
Related tasks
“Migrating EGL code to EGL V6.0 iFix 001” on page 56

Introduction 59
Related concepts
“Migrating from a previous version of EGL” on page 38
“Setting EGL-to-EGL migration preferences” on page 42
“Changes to properties during EGL V6.0 iFix 001 migration”
Related reference
EGL reserved words

Changes to properties during EGL V6.0 iFix 001 migration


The V6.0 migration tool makes significant changes to the way properties are
specified. A summary of these changes follows:
v The migration tool renames properties whose names have changed in EGL V6.0
iFix 001:
Table 21. Renamed properties
Before migration After migration
action actionFunction
boolean isBoolean
getOptions getOptionsRecord
msgDescriptor msgDescriptorRecord
onPageLoad onPageLoadFunction
openOptions openOptionsRecord
putOptions putOptionsRecord
queueDescriptor queueDescriptorRecord
range validValues
rangeMsgKey validValuesMsgKey
selectFromList selectFromListItem
sqlVar sqlVariableLen
validator validatorFunction
validatorMsgKey validatorFunctionMsgKey
validatorTable validatorDataTable
validatorTableMsgKey validatorDataTableMsgKey

v The migration tool adds double quotes to property values that are used as string
literals.
Before migration:
{ alias = prog }
After migration:
{ alias = "prog" }
The following properties are affected:
– alias
– column
– currency
– displayName
– fileName
– fillCharacter
– help

60 EGL Programmer’s Guide


– inputRequiredMsgKey
– minimumInputMsgKey
– msgResource
– msgTablePrefix
– pattern
– queueName
– rangeMsgKey
– tableNames
– title
– typeChkMsgKey
– validatorMsgKey
– validatorTableMsgKey
– value
– view
v The migration tool replaces parentheses with brackets when specifying array
literals as values for the following properties:
– formSize
– keyItems
– outline
– pageSize
– position
– range
– screenSize
– screenSizes
– tableNames
– tableNameVariables
– validationBypassFunctions
– validationBypassKeys
v For properties that take array literals, the migration tool puts single element
array literals in brackets to specify that an array with only one element is still an
array. The migration tool uses double sets of brackets for properties that take
arrays of arrays.
Before migration:
{ keyItems = var, screenSizes = (24, 80), range = (1, 9) }
After migration:
{ keyItems = ["var"], screenSizes = [[24, 80]], range = [[1, 9]] }
v The migration tool uses the keyword this instead of a variable name when
overriding properties for a specific element in an array.
Before migration:
Form myForm type TextForm
fieldArray char(10)[5] { fieldArray[1] {color = red } };
end
After migration:
Form myForm type TextForm
fieldArray char(10)[5] { this[1] {color = red } };
end
v The migration tool changes references to parts, functions, and fields, adding
quotes and brackets where appropriate.

Introduction 61
Before migration:
{ keyItems = (item1, item2) }
After migration:
{ keyItems = ["item1", "item2"] }

The following properties are affected by the migration tool in this way:
– action
– commandValueItem
– getOptions
– helpForm
– inputForm
– inputPageRecord
– inputRecord
– keyItem
– keyItems
– lengthItem
– msgDescriptorRecord
– msgField
– numElementsItem
– onPageLoadFunction
– openOptionsRecord
– putOptionsRecord
– queueDescriptorRecord
– redefines
– selectFromListItem
– tableNameVariables
– validationBypassFunctions
– validatorFunction
– validatorDataTable
v The migration tool assigns a default value of yes to any boolean properties that
were specified but not assigned a value.
Before migration:
{ isReadOnly }
After migration:
{ isReadOnly = yes}
The following properties are affected by the migration tool in this way:
– addSpaceForSOSI
– allowUnqualifiedItemReferences
– boolean
– bypassValidation
– containerContextDependent
– currency
– cursor
– deleteAfterUse
– detectable
– fill

62 EGL Programmer’s Guide


– helpGroup
– includeMsgInTransaction
– includeReferencedFunctions
– initialized
– inputRequired
– isDecimalDigit
– isHexDigit
– isNullable
– isReadOnly
– lowerCase
– masked
– modified
– needsSOSI
– newWindow
– numericSeparator
– openQueueExclusive
– pfKeyEquate
– resident
– runValidatorFromProgram
– segmented
– shared
– sqlVar
– upperCase
– wordWrap
– zeroFormat
v The migration tool splits the currency property into two properties: currency
and currencySymbol. The following table gives some examples of how the
migration tool changes the currency property.
Table 22. Changes to the currency property
Before migration After migration
{ currency = yes } { currency = yes }
{ currency = no } { currency = no }
{ currency = "usd" } { currency = yes, currencySymbol = "usd"
}

v The migration tool changes the values of the dateFormat and timeFormat
properties to be case sensitive. For more information, see ″Date, time, and
timestamp format specifiers″ in the EGL Language Reference.
v If the Add qualifiers to enumeration property values check box is selected in
the preferences menu, the migration tool adds the name of the enumeration to
the value of the property.
Before migration:
color = red
outline = box
After migration:
color = ColorKind.red
outline = OutlineKind.box

Introduction 63
This change affects the following properties:
– align
– color
– deviceType
– displayUse
– highlight
– indexOrientation
– intensity
– outline
– protect
– selectType
– sign
v The migration tool changes the values of the tableNames property to be an
array of arrays of strings. Each array of strings must have either one or two
elements. The first element is the table name, and the second element, if present,
is the table label. The following table gives some examples of how the migration
tool changes the tableNames property.
Table 23. Changes to the tableNames property
Before migration After migration
{ tableNames = (table1, table2) } { tableNames = [["table1"], ["table2"]] }
{ tableNames = (table1 t1, table2) } { tableNames = [["table1", "t1"],
["table2"]] }
{ tableNames = (table1 t1, table2 t2) } { tableNames = [["table1", "t1"],
["table2", "t2"]] }

v The migration tool changes the way dates, times and timestamps are specified,
including changing the values of the dateFormat and timeFormat properties to
be case sensitive. Following are some examples:
Table 24. Changes to dates, times, and timestamps
Before migration After migration
dateFormat = "yy/mm/dd" dateFormat = "yy/MM/dd"
dateFormat = "YYYY/MM/DD" dateFormat = "yyyy/MM/dd"
dateFormat = "YYYY/DDD" dateFormat = "yyyy/DDD"
timeFormat = "hh:mm:ss" timeFormat = "HH:mm:ss"

v The migration tool changes the values of the defaultSelectCondition property to


be of type sqlCondition.
Before migration:
{ defaultSelectCondition =
#sql{
hostVar02 = 4
}
}
After migration:
{ defaultSelectCondition =
#sqlCondition{ // no space between #sqlCondition and the brace
hostVar02 = 4
}
}

64 EGL Programmer’s Guide


v The migration tool replaces the NULL value of the fillCharacter to the empty
string value "".
Related tasks
“Migrating EGL code to EGL V6.0 iFix 001” on page 56
“Setting EGL-to-EGL migration preferences” on page 42
“Migrating from a previous version of EGL” on page 38
Related concepts
“Changes made by the V6.0 iFix 001 migration tool” on page 57
Date/time masks and format specifiers

Introduction 65
66 EGL Programmer’s Guide
Contents of an EGL application
This topic describes the artifacts found in a typical EGL application.

Projects

An EGL application contains one or more projects to hold and organize your code
in folders and files. A project is contained in a single physical folder in your
workspace, and that folder contains other folders, as described below.

You can have as many projects as you want, and those projects can be independent
or they can reference each other and use parts from each other’s packages. The
needs of your organization and design of the application that you are creating
determines your use of projects, packages, and files. There are no set guidelines for
how to use them. See “The EGL build path” on page 83 for information on
references between projects.

Folders

An EGL project can contain several folders. Some of these folders have default
names; for example, the EGL source files go in a folder named EGLSource by
default. The documentation often refers to these folders by their default name, but
be aware that they might have different names in your project.
Source code folder
EGL projects have at least one source code folder, named EGLSource by
default. The source folder contains all of the EGL source files, build files,
and deployment descriptor files for the project. EGL generates output code
only for files within a source code folder.
You can create packages within source folders or additional source code
folders to organize your files. See “Creating an EGL package” on page 89
or “Creating source folders” on page 87.
Generated code folder
When you are generating to Java, the EGL project has a folder to hold the
files that are created by the generation process. By default, the generated
code folder is named src, but in most cases (such as in the Project Explorer
view), it is labeled Java Resources, regardless of the actual folder name on
disk. Do not edit the files in the generated code folder, because they are
overwritten each time you generate the project.
For COBOL output, EGL puts the generated code into a directory outside
the workspace as specified by the genDirectory build descriptor option.
EGL then transfers the outputs to the target system based on the destHost
and other related build descriptor options.
EGLBin folder
The EGLBin folder is used to store internal representation files, which are
used by EGL in the generation and debugging processes.
Web content folder
For EGL Web projects, the Web content folder contains the Web pages,
style sheet files, and other files that control how the Web project will
display in a browser. By default, the Web content folder is named

© Copyright IBM Corp. 1996, 2008 67


WebContent. See “Elements of a JSF Web application” on page 389 for
information on the files specific to Web projects.
Packages
Packages are contained within source folders and group source files.
META-INF folder
For EGL plug-in projects, the META-INF folder contains the
MANIFEST.MF file.

Files

The two major types of EGL files are source files, files that contain EGL parts such
as programs, libraries, and records, and build files, files that contain EGL build
parts such as build descriptors. Generally, you will not have to spend much time
working with other types of files. The following is a list of the files most
commonly found in an EGL project:
Source files
Source files contain EGL logic parts and data parts, such as programs and
records. Source files always end in the extension .egl.
Build files
Build files contain EGL build parts, such as build descriptors. These files
have the extension .eglbld.
Deployment descriptors
EGL deployment descriptors, not to be confused with J2EE deployment
descriptors, contain information about deployment. These files have the
extension .egldd.
Web pages
EGL Web projects can contain one or more JSP Web pages controlled by
JSF Handler parts.
Internal representation files
Internal representation files are an intermediate step between EGL source
and generated source; they are used in generation and debugging. These
files have the extension .ir and are found in the EGLBin folder. Generally,
you can ignore these files, because EGL usually creates them automatically
from your source code and build files when the project is built.
By default, the workbench builds your projects automatically, prompting
EGL to create or update the .ir files. If you have turned off the automatic
builds, you can set a preference within EGL to build your projects when
necessary by clicking Window → Preferences → EGL → Generation and
selecting Build before generate.
However, if automatic builds and the EGL Build before generate
preference are both disabled, you must invoke a build manually before
generating or debugging. Otherwise, EGL will not have current .ir files
with which to generate your code; this situation might mean that the
generated output represents outdated source code, or that the generation
process will not have all the parts it needs to generate. To build a project,
select the project in the Project Explorer view and then click Project →
Build Project. To turn on automatic builds, click Project, and select Build
Automatically.
.eglpath
The EGL build path file is named .eglpath and is stored in the root of the
project. This file lists the locations that are searched for any part that is not

68 EGL Programmer’s Guide


found in the current project, including the source folders in the current
project and any other projects on the build path of the current project.
In the following example of an .eglpath file, EGLSource is a source folder
in the current project, and AnotherProject is a project in the EGL build
path:
<?xml version="1.0" encoding="UTF-8"?>
<eglpath>
<eglpathentry kind="src" path="EGLSource"/>
<eglpathentry kind="src" path="\AnotherProject"/>
</eglpath>
The source folders for AnotherProject are determined from the .eglpath file
in that project.
For more information, see “The EGL build path” on page 83.
.eglproject
This file contains basic information about the EGL project, such as where
its default build descriptors are located.
faces-config.xml
For EGL Web projects, EGL uses the JSF configuration file to determine
how to navigate from page to page. See “Elements of a JSF Web
application” on page 389 for information on the JSF configuration file and
for other files related to EGL Web projects.
Transformation parameter files
When creating EGL code from a UML model, you create a .TPM file that
specifies options for the transformation. See Generating source code from
UML models.
Other files
Your project might contain any number of other files that are not directly
related to EGL. For information about those types of files, use the search
function of the help system.

Files that apply only to EGL plug-in projects

EGL plug-in projects contain several files that are not, strictly speaking, EGL files.
Instead, these files are part of the standard definition of an Eclipse plug-in, or the
smallest independent unit of functionality in the Eclipse workbench. The
workbench itself is composed largely of a collection of plug-ins; you can extend the
workbench by adding additional plug-ins, either from a commercial product, an
open-source project, or plug-ins you create yourself. When you create an EGL
plug-in project, EGL adds the files necessary for the project to function as a
plug-in. EGL also adds the files necessary to define a run-time configuration of the
workbench.
plugin.xml
The plugin.xml file describes the extensions that your project adds to the
Eclipse framework. More specifically, this file contains an entry for the EGL
″player″ that controls the runtime operations of Console UI applications
that are running in rich client platform (RCP) mode. Also, when you
generate a project, EGL adds a reference in the plugin.xml file for each
Console UI program in the project. This reference is needed only when
running a Console UI program in RCP mode. You will rarely need to edit
the reference. The plugin.xml file is created when you generate a program
within an EGL plug-in project.

Contents of an EGL application 69


MANIFEST.MF
The MANIFEST.MF file describes the requirements for a program to run as
an RCP application. This file is tied closely to the plugin.xml file.
Product file
EGL plug-in projects contain a file named projectName.product, where
projectName is the name of the project. This file defines an Eclipse product,
which in this context refers to the launch configuration for a stand-alone
instance of the workbench. This file defines what plugins are included in
the workbench when running a program as an RCP application.
config.ini
For EGL plug-in projects, this file sets the value of system variables needed
for the launch configuration.
build.properties
This file specifies which files from the project should be used when the
plug-in is used in the workbench at run time.
Related concepts
Developing EGL applications
Enterprise Generation Language (EGL) is a programming language that you
can use to focus on business problems instead of software technologies. Within
the Rational development environment, you can use EGL wizards and other
tools to write complex applications with minimal effort.
Related tasks
“Creating an EGL project” on page 71
This topic covers how to create an EGL project.
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.
Related reference
Naming conventions

Introduction to EGL projects


In the Eclipse workbench, a project is a container for a group of related files. EGL
adopts this framework and keeps its source files in several different types of EGL
projects. These projects differ mainly in the types of user interface they support:
EGL project
A general EGL project is useful for batch or reporting applications, or
anything with a character-based user interface.
EGL Web project
EGL Web projects have most of the abilities of a general EGL project, plus
the ability to create applications with JSF Web interfaces. You cannot
convert any other type of project into an EGL Web project, and you cannot
convert EGL Web projects to EGL projects.
EGL plug-in project
EGL plug-in projects have all of the abilities of a standard EGL project plus
the ability to run Console UI programs in rich client platform (RCP) mode.
You can convert other types of EGL projects into an EGL plug-in project.
EGL Rich UI project
EGL Rich UI projects have most of the abilities of a general EGL project,
plus the ability to create Rich UI applications. You cannot convert any
other type of project into an EGL Rich UI project, and you cannot convert
EGL Rich UI projects to EGL projects.

70 EGL Programmer’s Guide


EGL Portlet Project
EGL portlet projects contain one or more portlets for use within an
enterprise portal framework.

EGL projects can also have additional features and facets added to them to add
support for more granular pieces of functionality. See “Features and facets of EGL
projects” on page 76.

Depending on the target server for the project, EGL Web projects can be connected
to an Enterprise Application Resource (EAR) project. EAR projects contain
information for deployment in the J2EE application framework. See J2EE
Applications.
Related tasks
“Creating an EGL project”
This topic covers how to create an EGL project.
“Creating an EGL Web project” on page 73
This topic covers how to create an EGL Web project.
“Creating an EGL plug-in project” on page 74
EGL plug-in projects, also called RCP projects, are useful for Console UI
applications that you want to run in rich client platform (RCP) mode. You can
create a new EGL plug-in project or convert an existing EGL project or EGL
Web project to an EGL plug-in project.
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
“Features and facets of EGL projects” on page 76
EGL projects can have additional abilities, added through features and facets.

Creating an EGL project


This topic covers how to create an EGL project.

To create an EGL project:


1. From the menu bar, click File → New → Project The New Project window
opens.
2. In the New Project window, expand EGL and click EGL Project Wizard. If
you do not seeEGL Project Wizard, select the Show All Wizards check box.
3. Click Next.
4. Type a name for the project in the Project name field.
5. Under EGL Project Types, select the type of project:
v For a project that can contain JSF Web pages or Web services, select Web
Project and see Creating an EGL Web project.
v For a general-use project appropriate for batch, reporting, or other
applications with simple user interfaces, select General Project and
continue with the instructions on this page.
v For a project that can contain portlets, select Portlet Project.
v For a project that can use rich client platform (RCP) user interface, select
Plug-in Project.
v For a project used to develop EGL Rich UI applications, select Rich UI
Project and see Starting to work with EGL Rich UI.
6. Under Target Runtime Platform, select the language to which EGL will
generate your project: Java or COBOL.

Contents of an EGL application 71


7. Under Build Descriptor Options, choose where the default build descriptor
for the project will be located or created:
v Create a new build descriptor means that EGL provides a new build
descriptor and writes it to a new build file (extension .eglbld) that has the
same name as the project.
To specify a default database connection in that build descriptor, click
Options. To change those values later, change the build file that is created
for you.
v Use the build descriptor specified in the EGL preferences means that EGL
points to a build descriptor that you created and identified as an EGL
preference.
v Select an existing build descriptor enables you to specify a build
descriptor from those that are available in your workspace.
8. If you want to configure other options for the project, such as the location of
the project or what additional EGL features to add, select Show Advanced
Settings and then click Next. Otherwise, click Finish.
9. Accept the default location for the project in the Project location section or
clear the Use the default location for the project check box and specify a new
location.
10. Under EGL Project Features Choices, select the check boxes for the additional
features to include in the project, if any. For more information on features, see
Features and facets of EGL projects.
11. If you want an EGL deployment descriptor in the project, select Create an
EGL service deployment descriptor. Selecting this check box also sets the
deploymentDescriptor build descriptor option to the name of the deployment
descriptor, which has the same name as the project.
12. Click Next.
13. On the Projects tab of the EGL Settings page, select any other projects in your
workspace to be added to the build path of the new project.
14. On the Order and Export tab of the EGL settings page, set the order for the
projects in the build path and select the check boxes for the projects that you
want to export along with the new project.
15. Click Finish.
Related concepts
“Introduction to EGL projects” on page 70
“Contents of an EGL application” on page 67
This topic describes the artifacts found in a typical EGL application.
“Features and facets of EGL projects” on page 76
EGL projects can have additional abilities, added through features and facets.
Related tasks
“Creating an EGL Web project” on page 73
This topic covers how to create an EGL Web project.
“Creating an EGL plug-in project” on page 74
EGL plug-in projects, also called RCP projects, are useful for Console UI
applications that you want to run in rich client platform (RCP) mode. You can
create a new EGL plug-in project or convert an existing EGL project or EGL
Web project to an EGL plug-in project.
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
“Specifying database options at project creation” on page 189

72 EGL Programmer’s Guide


“Renaming an EGL project” on page 75
If you rename an EGL project, you must manually correct most of the
references to that project.

Creating an EGL Web project


This topic covers how to create an EGL Web project.

The steps for creating an EGL Web project are similar to those for creating an EGL
project, but include additional steps for the target runtime, or the server that the
project will be deployed to. To set up a new EGL Web project:
1. From the menu bar, click File → New → Project The New Project window
opens.
2. In the New Project window, expand EGL and click EGL Project Wizard. If
you do not seeEGL Project Wizard, select the Show All Wizards check box.
3. Click Next.
4. Type a name for the project in the Project name field.
5. Under EGL Project Types, select Web project.
6. Click Next.
7. Choose a target runtime for the project in the Target Runtime list.
You are not required to choose a runtime right now, but you will need to
choose a runtime before you can run the project on a server or deploy the
project. It is best to choose a runtime now; you can change the target runtime
later.
8. Under Build Descriptor Options, choose where the default build descriptor
for the project will be located or created:
v Create a new build descriptor means that EGL provides a new build
descriptor and writes it to a new build file (extension .eglbld) that has the
same name as the project.
To specify a default database connection in that build descriptor, click
Options. To change those values later, change the build file that is created
for you.
v Use the build descriptor specified in the EGL preferences means that EGL
points to a build descriptor that you created and identified as an EGL
preference.
v Select an existing build descriptor enables you to specify a build
descriptor from those that are available in your workspace.
9. If you want to configure other options for the project, such as adding it to an
EAR application or adding additional facets, select Show Advanced Settings
and then click Next. Otherwise, click Finish.
10. Under Project location, you can choose to place the project in your
workspace, as is the default, or you can choose a different location.
11. Under EAR Membership, specify whether to include the project as a module
within an Enterprise Application Resource (EAR) project in the workspace:
v If you clear the Add project to an EAR check box, the project is not added
to an EAR project. You can add the new project to an EAR project later.
v If you select the Add project to an EAR check box and choose an existing
EAR project in the EAR Project Name list, the new project will be added to
that EAR project. The new project will use the EAR project’s target runtime,
regardless of your choice of runtime on the previous page.
v If you select the Add project to an EAR check box and type a name for a
new EAR project in the EAR Project Name list, the new EAR and EGL Web

Contents of an EGL application 73


projects will both use the runtime selected in the Target Runtime list on the
previous page. By default, the name of the new EAR project is the name of
the EGL Web project with the suffix EAR.
v If you selected a target runtime that does not support EAR projects on the
previous page, the EAR Project Name field is disabled.
12. Under EGL Project Features Choices, select the check boxes for the additional
features to include in the project, if any. For more information on features and
facets, see “Features and facets of EGL projects” on page 76.
13. If you want an EGL deployment descriptor in the project, select Create an
EGL service deployment descriptor. You must still set the
deploymentDescriptor build descriptor option to the name of the deployment
descriptor before the project will use the new deployment descriptor.
14. After you have filled out the information on the first page, you can click
Finish to complete the process and create the project with the default options,
or click Next to continue setting the remainder of the options. These
instructions continue with the remainder of the options.
15. On the Project Facets page, select any facets that you may want to add to your
project or select a preset facet configuration. See “Features and facets of EGL
projects” on page 76.
16. Click Next.
17. In the Context Root field, type a name for the root folder of the project when
the project is deployed to a Web server or accept the default, which the same
as the project name.
18. In the Content Directory field, type the name for the Web content folder. The
default name is WebContent.
19. In the Java Source Directory field, type the name for the generated code
folder. The default name is src.
20. Click Finish.
Related concepts
“Introduction to EGL projects” on page 70
“Contents of an EGL application” on page 67
This topic describes the artifacts found in a typical EGL application.
Related tasks
“Creating an EGL project” on page 71
This topic covers how to create an EGL project.
“Creating an EGL plug-in project”
EGL plug-in projects, also called RCP projects, are useful for Console UI
applications that you want to run in rich client platform (RCP) mode. You can
create a new EGL plug-in project or convert an existing EGL project or EGL
Web project to an EGL plug-in project.
“Adding JSF component interface support to an EGL Web project” on page 464
“Adding Web transaction support to an EGL Web project” on page 562

Creating an EGL plug-in project


EGL plug-in projects, also called RCP projects, are useful for Console UI
applications that you want to run in rich client platform (RCP) mode. You can
create a new EGL plug-in project or convert an existing EGL project or EGL Web
project to an EGL plug-in project.

For more information on the files in an EGL plug-in project, see “Contents of an
EGL application” on page 67

74 EGL Programmer’s Guide


Creating a new project
1. From the menu bar, click File → New → Project. The New Project window
opens.
2. In the New Project window, expand EGL and click EGL Project Wizard. If you
do not seeEGL Project Wizard, select the Show All Wizards check box.
3. Click Next.
4. Enter a name for the project in the Project name field.
5. Under EGL Project Types, select RCP Project.
6. Click Next.
7. Fill in the remainder of the options for your project. The remainder of the
options are the same as those for an EGL project. See “Creating an EGL project”
on page 71.
8. When you are finished, click Finish.

Converting a project

To convert an EGL project or an EGL Web project to an EGL plug-in project,


right-click the project in the Project Explorer view and then click Convert to EGL
Plug-in Project.
Related tasks
“Creating an EGL project” on page 71
This topic covers how to create an EGL project.
“Creating an EGL Web project” on page 73
This topic covers how to create an EGL Web project.
Related concepts
“Contents of an EGL application” on page 67
This topic describes the artifacts found in a typical EGL application.
“Building EGL Console User Interface applications” on page 513
Console User Interface, or Console UI, is a style of user interface similar to that
used on a UNIX-based program that interacts with a character-based terminal.
“Console UI modes” on page 529
EGL supports three modes in which you can run Console UI applications:
Swing, Curses, and rich client platform (RCP). The three modes have different
abilities, but in general a Console UI application behaves the same way in each
mode.

Renaming an EGL project


If you rename an EGL project, you must manually correct most of the references to
that project.

To rename an EGL project:


1. In the Project Explorer view, right-click the project and click Refactor →
Rename.
2. In the Rename Java Project window, type a new name for the project.
3. Select the Update references check box. If you select this check box, EGL will
make the following changes in addition to renaming the project itself:
v EGL corrects the value of the genProject build descriptor option to the new
name of the project.
v EGL corrects the .eglproject file to point to the default build descriptors for
the renamed project.

Contents of an EGL application 75


v For Program parts within an EGL plug-in project, EGL corrects the reference
to the program in the plugin.xml file.
4. Click Preview to see the changes that will be made as a result of renaming the
project.
5. To complete the process, click OK.

You must manually correct any other references to the new project name,
including:
v References to the project in other projects’ EGL build path. See “Editing the
build path” on page 84.
v How the project is shared in a source code repository.
v References to files in the project, such as build files used in other projects.
Related concepts
“Introduction to EGL projects” on page 70
“Contents of an EGL application” on page 67
This topic describes the artifacts found in a typical EGL application.
Related tasks
“Creating an EGL project” on page 71
This topic covers how to create an EGL project.
“Renaming parts” on page 120
You can use the refactoring function of the workbench to rename parts and
correct references to those parts.
“Renaming a source file” on page 91
You can use the refactoring function of the workbench to rename source files
and correct references to those files.

Features and facets of EGL projects


EGL projects can have additional abilities, added through features and facets.

Features
EGL project features add support for a particular behavior or type of project. After
you add a feature to a project, you cannot remove it, although there is rarely any
reason to remove a feature. The features that a project can have depend on the
type of project; if you do not see a particular feature as an option for your project,
make sure you are using the correct type of EGL project.

You can specify features at project creation or add features to a project later. To add
features at project creation, see “Creating an EGL project” on page 71. To add a
feature to an existing project, follow these steps:
1. In the Project Explorer view, right-click the project and then click Properties.
The Properties window opens.
2. Click EGL Project Features. The check boxes under EGL Project Features
Choices are the features that you can apply to your project:
Create an EGL service deployment descriptor
Select this feature if the project contains programs that are available as
services.
EGL with BIRT report support
Select this feature if you want to create BIRT reports based on data in
the project.

76 EGL Programmer’s Guide


EGL with Jasper report support
Select this feature if you want to create Jasper reports based on data in
the project. This feature is not available in Web projects.
EGL with low-level MQ API support
Select this feature if you want to access message cues using API calls
rather than EGL statements like get and add.
EGL with LDAP support
Select this feature if you want to add files to your project that let you
retrieve security information from an LDAP compliant server.
EGL with i5/OS® objects support
Select this feature if you want to be able to access data queues or other
objects in the iSeries environment.
If you selected a feature as a default, it will be grayed out on the individual
project Properties window. You will find information about default features
later in this section.
3. Select the check boxes next to the features that you want to add to your project.
If a check box is already selected, that feature has already been added to the
project and you cannot remove it.
4. Click OK.

You can also choose the features that are applied to your new EGL projects by
default:
1. Click Window → Preferences. The Preferences window opens.
2. Click EGL.
3. Under Default EGL Project Features Choices, select the features to you add to
each new project by default.

EGL projects support the following features:


Table 25. Features and projects
EGL Web EGL plug-in EGL portlet
Feature EGL project project project project
Jasper report Yes No Yes No
support
BIRT report Yes Yes Yes No
support
EGL with LDAP Yes Yes Yes ?
support

For more information, see the individual topic that explains how to add the feature
to your project.

For more information about what the features do, see the related links at the end
of this topic.

Facets

Facets define characteristics and requirements for projects in the J2EE framework.
Unlike EGL project features, which in this context are exclusive to EGL projects,
project facets can be applied to any project that behaves as a J2EE module, with

Contents of an EGL application 77


certain restrictions. Therefore, within EGL, you can add features only to EGL Web
projects and EGL Web projects that have been converted to EGL plug-in projects.

Like project features, you can add facets at project creation or add them to an
existing project. Follow these steps to add a facet to an existing project:
1. In the Project Explorer view, right-click the EGL Web project and then click
Properties. The Properties window opens.
2. Click Project Facets. The list shows the facets currently in the project.
3. ClickAdd/Remove Project Facets. The Project Facets window opens.
4. In the Project Facets window, select the check boxes next to the facets tat you
want this project to have.
Only the facets that are valid for the project are listed:
v The list of runtimes selected for the project limits the facets shown in the list.
Only the facets that are compatible with all selected target runtimes are
shown.
v The currently selected facets and their version numbers limit the other facets
shown in the list. For example, if the project contains the Dynamic Web
Module facet, the EJB Module facet is not listed because these two facets
cannot be in the same project.
You can find out more about the requirements and limitations for each facet by
right-clicking the facet name and then clicking Show Constraints. You can also
choose a preset combination of facets from the Configurations list.
5. Choose a version number for the facet by clicking the current version number
and selecting the version number from the drop-down list.
6. To remove a facet, clear its check box. Not all facets can be removed.
7. If you want to limit the project so that it will be compatible with one or more
runtimes, click the Show Runtimes button and select the runtimes that you
want the project to be compatible with.
8. Click Finish.
9. Click OK.

You can also choose the facets that are applied to your new EGL Web projects by
default:
1. Click Window → Preferences. The Preferences window opens.
2. Click EGL.
3. Under Default EGL Web Project Facet Choices, select the facets that you want
to be added to each new EGL Web project by default.

Unlike project features, some facets can be removed from a project. Also unlike
project features, facets have version numbers, and facets can depend on the
presence or absence of other facets and specific version numbers of those facets.
Project features do not have version numbers.

Like project features, facets can depend on certain project types. For more
information on the EGL-specific facets, see the individual topic that explains how
to add the facet to your project. For more information on facets in general, see
Project Facets.
Related tasks
“Adding JSF component interface support to an EGL Web project” on page 464

78 EGL Programmer’s Guide


“Adding support for Jasper reports to a project” on page 549
Before you can create reports with EGL and Jasper, you must add support for
Jasper reports to your project and add a Java compiler to your system’s path
variable.
“Adding support for BIRT reports to a project” on page 553
Before your EGL code can create BIRT reports, you must add support to your
project. You need to add support only once for each project, and you do not
need to remove support if you stop using BIRT reports. During this beta,
support is available for General and Plug-in projects.
“Accessing an LDAP-compliant server” on page 190
EGL provides a code sample that you can customize to retrieve security or
other details from a server accessed by way of Lightweight Directory Access
Protocol (LDAP).
“Using direct MQ API calls” on page 240
The MQ API is a set of program interfaces used to request services from the
message queue manager.
“Accessing an LDAP-compliant server” on page 190
EGL provides a code sample that you can customize to retrieve security or
other details from a server accessed by way of Lightweight Directory Access
Protocol (LDAP).

Sharing projects
This topic explains the options for sharing projects between computers, as well as
some of the possible problems in doing so.

There are two main ways of transferring projects or files to another computer or
workspace:
v Storing them in a source repository and version control system, such as CVS or
Rational ClearCase®. This method provides the best results for development
code for many reasons, including the ability to synchronize changes, resolve
conflicts, and collaborate on code. See “Sharing projects in a repository” on page
82.
v Exporting an EGL project to the local file system. This method is appropriate
when you want to share a project a single time. See “Importing and exporting
projects” on page 81.

Files to share

Generally, share only the files that someone else needs to work with the project. Do
not share any files that can be generated from other files.

Share the following files, unless you have a reason not to do so:
v EGL source files
v EGL build files
v EGL deployment descriptors
v Non-derived metadata files in the project, such as .eglpath and .eglproject
files
v Files necessary for Web projects to run on a server, including faces-config.xml,
JSP files, web.xml, and files in the Enterprise Application Resource project, if you
have one

Do not share the following files in a repository unless you have a reason to do so:

Contents of an EGL application 79


v Derived files, including the .ir files found in the EGLBin folder
v Output files generated from EGL source files, such as .java files and .class files

Regardless of the type of project, do not share derived files. Derived files are
generated from source files and are not original data, so it is usually unnecessary
to share them. In the context of EGL Java generation, derived files include the Java
source files that are created during the generation process as well as the Java class
files created from those Java source files. EGL source files and build files are not
considered derived, but .ir files created from the source files are derived.

Including derived files increases the size of the artifacts that you share. Moreover,
including derived files might not be useful because they can be regenerated and
overwritten when the files are imported into another workspace. However, you
may want to share derived files if the person you are sharing the project with
cannot generate the derived files, or if you are trying to diagnose problems with
the derived files.

The workbench maintains a flag on each file to specify whether the file is derived
or not. For example, class files created from Java files and .ir files created from
EGL source files are automatically marked as derived. However, the workbench
does not mark Java source files as derived, even if they are generated from EGL
source files. In EGL, these Java source files are still considered derived because
they are created from EGL source files.

You can see whether a file is marked as derived by right-clicking the file in the
Project Explorer view or Navigator view, clicking Properties and moving to the
Info page. (You may want to use the Navigator view to examine derived files
because the Project Explorer view filters out some types of derived files, such as
EGL .ir files.) If the Derived check box on the file’s Properties window is selected,
the file is marked as derived. However, many sharing methods (including Project
Interchange files and some types of repositories) do not retain the derived flag. If
you share a derived file and someone else checks out the file, that file will no
longer be marked as derived.

For more information on which files are considered derived and why you would
or would not want to include them, see Derived resources.

Possible errors

When sharing projects, dependencies and links within the projects can break as the
projects are moved to different locations. The following are some common tasks
that you might need to perform to correct errors that you encounter while sharing
projects:
v Correct project dependencies, if it has other projects in its build path.
v Make sure that the project can find imported parts in the new location, if any
source files use import statements to refer to other EGL parts.
v Verify that links between Web pages still work.
Related concepts
“Introduction to EGL projects” on page 70
Related tasks
“Importing and exporting projects” on page 81
The workbench includes several ways to import projects and files from your
local file system and export them to your local file system.

80 EGL Programmer’s Guide


“Sharing projects in a repository” on page 82
These general guidelines describe EGL files that you will most likely share in a
repository or source-control system. The guidelines also cover some common
problems you might encounter when sharing EGL projects.

Importing and exporting projects


The workbench includes several ways to import projects and files from your local
file system and export them to your local file system.

Importing and exporting with Project Interchange

Project Interchange files are archive files that contain one or more projects, making
them appropriate for sharing entire projects at once. Follow these steps to export
one or more of your projects as a Project Interchange file:
1. Click File → Export. The Export window opens.
2. Under Select an export destination, expand Other and click Project
Interchange.
3. Click Next.
4. On the Export Projects page, select the check boxes next to the projects that you
want to export in the Project Interchange file.
5. In the To zip file field, select the name and location for the exported file.
6. If you want to include derived files in the exported file, select the Include
derived files check box.
See “Sharing projects” on page 79 for information on derived files. Derived files
generated from source files and are not original data, so it is typically
unnecessary to include them when sharing projects.
7. Click Finish.

Follow these steps to import one or more of the projects in a Project Interchange
file:
1. Click File → Import. The Import window opens.
2. Under Select an import source, expand Other and click Project Interchange.
3. Click Next.
4. On the Import Projects page, select the projects you want to import.
5. Click Finish.

Importing and exporting individual files

With the workbench, you can also import and export individual files as separate
files or as a single archive file. Follow these steps to export individual files from
your workspace to your local file system:
1. Click File → Export.
2. In the Export window, expand General and choose a format for your output
files. These are some of the common formats:
v File System exports files to your local file system as individual files, the
same as they are within the workbench.
v Archive File compresses files into an archive file and saves that archive file
to your local files system.
3. Click Next.
4. Select the files that you want to export and select a location for the exported
file or files.

Contents of an EGL application 81


5. Click Finish.

To import files into your workspace, you must first have a project to put the new
files in. Follow these steps to import individual files into your workspace from
your file system:
1. Click File → Import.
2. In the Import window, select the type of file you want to import. These are
some of the common formats:
v File System imports one or more files directly into a project in your
workspace.
v Archive File extracts one or more files from an archive file and imports those
files into the workspace.
3. Click Next.
4. Select the location of the files that you want to import and the folder in your
workspace into which you want to import the files.
5. Click Finish.
Related concepts
“Introduction to EGL projects” on page 70
“Sharing projects” on page 79
This topic explains the options for sharing projects between computers, as well
as some of the possible problems in doing so.
Related tasks
“Sharing projects in a repository”
These general guidelines describe EGL files that you will most likely share in a
repository or source-control system. The guidelines also cover some common
problems you might encounter when sharing EGL projects.

Sharing projects in a repository


These general guidelines describe EGL files that you will most likely share in a
repository or source-control system. The guidelines also cover some common
problems you might encounter when sharing EGL projects.

The way that you share your projects in a repository or source-control system
depends on the type of repository or source-control system. In general, share
source files and build files but not derived files, files that are created from other
files. This way, the files in the repository are limited to only those necessary for the
application. (If you edit a file directly, it is probably not derived.) For a discussion
of derived files in the context of EGL, see “Sharing projects” on page 79.

Also, when you share projects in a repository, be aware of these possible problems:
v If derived files are checked into a repository, they often lose their derived flags.
In this case, files that you normally wouldn’t check into a repository may appear
to need to be stored in a repository.
v Checking files into a repository can break connections between files. For
example, if you check a UML model and a TPM file into a repository and then
check them back out again, the workbench might not know that the two are
associated. For information on this problem, see Linking a UML model to an
existing TPM file.
v When sharing projects in a repository, the projects are subject to the same
potential errors as described in “Sharing projects” on page 79.
Related concepts
“Introduction to EGL projects” on page 70

82 EGL Programmer’s Guide


“Sharing projects” on page 79
This topic explains the options for sharing projects between computers, as well
as some of the possible problems in doing so.
Related tasks
“Importing and exporting projects” on page 81
The workbench includes several ways to import projects and files from your
local file system and export them to your local file system.

The EGL build path


EGL projects contain a build path, which lists other EGL projects that you want to
use in the current project.

For example, suppose project A contains a Record part and you want to create a
variable based on that Record part in project B. You could copy the source file
from project A into project B, but that would mean duplicating the file. Instead,
you can add project A to the build path of project B. Then, you can use the Record
part in project B as though the definition were in project B. Scoping rules still
apply, however, so you might need to import the part to bring it into scope.

A project build path includes the following items:


v A list of EGL source folders in the current project
v The location of the generated output folder, which is meaningful only for Java
generation
v Zero to many projects to include in the build path

Adding other projects to the build path is useful only while you are coding; for
example, the EGL build path enables content assist to find other parts and insert
correct import statements. The EGL build path also provides a way for validation
to flag unknown parts and functions. If you are generating to Java, to allow your
project to use parts in another project at run time, you must make that project
available at run time. See “Editing the build path” on page 84.

The order of the items in the build path is significant because EGL searches for
parts based on the order of the folders and projects in the build path. See Name
resolution in an expression. For this reason, the source folders of the current
project are usually the first items in the build path.

You can also choose to export a project or source folder in your build path. In this
case, the exported project or source folder is available to all projects that refer to
the current project. For example, take the following project build paths:
v Project C
C, D, Y
v Project D
D, E, Z
If, in the build path for project D, you choose to export project E but not project Z,
the effective build path for project C is as follows:
C, D, E, Y

In this case, project D can use project Z, because Z is in D’s build path. However,
project C cannot use project Z because Z, is not exported along with project D.
Project C can use project E, because project E is exported along with project D.

Contents of an EGL application 83


When working with multiple EGL projects, you should be careful not to create
packages with identical names in two different projects. Also, you must be careful
to avoid circular references, that is, build paths that make an infinite loop.

To add or remove projects in the build path, or to set exporting for a project on the
build path, see “Editing the build path.”

In general, the build path information is stored in the .eglpath file in the root of
the project. However, if you generate output code using the EGL SDK, the build
path is determined through the command-line argument eglpath, which is a list of
operating-system directories that are searched when the EGL SDK attempts to
resolve a part reference. The eglpath argument behaves much like the .eglpath file
except that you cannot export source folders with the eglpath argument as you can
with the .eglpath file. See the EGL Generation Guide for more information on
generating in the SDK.
Related tasks
“Editing the build path”

Building projects
To build EGL output for Java programs, complete the following steps:
1. Generate Java source code into a project or directory: If you generate code into
a project (for best results) and if your Eclipse preferences are set to build
automatically on resource modification, the workbench prepares the output. If
you generate into a directory, distributed build function of the generator
prepares the output.
2. Prepare the generated output. This step is done automatically unless you set
the buildPlan or prep build descriptor options to no.

Details for generating source code are located in the EGL Generation Guide.
Related tasks
“Editing the build path”

Editing the build path


See “The EGL build path” on page 83 for information on the build path.

To include projects in the EGL build path, follow these steps:


1. In the Project Explorer view, right-click a project that you want to link to other
projects and then click Properties. The Properties window opens.
2. Select the EGL Build Path properties page.
3. A list of all other projects in your workspace is displayed in the Projects tab.
Click the check box beside each project that you want to add to the project’s
build path.
4. To put the projects in a different order or to export any of them, click the Order
and Export tab and do as follows:
v To change the position of a project in the build-path order, select the project
and click the Up and Down buttons.
v To export a project, select the related check box. To handle all the projects at
once, click the Select All or Deselect All button.
5. Click OK.

If you are generating to Java and want to use parts in a referenced project at run
time, you must make the referenced project available at run time. You can either

84 EGL Programmer’s Guide


add that project to the Java build path of the current project, or you can add the
referenced project to your project as a JAR file.

To add a project to the Java build path of your project:


1. In the Project Explorer view, right-click a project that you want to link to other
projects and then click Properties. The Properties window opens.
2. Select the Java Build Path properties page.
3. On the Java Build Path page, click Projects tab.
4. Click Add,
5. Select the check boxes next to the projects that you want to add and then click
OK.
6. Click OK again.

Follow these steps to add a referenced project as a JAR file:


1. Right-click the project that you want to use in your project and then click
Export.
2. In the Export window, expand Java and click JAR file.
3. Click Next.
4. Under Select the resources to export, select the check box next to the project
that you want to export.
5. In the JAR file field, set the location for the JAR file.
6. Click Finish.
7. Right-click the project in which you want to use the referenced project and
then click Properties.
8. In the Properties window, click Java Build Path.
9. Go to the Libraries tab.
10. Click Add external JARs.
11. Select the JAR file that you exported and click Open.
12. Click OK.
Related concepts
“The EGL build path” on page 83
EGL projects contain a build path, which lists other EGL projects that you want
to use in the current project.
Related reference
EGL projects, packages, and files
Parts

The Eclipse build order


The build order is an Eclipse concept, as opposed to the build path, which EGL
maintains.

Eclipse maintains a build order for projects that share code (such as record
definitions), share variables, or call each other’s programs.

A key concept here is project cycles. A project cycle involves two or more projects
with mutual dependencies. For example, assume that Project1 contains parts A and
C, and Project2 contains parts B and D. A depends on B, B depends on C, and C
depends on D. If EGL builds Project1 first, it finds errors in parts A and C because
it cannot resolve references to parts B and D. After building Project2, which

Contents of an EGL application 85


produces no errors because A and C have already been built in Project1, EGL
builds Project1 again to resolve the errors in A and C.

Eclipse determines the build order by asking each project for its dependencies,
which EGL generates using the .eglpath file (see “The EGL build path” on page
83). If the workspace contains no cycles, the order that Eclipse determines is the
most efficient, and allows EGL to build all the projects in a single pass.

However, Eclipse does not take project cycles into account. If there are project
cycles in the workspace, EGL may be able to modify the build order to improve
workspace build times. When you click Project → Optimize EGL Project Build
Order, EGL attempts to move projects that are involved in cycles to a more
optimal spot in the build order.

You can manually change the build order through the workspace preferences
(Window → Preferences → General → Workspace → Build Order). Changing these
preferences manually may cause build errors. You can also use the Build Order
preference page to revert changes introduced in the build order by the
optimization operation.

You can change the Max iterations when building with cycles field on the Build
Order preferences page. The value of this field limits the number of times the build
will cycle through the projects. If this value is too low, the build may terminate
before resolving all errors.
Related concepts
“Using EGL with the Eclipse IDE” on page 1
The Eclipse IDE offers a graphical user interface (GUI) called the workbench, in
which users perform work by pointing and clicking objects on the screen as
well as by typing code. In this way, when you are working with EGL, you are
using the Eclipse workbench, so it is worth taking a minute to look at the tools
in the workbench.
“The EGL build path” on page 83
EGL projects contain a build path, which lists other EGL projects that you want
to use in the current project.

Source folders
EGL source folders contain EGL packages and files. By default, each new EGL
project has a source folder named EGLSource. You can add and remove source
folders as necessary to organize your code at high levels, but generally, EGL
projects have only one source folder and the packages within that source folder
provide the organization. You can create EGL packages only within an EGL source
folder, and EGL generates output code only for files within a source folder.
Related concepts
“Contents of an EGL application” on page 67
This topic describes the artifacts found in a typical EGL application.
Related tasks
“Creating source folders” on page 87
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.

86 EGL Programmer’s Guide


Creating source folders
After you create a project in the workbench, you can create one or more folders
within that project to contain your EGL files.

To create a folder for grouping EGL files, complete these steps:


1. From the main menu, click File → New → EGL Source Folder. The New Source
Folder window opens.
2. In the Project name field, specify the project to contain the new source folder.
3. Specify a name for the folder in the Folder name field.
4. Click Finish.
Related concepts
“Contents of an EGL application” on page 67
This topic describes the artifacts found in a typical EGL application.
“Source folders” on page 86
Related tasks
“Creating an EGL project” on page 71
This topic covers how to create an EGL project.
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.
Related reference
Naming conventions

Introduction to EGL packages


Packages work like folders: they organize source files and prevent naming
conflicts.

Technically speaking, a package is a named collection of related parts, but it can be


easier to think of a package in the same way as a folder or directory on your local
system.

Packages prevent name conflicts by separating files into different contexts. Two
parts with the same name cannot be defined in the same package, but two
different packages can each have a part with the same name. Likewise, you should
prevent conflicts between packages by not creating packages with the same name,
even if those packages are in different projects or source folders.

The parts in an EGL source file all belong to the same package. The package
statement in the file, if any, specifies the name of that package. If you do not
specify a package statement, the parts are stored in the root of the source folder
and are considered to be in the default package. Because files in the default package
cannot be shared by parts in other packages or projects, it is best to specify a
package statement.

Package names are case sensitive. For more information on naming conventions for
packages, see package.

Contents of an EGL application 87


Working with packages

When you want a part to reference another part that is in the same package, you
do not need to specify the location of the second part. The following example
shows two parts in the same package: a Record part and a Program part that uses
the record part:
package com.companyb.firstpackage;

program testProgram type BasicProgram


function main()
myVariable myRecordPart;
end
end

Record myRecordPart type BasicRecord


field1 int;
field2 string;
end

When you want a part to reference another part that is in a different package,
specify the complete location of the part within its package. For example, the
following Program part uses the Record part from the previous example:
package com.companyb.secondpackage;

program testProgram2 type BasicProgram


function main()
myVariable2 com.companyb.firstpackage.myRecordPart;
end
end

As shorthand, you can use the import statement to tell EGL that you want to use
the part in the source file. If you import a part in this way, you can use the part as
though it were in the current package, without specifying the complete location of
the part within its package each time you use it. Sometimes, importing a part in
this way is called ″bringing the part into scope.″

For example, the following Program part again uses the Record part defined
earlier, but this time it imports the part first:
package com.companyb.thirdpackage;

import com.companyb.firstpackage.myRecordPart;

program testProgram3 type BasicProgram


function main()
myVariable3 myRecordPart;
end
end

Note that the import statement uses the package path to the part and the part
name, not the source file name.

For more information on import, see “Import and use statements” on page 124.
Related concepts
“Contents of an EGL application” on page 67
This topic describes the artifacts found in a typical EGL application.
Related reference
package
Scope

88 EGL Programmer’s Guide


“Import and use statements” on page 124
Use the EGL import and use statements to expand the visibility of code
elements.

Creating an EGL package


An EGL package is a named collection of related source parts. To create an EGL
package, do the following:
1. Identify a project or folder to contain the package. You must create a project or
folder if you do not already have one.
2. In the workbench, click File → New → EGL Package.
3. Select the project or folder that will contain the EGL package. The Source
folder field might be pre-populated depending on the current selection in the
Project Explorer.
4. In the Package name field, type the name of the EGL package.
5. Click the Finish button.
Related concepts
“Introduction to EGL projects” on page 70
Related tasks
“Creating an EGL Web project” on page 73
This topic covers how to create an EGL Web project.
“Creating an EGL project” on page 71
This topic covers how to create an EGL project.

Introduction to EGL files


The two most common types of files in an EGL project are source files and build
files. EGL also uses deployment descriptors in service applications and service
client applications.

Source files

Source files contain EGL source code in units called logic parts and data parts. You
can have any number of logic parts and data parts in any one source file, except
that you can have only one generatable part in a source file. See “Introduction to
EGL parts” on page 95.

Source files have an extension of .egl and are written in EGL source format.

Build files

Build files contain information EGL uses to generate and deploy applications.
Build files are written in Extensible Markup Language (XML) and have the
extension .eglbld. This type of file contains build parts such as build descriptor
parts, linkage options parts, and resource associations parts.

Whenever possible, use the build parts editor provided in the workbench to work
with build parts and build files. However, it is possible to edit a build file with a
text editor or XML editor.

Deployment descriptors

Deployment descriptors contain information that describes how EGL services will
be made available to other applications and how EGL applications will find

Contents of an EGL application 89


services provided by other applications. Deployment descriptor files have an
extension of .egldd and open in the deployment descriptor editor.
Related reference
Naming conventions
“Contents of an EGL application” on page 67
This topic describes the artifacts found in a typical EGL application.

Creating EGL source files


The creation process is essentially the same for most EGL source files.

Follow these steps to create a source file that contains an EGL part:
1. You must specify a project or folder when you create an EGL source file. You
can do this in one of two ways:
v Right-click a project or folder in your workspace and click New → Other.
v With a project or folder selected in your workspace, click File → New → Other
If you have not yet created a project or folder, you must do so before creating
parts. See “Creating an EGL project” on page 71
2. From the Select a wizard window, expand EGL, and click the type of part you
want to create. If you do not see the part type you are looking for, click Show
All Wizards. The following instructions cover any of these parts:
v DataTable
v EGL Source File (generic wizard)
v FormGroup
v Interface
v JSF Handler
v Library
v Program
v Report Handler
v Service
Click Next
3. EGL displays a new part wizard. In the Source folder field, EGL shows the
project or folder you previously selected. You can change this name to that of
another existing project or folder if you chose the wrong one initially.
4. In the Package field, select a package to hold the new file. If the package name
you enter here does not exist, EGL creates it for you. To ensure that you use the
correct name of an existing package, click Browse and locate the package name.
5. In the EGL source file name field, type a name for the new file. The file name
must be same as the part name. For example, assume your file will define a
program named checkCustomerBalance:
Program checkCustomerBalance type BasicProgram
...
end
In this case you must name the file checkCustomerBalance. EGL will add the
.egl extension to file name automatically.
File names that contain EGL parts must conform to EGL part naming
conventions. For more information, see Naming conventions
6. Some wizards require further information. You can learn about these options in
the appropriate topic for the specific part:
v DataTable part

90 EGL Programmer’s Guide


v “Introduction to Library parts” on page 110
v “Transfer of control across programs” on page 251
v “Overview of service-oriented architecture (SOA)” on page 475
7. Click Finish.
Related concepts
“Introduction to EGL files” on page 89
Related tasks
“Creating an EGL project” on page 71
This topic covers how to create an EGL project.
Related reference
Naming conventions

Renaming a source file


You can use the refactoring function of the workbench to rename source files and
correct references to those files.

With refactoring, you can rename EGL source files or JSP files that are controlled
by a JSF Handler.
1. In one of the following places, select the file you want to rename:
v Right-click the file in the Project Explorer view
v For files that contain a generatable part, right-click the generatable part in
the Outline view, Parts List view, or Parts Reference view
v For files that contain a generatable part, place the cursor on the generatable
part’s name in the EGL editor and right-click
2. From the pop-up menu, click Refactor → Rename. The Rename Part window
opens.
3. In the Rename Part window, type a new name for the file, following EGL
naming conventions.
4. You can click Preview for a list of the changes EGL will make if you proceed.
5. If you clear the Update references check box, EGL will not search other files
for references to change. In most instances, select this check box.
6. Click OK.

Renaming a file makes the following changes:


v EGL changes the name of the file to the new name
v For files that contain a generatable part, EGL changes the name of the part to
match the new file name
v For files that contain a generatable part, EGL searches the build path for
references to that part and changes the references to match the new name of the
part. For example, if you rename a file that contains a called program, EGL
changes the code that calls that program to use the new name.
v For files that contain a JSF Handler, EGL links the JSP file to the new file and
changes any references in the JSP to the JSF Handler to use the new name, but it
does not change the name of the JSP file.
v For files that contain a JSF Handler, EGL updates references to the file in the
faces configuration file.
v For JSP files that are controlled by a JSF Handler, EGL updates the view
property of the JSF Handler to refer to the new JSP file.

Contents of an EGL application 91


v For Program parts within an EGL plug-in project, EGL corrects the reference to
the program in the plugin.xml file.

You might still need to check for other changes caused by refactoring. For example,
EGL does not change labels used with the forward statement. Suppose that you
have a line of code that passes control to a JSF Handler like this:
forward to "myWebPage";

In this case, if you renamed myWebPage, EGL does not change this forward
statement to reflect the new label for the page. You must search for changes and
update the files manually.
Related concepts
“Generatable parts and non-generatable parts” on page 96
EGL parts can be generatable or non-generatable.
“Introduction to EGL files” on page 89
“Introduction to EGL parts” on page 95
Parts are the building blocks of EGL applications.
Related tasks
“Moving a source file”
You can use the refactoring function of the workbench to move source files and
correct references to those files.
“Renaming parts” on page 120
You can use the refactoring function of the workbench to rename parts and
correct references to those parts.
“Moving parts” on page 121
You can use the refactoring function of the workbench to move parts between
source files and correct references to those parts.
“Deleting a source file” on page 93
You can delete a source file using the workbench.
“Renaming an EGL project” on page 75
If you rename an EGL project, you must manually correct most of the
references to that project.

Moving a source file


You can use the refactoring function of the workbench to move source files and
correct references to those files.

With refactoring, you can move EGL source files to a new location in an EGL
package in your workspace.
1. In the Project Explorer view, right-click the file and then click Refactor → Move.
The Move window opens.
2. In the Move window, select a destination for the file. You can create a new
package for the file with the Create Package button.
3. You can click Preview for a list of the changes that EGL will make if you
proceed.
4. If you clear the Update references to the moved elements check box, EGL will
not search other files for references to change. In most instances, select this
check box.
5. Click OK.

Moving a file makes the following changes:

92 EGL Programmer’s Guide


v EGL moves the file to the new location
v EGL updates the package statement in the file
v EGL searches the build path for references to parts in the file and updates
references and import statements as necessary
v For files containing a JSF Handler, EGL links the JSP file to the new file and
changes any references in the JSP to the JSF Handler to use the new name, but it
does not change the name of the JSP file.
v For files containing a JSF Handler, EGL updates references to the file in the faces
configuration file.
v For Program parts within an EGL plug-in project, EGL also corrects the reference
to the program in the plugin.xml file.

You might still need to check for other changes that refactoring causes.
Related concepts
“Introduction to EGL files” on page 89
Related tasks
“Renaming a source file” on page 91
You can use the refactoring function of the workbench to rename source files
and correct references to those files.
“Renaming parts” on page 120
You can use the refactoring function of the workbench to rename parts and
correct references to those parts.
“Moving parts” on page 121
You can use the refactoring function of the workbench to move parts between
source files and correct references to those parts.
“Deleting a source file”
You can delete a source file using the workbench.

Deleting a source file


You can delete a source file using the workbench.

To delete a source file, select it in the Project Explorer view and:


v Press Delete
v Click Edit → Delete
v Right-click the file and then click Delete

In most cases, EGL does not correct references to the file as it does when you
rename or move a source file. However, if the project is an EGL plug-in project and
the file you are deleting contains a Program part, EGL removes the reference to
that program in the plugin.xml file.
Related concepts
“Introduction to EGL files” on page 89
Related tasks
“Renaming a source file” on page 91
You can use the refactoring function of the workbench to rename source files
and correct references to those files.
“Moving a source file” on page 92
You can use the refactoring function of the workbench to move source files and
correct references to those files.

Contents of an EGL application 93


“Renaming parts” on page 120
You can use the refactoring function of the workbench to rename parts and
correct references to those parts.
“Moving parts” on page 121
You can use the refactoring function of the workbench to move parts between
source files and correct references to those parts.

Creating EGL build files


To create an EGL build file, complete these steps:
1. Identify a project or folder to contain the file. If you do not already have a
project or folder, you must create one.
2. From the main menu, click File → New → EGL Build File.
3. From the Select Container window, type the project or folder that will contain
the EGL build file in the Enter or select the parent folder field or use the
directory tree to select the location.
4. Click Advanced to link the file to an existing file in the file system. Type the
name of the file to be linked in the text box or click Browse to locate the file.
Click Variables to work with the variables in the file that you specify.
5. Type the name of the build file in the File name field.
6. Optionally, you can click Next to select EGL parts to populate the file.
7. Click Finish to create the file without populating it with an EGL part. An
extension (.eglbld) is automatically appended to the end of the file name. The
EGL build file is displayed in the Project Explorer view and automatically
opens in the default EGL editor.
Related concepts
“Introduction to EGL projects” on page 70
“Introduction to EGL parts” on page 95
Parts are the building blocks of EGL applications.
Developing EGL applications
Enterprise Generation Language (EGL) is a programming language that you
can use to focus on business problems instead of software technologies. Within
the Rational development environment, you can use EGL wizards and other
tools to write complex applications with minimal effort.

Creating a deployment descriptor


The EGL deployment descriptor provides service-binding detail when you are
generating a service, as well as service-binding detail when you are generating a
logical unit (program, library, handler, or service) that invokes a service.

The EGL deployment descriptor is distinct from JEE deployment descriptors. For
information on JEE deployment descriptors, see Defining JEE enterprise
applications (EARs).

You can have as many deployment descriptors in your EGL project as you want,
but only one can be selected as the main deployment descriptor in the
deploymentDescriptor build descriptor option. That main deployment descriptor
can include entries from other deployment descriptor files, linking the main
deployment descriptor to the other deployment descriptors without directly
copying their information. Alternately, you can copy the information from one
deployment descriptor directly into another deployment descriptor.

Follow these steps to create a new EGL deployment descriptor file:

94 EGL Programmer’s Guide


1. Click File → New → Other. The New window opens.
2. In the New window, expand EGL and click Deployment Descriptor.
3. Click Next.
4. In the Source folder field, select an EGL source folder in an EGL project. You
can add a deployment descriptor only to EGL projects.
5. Type a name for the file in the EGL deployment descriptor file name field.
6. Click Finish.

The new deployment descriptor file is created and opens in the editor. The next
step is to configure your project to use the new deployment descriptor. There are
several ways to configure your project in this way:
v If this is the only deployment descriptor in your project, set the
deploymentDescriptor build descriptor option to the name of the deployment
descriptor file, omitting the .egldd extension.
v You can include entries from one deployment descriptor in another.
v You can copy the entries from one deployment descriptor into another.
Related concepts
“Overview of service-oriented architecture (SOA)” on page 475
Related tasks
“Adding Web service deployment information to the deployment descriptor”
on page 496
After you have coded a service part that you want to expose as a Web service,
you must add information to the deployment descriptor that tells EGL to
generate the necessary Web service wrapper.
“Calling a remote service” on page 485
You can call remote services from your EGL logic parts.
“Exposing a service to other applications” on page 493
Your EGL application can act as a service by exposing its functions to other
applications.

Introduction to EGL parts


Parts are the building blocks of EGL applications.

EGL includes these basic kinds of parts:


Logic parts
Logic parts define a sequence of instructions. Logic parts contain one or
more functions, which are the basic unit of logic. Logic parts include
Program parts and Library parts, which are general-use parts, as well as
Service parts, ExternalType parts, and Handler parts, which have more
specialized uses.
Data parts
Data parts define a structure that stores data. Data parts form the basis for
a variable that you can use in a logic part. Data parts can hold one piece of
data, as in a primitive or DataItem, or they can hold many pieces of data,
as in a Record part. See “Introduction to data parts” on page 97.
User interface parts
User interface parts define the information presented to a user or the logic
required when interacting with a user. Some user interface parts are
defined with a stereotype of a Record part, as is the case with
ConsoleForms and VGUIRecords, which specify the information that you

Contents of an EGL application 95


want to appear on the user interface. Others are defined with a stereotype
of a logic part, as is the case with JSFHandlers, ReportHandlers, and
VGWebTransactions. Other user interface parts are parts in their own right,
such as FormGroups.
Build parts
Build parts control the generation process and set how the application will
behave at run time. The most commonly used kind of build part is the
build descriptor part, which contains a list of build descriptor options to
define how the EGL code will be generated to the output language. Other
build parts control how the application will work with other applications
and resources at run time.
Deployment descriptors
Deployment descriptors contain information that describes how EGL
services will be made available to other applications and how EGL
applications will find services provided by other applications.
Related concepts
“Contents of an EGL application” on page 67
This topic describes the artifacts found in a typical EGL application.
Related reference
Parts

Generatable parts and non-generatable parts


EGL parts can be generatable or non-generatable.

Generatable parts are the parts on which you can begin the generation process. For
example, you cannot start the generation process on a DataItem part or a Record
part with the BasicRecord stereotype. Instead, you must start the generation
process on a generatable part such as a Program part; in the process, any
non-generatable parts used in that Program part, such as Records and DataItems,
are generated as well.

The following parts are generatable:


v Program parts of all stereotypes except VGWebTransaction
v Library parts of all stereotypes
v Handler parts of all stereotypes
v Service parts
v DataTable parts
v Record parts with the stereotype ConsoleForm
v Record parts with the stereotype VGUIRecord
v Program parts with the stereotype VGWebTransaction
v FormGroup parts
v EGL deployment descriptors

Generatable parts have these characteristics:


v A source file can contain zero or one generatable parts. Any number of
non-generatable parts can be included in the same source file as the generatable
part.

96 EGL Programmer’s Guide


v The generatable part must have the same name as the source file, minus the
source file’s .egl extension. The case of the names must match. EGL deployment
descriptors are considered generatable even though they do not have a part
name separate from the file name.
Related concepts
“Introduction to EGL parts” on page 95
Parts are the building blocks of EGL applications.

Introduction to data parts


Data parts define a structure that stores one or more pieces of data. Data parts
form the basis for a variable that you can use in a logic part.

These are the three most common types of data part:


Primitives
EGL supplies simple data types similar to those found in most other
programming languages, such as numbers, dates, characters, and large
objects. Primitives form the basis for more complex data types. Here are
two examples of variables created from primitives:
myInteger int;
myString char(50);

You can find a complete list of primitives in ″Primitive data types″ in the
EGL Language Reference. See “Commonly used primitives” on page 98 for
the primitives you are most likely to work with.
DataItems
A dataItem part is a customized primitive. To create a dataItem, choose
one primitive and add properties that adjust the behavior of the part. The
properties that a dataItem can accept depend on its primitive type and the
context in which it is used. Here are a few examples of dataItem parts:
DataItem myZipCodeItem int
{validValues = [00000,99999]} end
DataItem myAddressItem char(50)
{upperCase = YES} end

In this case, the first dataItem is built from an integer primitive, but is
limited with the validValues property to include only the integers between
0 and 99999. The second dataItem is built from the character primitive with
50 characters, and it is set to convert any user input into its value to upper
case.

When you create a variable in a logic part, you can use a dataItem part as
the variable type instead of the primitive. The following example creates a
variable from a dataItem part in the previous example:
zipVar myZipCodeItem;
The following variable is equivalent to the previous one:
zipVar int {validValues = [00000,99999]};
In this way, a dataItem part is simply an alias for a primitive type that has
specific property settings.
Records
Record parts are structured collections of other data parts, such as
primitives, dataItems, or other records. These other data parts within the

Contents of an EGL application 97


record part are referred to as its fields. Generally, a record part represents a
table in a database, with one field for each column in the table:
Record myCustomerRecord type BasicRecord
customerNumber int;
customerFirstName string;
customerLastName string;
customerBalance float;
end

This record has four fields: one integer, two strings, and one floating-point
number. These fields could just as easily be dataItems or other records.

Strictly speaking, the data part itself doesn’t store data; a variable created from that
data part stores the data. In this way, you can think of a data part as a pattern for
a variable. You can declare a variable simply by naming the variable and then
specifying the data part that you want to use:
myVariable1 int;
myVariable2 myDataItemPart;
myVariable3 myRecordPart;

These are only the most common types of data part. For the others, see “Other
data parts” on page 102.
Related concepts
“Contents of an EGL application” on page 67
This topic describes the artifacts found in a typical EGL application.
“Other data parts” on page 102
These data parts are not used as often as the others.
“Commonly used primitives”
This topic lists and describes the primitives that you are most likely to use.
“Introduction to Record parts” on page 100
Record parts are collections of other data parts. The data parts within the
Record part are referred to as fields. A Record part can contain any number of
fields, and the fields can be primitives, data items, or other records.
Related reference
Primitive data types
DataItem part
Record part

Commonly used primitives


This topic lists and describes the primitives that you are most likely to use.

Not all primitives are listed here; for the complete list, see ″Primitive data types″ in
the EGL Language Reference.

Primitive numeric types: The following numeric primitives are the most often
used:
INT
This is a basic four-byte integer, the workhorse of internal calculations, used
also for key numbers, stock quantities, or anywhere else that a whole number
is appropriate. The range of values you can put in an INT is -2,147,483,648 to
+2,147,483,647.
DECIMAL
Use decimals for any numbers that need a decimal point—currency amounts,
for example, or employee hours (if you allow fractions). When you declare a

98 EGL Programmer’s Guide


variable of this type, specify the length (in digits, not bytes) and the number of
decimal places. If you know that a variable will never need to hold a value as
large as ten million dollars, you could declare it as follows:
mySalary DECIMAL(9,2) = 30000.00;
FLOAT
Variables of this type are 8 bytes in length (or double-precision, as opposed to
single-precision floating point numbers, which are only 4 bytes long). A
FLOAT variable stores a number that uses exponents, so it can hold extremely
large numbers in those 8 bytes. Very high numbers are the only values that
you typically store in FLOAT variables. You can assign the value through
ordinary decimal notation, or, because values of FLOAT variables can get so
large, through exponential notation, where e indicates a power of ten:
speedOfLight FLOAT = 299800000;
speedOfLight FLOAT = 2.998e8;

Here 2.998e8 means 2.998 x 108.

Primitive character types: The most common character primitives are STRING
and CHAR.
STRING
A STRING variable holds a group of characters such as a name or an address.
EGL automatically makes all strings Unicode, which means that each character
is two bytes long and can handle any international language that the Unicode
standard can render. STRING variables, by default, are variable in length. The
length of a STRING at any given moment is the length of the data that it
holds, and that length can change at run time. For some uses you might want
to limit the size of the STRING variable. To limit the length of the STRING
variable, specify a maximum number of characters (not bytes) at declaration
time, as in the following example:
myUSState STRING(2) = "TX";

Note that when you assign a STRING value, you place it inside double quotes.
CHAR
A CHAR primitive is also available, mostly to provide compatibility with older
programs and data. A variable declared as CHAR(4) would hold four bytes of
character data.

Primitive date and time types: To store dates and times, you typically use the
following types:
DATE
A DATE variable stores month, day, and year in Gregorian format, using eight
bytes.
TIME
A TIME variable stores hours, minutes, and seconds in six bytes.
TIMESTAMP
A TIMESTAMP variable holds both date and time, and has a maximum of 20
digits.

For variables based on any of these date and time types, you can specify formats
for input and output. See ″Date, time, and timestamp format specifiers″ in the EGL
Language Reference for more information.

Contents of an EGL application 99


Primitive large object types: Large object types store unformatted data. EGL
simply passes them through without changing them—generally capturing them
and storing them in a database, or retrieving them from a database and
transferring them off to a program that can display them. The two types of
large-object primitives follow:
BLOB
BLOB is short for binary large object. BLOB variables are most commonly used
to store visual data, such as JPGs and movies. For example, a Web site that
sells movies might store short previews as BLOBs in a database, and serve
them to customers on request.
CLOB
Similarly, CLOB is a large object that contains character data. For example, a
company might use a database to archive emails as CLOBs.
Related concepts
“Introduction to data parts” on page 97
Data parts define a structure that stores one or more pieces of data. Data parts
form the basis for a variable that you can use in a logic part.
“Contents of an EGL application” on page 67
This topic describes the artifacts found in a typical EGL application.
Related reference
Primitive data types
Date/time masks and format specifiers

Introduction to Record parts


Record parts are collections of other data parts. The data parts within the Record
part are referred to as fields. A Record part can contain any number of fields, and
the fields can be primitives, data items, or other records.

At the simplest level, a Record part is a group of other data parts. In this example,
three different primitives are grouped into a single Record part:
Record primitiveRec type BasicRecord
integerField int;
stringField string;
charField char(30);
end

Creating a variable based on this Record part is similar to creating a variable based
on a DataItem part or primitive:
myRecVar primitiveRec;

The record variable itself does not contain a value, but the fields within the record
do contain values. After you have a variable based on a Record part, you can
access the fields within the record as though they were individual variables:
myRecVar.integerField = 6;
myRecVar.stringField = "Hello";
myRecVar.charField = "Character field";

However, the record still behaves as a single unit, so you can pass it to functions
as a single parameter, for example:
myFunction(myRecVar);

100 EGL Programmer’s Guide


Record stereotypes

Like most other parts, Record parts can be specialized for specific purposes with a
stereotype. You set the stereotype for a Record part with the type keyword, as in
this example of a Record part with the stereotype BasicRecord:
Record myCustomerRecord type BasicRecord
customerNumber int;
customerFirstName string;
customerLastName string;
customerBalance float;
end

The BasicRecord stereotype denotes a general-purpose Record part. You can use
this stereotype any time that you want to group one or more variables together for
simplicity.

Because Record parts are most often used to represent records or other groups of
related data in a data source, the other stereotypes that you can apply make the
Record parts specialized for use with a particular kind of data source. For example,
the SQLRecord stereotype makes the Record part specialized for use with a SQL
database. When creating a Record part of this type, use properties to link the
record and its fields to the database table and its columns:
Record myCustomerRecordSQL type SQLRecord
{ tableNames = [["Customer"]], keyItems = [customerNumber] }
customerNumber int {column = "CustomerID"};
customerFirstName string {column = "FirstName"};
customerLastName string {column = "LastName"};
end

In this case, the record is linked to a database table named Customer that has
columns named CustomerID, FirstName, and LastName. When you link a record to a
database table like this, EGL can use this information to access the database based
on your interactions with the record. In simple terms, you can use the record as
though it were the row in the database.

For example, the following code uses the Record part defined in the previous
example to retrieve a specific row from the database:
myRecordVar myCustomerRecordSQL;
myRecordVar.customerNumber = 5;
get myRecordVar;
SysLib.writeStderr("Name: " +
myRecordVar.customerFirstName + " " +
myRecordVar.customerLastName);

Other stereotypes that can be added to Record parts include IndexedRecord,


SerialRecord, RelativeRecord, and CSVRecord, which are used for accessing
different types of files.

Structured records

Record parts can be structured to provide more detail about the layout and
organization of their fields. In a structured record, each field is assigned a level
number, an arbitrary number that indicates that field’s relationship to other fields.

The fields in unstructured records do not have level numbers, so each field is
considered to be at the same level. Structured records can also behave this way,
with each field at the same level number:

Contents of an EGL application 101


record structRec1 type BasicRecord
10 field1 int;
10 field2 int;
10 field3 int;
end

Varying the level numbers creates substructures within the record:


Record CustomerRecord type BasicRecord
10 phoneNumber CHAR(10);
20 areaCode CHAR(3);
20 localNumber CHAR(7);
end

In this case, the fields areaCode and localNumber are subfields of the field
phoneNumber. You can access the phoneNumber field to get the entire value of the
field, or you can access the areaCode or localNumber fields to get a portion of the
value held in the phoneNumber field.

Structured records are limited to fields with fixed length. See ″Records″ in the EGL
Language Reference for more information on the limitations and uses of structured
records.
Related concepts
“Introduction to data parts” on page 97
Data parts define a structure that stores one or more pieces of data. Data parts
form the basis for a variable that you can use in a logic part.

Other data parts


These data parts are not used as often as the others.
FormGroup
A form part, like a record, contains fields; like a record, each generally
represents data from a single line of a database table. The difference is that
a record provides a blueprint for storage inside a program, and a form
provides a blueprint for displaying that information—either on a printer
(print form) or on a 3270 screen or console window (text form). A
FormGroup organizes a number of form prototypes for a particular
program or for related programs.
DataTable
A DataTable part provides a collection of data in tabular form that you can
make available throughout an application. Unlike other data parts, you
declare each DataTable part in its own EGL source file because DataTables
are generatable parts. For more information, see ″DataTable″ in the EGL
Language Reference.
Dictionary
A dictionary is like a record in that it contains fields to which you can
assign values. Unlike a record, it is not associated with a database and you
can add new fields (also called name/value pairs) while your program is
running. As with a record, you create a dictionary type variable to reserve
storage. The amount of storage the dictionary uses will change depending
on the information that you put in it. For more information, see
″Dictionary″ in the EGL Language Reference.
ArrayDictionary
A variable that is based on an ArrayDictionary part enables you to access a
series of arrays by retrieving the same-numbered element of every array. A

102 EGL Programmer’s Guide


set of elements that is retrieved in this way is itself a dictionary, with each
array name treated as a key that is paired with the value in the array
element.
Related concepts
“Introduction to data parts” on page 97
Data parts define a structure that stores one or more pieces of data. Data parts
form the basis for a variable that you can use in a logic part.
“Arrays of data parts”
Like many other programming languages, EGL can group variables of the same
type into arrays. This topic covers the basics of using arrays in EGL.
Related reference
Primitive data types
FormGroup part
Dictionary part
Dictionary parts contain lists of data that you can access via a key. For example,
you can create a message handling facility that uses a library and a dictionary
populated with keys and messages read from a database.
DataTable part
ArrayDictionary

Arrays of data parts


Like many other programming languages, EGL can group variables of the same
type into arrays. This topic covers the basics of using arrays in EGL.

An array is an ordered series of variables of the same type. For example, you can
define an array of integer variables:
myInts int[] = [1,2,3,4,5];

In this case, the array is a series of five integer variables. In EGL, arrays begin
numbering with the number one, so this array has elements numbered one
through five.

You can access each of the integers in the array as though they were individual
variables by specifying the index number of the integer in brackets:
myInts[1] = 5+5;
myInts[2] = 16;
myInts[3] = myInts[1] + myInts[2];

You can also assign values to the array more than one at a time using one of these
two methods:
v You can use a set-value block:
myStrings string[2];
myStrings {"Hello", "Goodbye"};
Note that this syntax uses braces ({) and no equals sign (=). This is not an
assignment statement but a method of assigning values to the array as though
the elements were its properties. This method offers better performance at run
time than the other method, which entails an array literal to the array.
Also, this method works only when the array has sufficient elements to accept
the new values in braces; EGL does not automatically add more elements. For
this reason, you must specify a starting length for the array or otherwise add
elements to it before you can assign values to elements with a set-value block.
v You can assign an array literal to the array:

Contents of an EGL application 103


myBigInts bigint[];
myBigInts = [10,40];

This method is a little slower than the set-value method because the generated
code must create two arrays: one for the variable and one for the literal.
You can also use either of these two methods to assign values to the array when
you create it:
myStringsInit string[] {"Hello", "Goodbye"};
myBigIntsInit bigint[] = [10, 40];

If you want to assign properties to the array as well as specifying starting values
in the set-value block, put the property name-value pairs after the starting values:
myDecimals decimal(10,2)[3] {55.43, 22.12, 4.34, CurrencySymbol = "$"};

If you are using the array literal method of specifying starting values, you can set
properties with the set-value block as usual:
myBools boolean[3]{MaxSize = 5} = [true, false, true];

If you specify a number of elements in the array when you create it, that array is
initialized to contain that number of elements. Each element has the default value
for its type:
fiveInts int[5];
SysLib.writeStderr(fiveInts[1]); //Writes "0"

It’s good coding practice to specify a starting length for the array when you create
it so that EGL can initialize it. You can always add or remove elements later with
array functions such as appendElement and removeElement.

However, if you do not specify a starting length for the array, it starts as null, so
there is nothing in the array to be accessed:
nullArray int[];
nullArray[2] = 5; //NullValueException!
nullArray.appendElement(5); //NullValueException!
nullArray {1,2,3}; //NullValueException!

Instead, you must begin by initializing the array with an array literal:
nullArray2 int[];
nullArray2 = [1,2,3];
nullArray2.appendElement(4);

Alternatively, you can use a set-value block to initialize a null array:


emptyArray int[]{};
emptyArray.appendElement(5);

In the previous example, the set-value block is empty. You cannot use a set-value
block to assign more elements to an array than currently exist in the array. This
array has zero elements, so you must use a set-value block with zero values.

You can increase the length of an array by assigning a longer array literal to it. In
this case, you overwrite the shorter array with a new, longer array. The following
example assigns an array literal with 5 elements to replace an array with only two
elements:
smallIntArray int[2];
smallIntArray = [1,2,3,4,5];

104 EGL Programmer’s Guide


However, you cannot use a set-value block to assign more elements to the array
than currently exist in the array:
smallStrArray string[2];
smallStrArray {"ab", "cd", "ef", "gh"};
//IndexOutOfBoundsException! Array has only 2 elements!

For more details on arrays, see ″Arrays″ in the EGL Language Reference.
Related concepts
“Introduction to data parts” on page 97
Data parts define a structure that stores one or more pieces of data. Data parts
form the basis for a variable that you can use in a logic part.
Related reference
Arrays
The rules for an EGL array depend on the type of the array.

Introduction to logic parts


Logic parts define a sequence of instructions. Most logic parts contain one or more
functions, which are the basic unit of logic.

A function can receive parameters, execute EGL statements, and return a value to
the function that called it. Following is a simple example of a function:
Function addIntegers(int1 int in, int2 int in) returns (int)
sum int = int1 + int2;
return (sum);
end

For more details, see Functions.

A function is not technically a logic part, although it is possible for a function to


exist outside of a logic part and thus behave like a logic part. See Standalone
function part.
Program
A program is the simplest kind of logic part. A program in EGL behaves
similarly to programs in many other programming languages. An EGL
program must contain a function named main, which is the function that is
invoked when the program runs. The program can contain any number of
other functions. The following example shows a simple program part:
package programs;

program multiplicationTable type BasicProgram

stopNumber int = 7;

function main()
SysLib.writeStderr("Printing multiplication table through "
:: stopNumber);
i, j int;

for (i from 1 to stopNumber by 1)


for (j from 1 to stopNumber by 1)
printProduct(i, j);
end
end

SysLib.writeStderr("Finished.");
end

function printProduct(int1 int in, int2 int in)

Contents of an EGL application 105


SysLib.writeStderr(int1 :: "x" :: int2 ::
"=" :: int1*int2);
end

end
Library
A library part is a collection of functions and variables that are made
available locally to other logic parts. Functions in a library part can be
invoked in any order, while the main function in a program always runs
first. The following example shows a simple library part:
package libraries;

library myMathLibrary type BasicLibrary

function addIntegers(int1 int in, int2 int in)


returns (int)
return (int1+int2);
end

function subtractIntegers(int1 int in, int2 int in)


returns (int)
return (int1-int2);
end

end
Handler
A Handler part is specialized to control a particular kind of user interface.
BasicHandler
BasicHandler parts are the simplest kind of Handler. Generally,
you will use a Handler that is specialized for a type of interface.
JSFHandler
JSF Handler parts control Web pages. See “Elements of a JSF Web
application” on page 389.
JasperReport
Jasper Report Handler parts control reports that are created by
EGL within the Jasper Reports framework. See “Elements of an
EGL JasperReport application” on page 533.
Service
Like a library part, a service part is a collection of functions, but unlike a
library part, the service part is designed to enable applications outside the
current run unit to use the functions. See “Elements of a service-oriented
application” on page 478 for more information and examples.
Interface
An interface part is different from most logic parts because instead of
containing functions or any executable code, it contains function
prototypes. Instead of defining actual logic, as the other types of logic part
do, an interface part merely describes another logic part, usually a service
part. In EGL, you can use interfaces to plan services or to represent
services that your application will use. See “Elements of a service-oriented
application” on page 478 for more information and examples.
ExternalType
With an ExternalType part, you can create variables in EGL that refer to
elements in another language. Generally, ExternalType parts are used to
represent Java objects. An ExternalType part contains function prototypes
that allow you to invoke the logic in the Java object. Also, an ExternalType

106 EGL Programmer’s Guide


part can contain variables that represent public variables in the Java object.
See “Calling Java” on page 128 for an example.
Related concepts
“Contents of an EGL application” on page 67
This topic describes the artifacts found in a typical EGL application.
Related reference
Program part
Functions
Library part
Library parts support the sharing of functions and variables.
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.
Interface part
Interface parts provide access to a remote service, such as a Web service.
Handler part
ExternalType part
ExternalType parts map EGL to external language elements.

Introduction to functions
Functions are the fundamental units in EGL logic parts.

A function contains a series of EGL statements. Except for standalone functions,


functions are not EGL parts (see Standalone function part). Functions either contain
the first executable code in the program or are called from another function.

Functions can include the following elements:


v A set of parameters, enclosed in parentheses. Each set of parameters corresponds
to an argument that passes when the function is called by another function. A
pair of parentheses must follow the function name, even if the function has no
parameters.
v A return type, which describes the type of data that the function returns to the
calling function. The return type must be compatible with the data type of the
receiving variable, as described in ″return.″ If the function does not have a
return type, it cannot return data and you cannot use the function in an
expression where the function must have a value. In a service, a return type
cannot be an ANY, BLOB, or CLOB type.
v A set of local variables, each of which has meaning within the function only. For
more about local variables, see Scope.
v EGL statements.
v An end delimiter.

The name main() is reserved for the top-level function that runs first when you
start or call a program. Every program part must contain a function named main()
that has no parameters or return type.

For information about function syntax, see Functions in the EGL Language Reference.

Parameter modifiers

Parameters correspond to the arguments that are passed to a function. When you
declare a function, you can specify parameters. Parameters correspond in number,

Contents of an EGL application 107


type, and position to the arguments that you pass to a function. Reference
parameters point to a location where a value is stored. Value parameters contain
the value. See Reference variables. For example, an array is always a reference
variable.

When you declare parameters, you must specify a parameter modifier:


in Use this modifier if the parameter is used as input to the function. When
you specify in, the function receives the argument value as input, but the
calling function does not receive changes that are made to the parameter.
You cannot specify the in modifier for a record that is used to access a file
or database in either the current function or in a function called by the
current function.
When you specify a limited-length string as a function parameter whose
modifier is in, any text input is valid:
v If the argument contains more characters than are valid in the parameter,
EGL truncates the copied content to fit the available length.
v If the argument contains fewer characters than are valid in the
parameter, EGL pads the copied content with blanks to meet the
specified length.
If the argument is a reference type, a copy passes to the corresponding
function parameter. Any value you assign to the parameter does not affect
the value that the reference points to. However, if you change an element
of an array without changing the original value of the parameter, the
calling program will detect the change. This is because the parameter still
points to the same area of memory that the original argument points to.
out Use this modifier if the parameter is used as output from the function. The
function does not receive the argument value as an input; the parameter is
initialized according to the rules described in Data initialization. When the
function returns, a value is assigned to the argument of the calling
program.
If the argument is a literal or constant, the parameter is treated as if the
modifier is in. You cannot specify the out modifier for a record that is used
to access a file or database in either the current function or in a function
invoked by the current function.
When you specify a limited-length string as a function parameter whose
modifier is out, the length limit must be the same in the parameter and the
argument.
If the argument is a reference type, a null reference passes to the
corresponding function parameter. Any value you assign to the parameter
updates the corresponding variable in the calling function.
inOut Use this modifier if the parameter is used as both input to and output
from the function. The function receives the argument value as input, and
the calling function receives all changes to the parameter when the
function ends. If the argument is a literal or constant, it is treated as if the
modifier is in.
If the argument is a record, the following rules apply:
v If you intend to use the record to access a file or database in the current
function or in a function called by the current function, you must specify
the inOut modifier or accept that modifier by default.

108 EGL Programmer’s Guide


v If the type of record is the same for the parameter and the argument (for
example, if both are serial records), the record-specific state information
such as endOfFile status is available in the function and is returned to
the caller, but only if the inOut modifier is in effect.
If the argument is a reference type, it passes to the corresponding function
parameter as a reference. Any value you assign to the parameter updates
the corresponding variable in the calling program.
sqlNullable
This modifier is available to relational database users. For more
information, see sqlNullable.

You can use a question mark to indicate that a parameter is nullable, as in the
following example:
function getCustomerBalance (custNo INT? inOut) returns (DECIMAL(7,2))
...
end

Return type

The return type describes the data that the invoked function returns to the invoker.
The return type must be compatible with the data type of the receiving variable, as
described in return.

In a service, the return type cannot be an ANY, BLOB, or CLOB type.

Overloaded functions

An overloaded function has multiple function signatures for one function name. The
signature of a function is the combination of the name of the function with the
number and type of its parameters. The return value of the function is not part of
its signature. When multiple functions have the same name, EGL uses the
signature to match function code to a function call. EGL does not permit two
functions to have the same signature.

Many EGL system functions are overloaded. For example, you can call the
sysLib.audit() function with one parameter or two. The second parameter specifies
a journal ID. If you call the function with a single parameter, the function writes to
the system journal. The two functions have the following signatures:
sysLib.audit(record BasicRecord in)
sysLib.audit(record BasicRecord in, jid SMALLINT in)

In another example, the mathLib.abs() function accepts a range of numeric types,


and returns a value of the same type as the input. This requires a different
signature for each numeric type:
mathLib.abs(inputVar SMALLINT)
mathLib.abs(inputVar INT)
mathLib.abs(inputVar BIGINT)

You can create overloaded functions in the following circumstances:


v The function cannot be a standalone function.
v The overloaded functions must be in the same part. If two parts contain
functions with the same name, even if the functions have different signatures,
you cannot use an unqualified reference to that function name.
v Because the function signature does not include the return value, you cannot
have two functions that are identical except for the return value.
Contents of an EGL application 109
During the generation process, EGL uses the following rules to resolve references
to unqualified function names:
1. EGL searches in the current scope for all functions with matching names.
2. If EGL finds matching function names in more than one container (logical part),
the generator displays an ambiguous reference error.
3. If more than one function matches the number of parameters, EGL continues to
step 4. If no function matches, the generator displays an invalid arguments
error.
4. EGL searches for a function with parameters that match the types of the
arguments in the function call. If no match is found, EGL continues to step 5.
EGL cannot find multiple matching functions, because that causes a validation
error.
5. EGL searches for a function with parameters that are assignment-compatible
with the arguments in the function call. If no match is found, the generator
displays an invalid arguments error. If multiple matches are found, EGL
searches for the best match. For example, if the argument is a SMALLINT and
EGL finds two functions, one with an INT parameter and the other with a
BIGINT parameter, EGL will pick the function with the INT parameter, because
an INT is closer in size to SMALLINT. If EGL cannot find such a match, the
generator displays an ambiguous reference error.
Related concept
“Introduction to logic parts” on page 105
Logic parts define a sequence of instructions. Most logic parts contain one or
more functions, which are the basic unit of logic.
Related reference
Standalone function part
Functions
Scope
Reference variables
Data initialization
return
sqlNullable

Introduction to Library parts


Library parts support the sharing of functions and variables.

A Library part is a generatable logic part with multiple entry points. You can
access a Library part by direct calls to the shared Library functions or by direct
references to the shared Library variables.

EGL provides many system Libraries that contain common functions. You can also
create your own Libraries of functions that you use frequently. The program uses
stereotypes to specialize code for functions. The following stereotypes are available
as part of the core EGL package:
BasicLibrary
Contains EGL-written functions and values for runtime use in other EGL
logic parts. This is the most common type of Library. For more
information, see “BasicLibrary stereotype” on page 111.
NativeLibrary
Enables code migrated from Informix 4GL to invoke a single, locally
running DLL (dynamic link library, also sometimes called a driver). Most

110 EGL Programmer’s Guide


developers never use the NativeLibrary stereotype. For more information,
see “NativeLibrary stereotype” on page 112.

Many properties that determine the behavior of your generated code are available
to Libraries. The properties that are available depend on the stereotype of the
Library. See Library properties and NativeLibrary properties.

An EGL Library is generated separately from the parts that use it. At run time,
EGL loads the Library the first time you use it, and unloads it when the run unit
ends. If a Library invokes another Library, the invoked Library remains in memory
as long as the invoking Library does.
Related concepts
“Introduction to logic parts” on page 105
Logic parts define a sequence of instructions. Most logic parts contain one or
more functions, which are the basic unit of logic.
“BasicLibrary stereotype”
The BasicLibrary stereotype identifies a Library part that contains EGL-written
functions and values for runtime use in other EGL logic parts.
“NativeLibrary stereotype” on page 112
Customers migrating from Informix 4GL need the NativeLibrary stereotype to
hold their C language subroutines.
Related reference
Library properties
NativeLibrary properties
The NativeLibrary stereotype provides additional properties to the standard set
of Library properties.

BasicLibrary stereotype:

The BasicLibrary stereotype identifies a Library part that contains EGL-written


functions and values for runtime use in other EGL logic parts.

The following rules apply to a BasicLibrary:


v Any generatable logic part (Program, Service, Handler, or another Library) can
reference the functions, variables, and constants of a Library without specifying
the Library name if that logic part includes the Library in a use statement.
v Library functions cannot include the following statements:
– converse
– display
– forward
– show
– transfer
v You can use the private modifier on a function, variable, or constant declaration
to keep the element from being used outside of the Library. You might do this
when the element is used only by a function within the Library.
v Public Library functions (the default) are available outside of the Library and
cannot have loose type parameters. A loose type is a special case of primitive
type that is available only if you want the parameter to accept a range of
argument lengths. For more information, see Loose types.

The following example shows a BasicLibrary part:

Contents of an EGL application 111


package com.companyb.customer;

Record CustomerRecord type SQLRecord


customerNumber CHAR(6);
customerName CHAR(25);
customerBalance BIN(9,2);
end

Library CustomerLibrary type BasicLibrary

// Function Declarations
function getCustomerName(
myCustomerNumber CHAR(6) in,
myCustomerName CHAR(25) inOut)

myCustomer CustomerRecord;
myCustomer.customerNumber = myCustomerNumber;
get myCustomer;
myCustomerName = myCustomer.customerName;
end

end
Related concept
“Introduction to Library parts” on page 110
Library parts support the sharing of functions and variables.
Related reference
Library properties
Loose types

NativeLibrary stereotype:

Customers migrating from Informix 4GL need the NativeLibrary stereotype to


hold their C language subroutines.

This type of Library enables your EGL-generated Java code to invoke a single,
locally running DLL written in the C language. The purpose of each function in
this Library type is to provide an interface to a DLL function. You cannot define
statements in the EGL function, and you cannot declare variables or constants
anywhere in the Library.

The following example shows a NativeLibrary part:


Library myNativeLibrary type NativeLibrary
{callingConvention=CallingConventionKind.I4GL, dllname="mydll"}

Function entryPoint1( p1 INT sqlNullable in,


p2 DATE in, p3 TIME in,
p4 INTERVAL in, p5 ANY out)
end

Function entryPoint2( p1 FLOAT in,


p2 STRING in,
p3 SMALLINT out)
end

Function entryPoint3( p1 ANY in,


p2 ANY in,
p3 ANY out,
p4 CLOB inOut)
end
end

112 EGL Programmer’s Guide


For information on properties associated specifically with this stereotype, see
NativeLibrary properties.
Related concepts
“Introduction to Library parts” on page 110
Library parts support the sharing of functions and variables.
“BasicLibrary stereotype” on page 111
The BasicLibrary stereotype identifies a Library part that contains EGL-written
functions and values for runtime use in other EGL logic parts.
Related reference
NativeLibrary properties
The NativeLibrary stereotype provides additional properties to the standard set
of Library properties.

RUIPropertiesLibrary stereotype:

When you are writing a Rich UI application, set up an Rich UI properties library
(stereotype RUIPropertiesLibrary) if you want to retrieve displayable text from
external files rather than hard-coding the text.

For details on this stereotype, see the following files in the EGL Language
Reference:
v Use of properties files for displayable text
v RUIPropertiesLibrary stereotype
Related concepts
Use of properties files for displayable text
RUIPropertiesLibrary stereotype
“Introduction to Library parts” on page 110
Library parts support the sharing of functions and variables.

Introduction to Service parts


Service parts provide requesters with access to the functions in the service.

A requester is a program or other code that accesses the functions that are defined
in a service. The requester can be a program, handler, library, or another service,
and can be local or remote.

When you want to consume a service, you create an Interface part. The interface
provides EGL with a list of the functions that the service provides. To handle the
connectivity, use the EGL deployment descriptor file. The deployment descriptor
file describes how other applications can use a Service part from your application,
or how your application uses an external service. For more information about
Interface parts, see “Introduction to Interface parts” on page 114. For details about
the deployment descriptor file, refer to the EGL Generation Guide.

Service function calls

You can call a function from a service much as you would call a function from a
library, but you must first declare a variable based on the service:
myEcho EchoString;
result STRING;

result = myEcho.returnString("Hello!");

There are restrictions on passing reference variables to remote service functions.

Contents of an EGL application 113


Related concepts
“Introduction to Interface parts”
Interface parts provide access to a remote service, such as a Web service.
Related tasks
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.
“Creating an Interface part from a Service or ExternalType part” on page 116
You can use other parts as a models for an Interface part.
“Creating a service to call a program”
If you have a called program in your project, you can create a Service part to
call that program.
“Creating a WSDL file from a Service part” on page 119
You can create a sample WSDL file as a point of reference to a Service part.
Related reference
Interface part
Interface parts provide access to a remote service, such as a Web service.
Service properties
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.

Creating a service to call a program


If you have a called program in your project, you can create a Service part to call
that program.

You might want to create a service in this way to act as a wrapper for the called
program. In this context, a wrapper refers to a logic part that has no meaningful
logic in itself but exists only to provide other applications access to another logic
part.
1. In the Project Explorer view, right-click a file containing an EGL called program
part and then click EGL Services → Create Program Call Function. The New
EGL Service Part window opens.
2. Enter the location and file name information for the Service part as in “Creating
EGL source files” on page 90.
If you type the name of an existing Service part and then select the Update
existing files check box, EGL adds a function to the existing Service part that
calls the called program. If you type a name for a new Service part, EGL
creates the new part and adds a function that calls the called program.
3. Click Finish.
Related concepts
“Overview of service-oriented architecture (SOA)” on page 475
Accessing IBM i programs as Web services
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.
Related reference
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.

Introduction to Interface parts


Interface parts provide access to a remote service, such as a Web service.

114 EGL Programmer’s Guide


You can also use an Interface part to access a local service in situations where you
want to restrict access to the source code. For example, you might ship services as
generated Java classes with EGL Interface parts so that the customer can invoke
the services from EGL programs. For information on Interface part syntax, see
Interface part.

The Interface part includes a set of function prototypes (see Function prototypes).
Each prototype has an ending semicolon (;) and includes only a function name,
parameter list, and return type:
Interface StockQuote
Function getQuote(symbol String in) returns (float);
end

You cannot use an Interface part directly in your code; you must create a variable
that is based on the part. At run time, the variable refers to a service that you are
running from a specific location (URI).

When you access a service through an interface, the interface must be bound to the
location of the service implementation with a deployment descriptor file. The
deployment descriptor file describes how other applications can use a Service part
from your application, and how your application uses an external service. For
more information, see the EGL Generation Guide.

Uses of interface parts


v Designing the services of an organization.
You can create an interface that describes the functionality that you want to have
coded in an EGL service. After the interface is complete, you can code the
service that implements the interface. The service must contain a function that
matches each prototype in the interface. The interface is like a contract that the
service fulfills.
Benefits of using interface parts to design services:
– People in your organization can use an interface to decide which operations a
service needs before service development begins.
– Developers can use interfaces to begin coding client applications while the
service code is under development.
A service can implement multiple interfaces, and multiple services can
implement the same interface.
v Providing access to the services of an organization while keeping the details
of service implementation confidential.
The runtime effect of declaring a variable based on an Interface part is the same
as the effect of declaring a variable based on the related Service part; but when
you use an Interface part, you can avoid disclosing the logic inside the service.
You might want to keep logic confidential for two reasons:
– To hide the source code from developers outside of your organization.
– To encourage developers to focus on the functionality that the service
provides rather than on the details of the implementation.
v Providing access to Web services regardless of the language or location of the
service implementation.
To access a Web service that is created outside of your organization, you must
have the service-specific Web Service Description Language (WSDL) definition,
which details how to access the service.

Contents of an EGL application 115


You use the WSDL definition as input to create an external service using the
service module editor. The editor creates a service-specific Interface part through
which you can access the service in your code.
Related concepts
“Introduction to Service parts” on page 113
Service parts provide requesters with access to the functions in the service.
Related tasks
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.
“Creating an Interface part from a Service or ExternalType part”
You can use other parts as a models for an Interface part.
Related reference
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.
Interface part
Interface parts provide access to a remote service, such as a Web service.
Function prototypes
Interface properties
Interface part
Interface parts provide access to a remote service, such as a Web service.

Creating an Interface part from a Service or ExternalType part:

You can use other parts as a models for an Interface part.

To create an Interface part from a Service or ExternalType part, follow these steps:
1. In the Project Explorer view, right-click an EGL source file that includes an EGL
Service or ExternalType part and then click EGL Services → Extract EGL
Interface. The New EGL Interface Part window opens.
2. In the Source folder field, select a source folder to hold the new file.
3. In the Package field, select a package to hold the new file.
4. In the EGL source file name field, type a name for the new file that will
contain the new Interface part. By convention, files that contain interface parts
begin with a capital letter I.
5. In the Functions field, select the functions (or function prototypes in the case of
an ExternalType) that you want to include in the new Interface part. Only the
functions not marked as private are shown in this list. In the case of an
ExternalType part, EGL might show multiple Interfaces on separate tabs. You
can change the suggested name for any of these Interfaces.
You can use the Select All and Deselect All buttons to select or deselect the
functions.
6. If you want to overwrite an EGL source file, select the Overwrite existing files
check box.
7. Click Finish.
Related concepts
“Overview of service-oriented architecture (SOA)” on page 475
Related tasks
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.

116 EGL Programmer’s Guide


Related reference
ExternalType part
ExternalType parts map EGL to external language elements.
Function prototypes
Interface part
Interface parts provide access to a remote service, such as a Web service.

Delegate part
A Delegate part provides a model for a function.

A Delegate part is similar to a function pointer in COBOL or C. When you declare


a variable, you specify the Delegate part name as a type, the way you specify a
Record part name when you declare a record variable. The variable is initialized,
or assigned the name of a matching function with the same signature (parameter
and return type definition) as the Delegate part. You can specify a delegate
variable in the place of the function name on a function invocation. Then you can
choose the actual function to be called dynamically.

The most common use for Delegate parts is as an infrastructure to register event
handlers. For more information, see External type for Java code. Nothing in EGL
generates events, though some associated UI technologies do. Still, the
event-driven architecture is an increasingly common model for programming, and
you can use Delegate parts in situations that do not involve user interfaces,
including the following:
v As elements in a Dictionary of function pointers.
v As a way to dynamically invoke functions.

The Delegate part does not have properties. For more information about the
Delegate part, see Delegate part.
Related concepts
“Introduction to logic parts” on page 105
Logic parts define a sequence of instructions. Most logic parts contain one or
more functions, which are the basic unit of logic.
Related reference
External type for Java code
Logic parts
Delegate part
Delegate parts provide models for functions.

Introduction to ExternalType parts


ExternalType parts map EGL to external language elements.

This mapping is similar to the mapping that an Interface part provides for Service
functions, but mapping EGL to external language elements is generalized to
include fields and constructors. The only external element that ExternalType part
supports is the Java object.

An ExternalType part consists of the following components:


Variable declarations
These provide access to public variables in the external language element.
Function prototypes
These represent method invocations or function calls in the external type.

Contents of an EGL application 117


Constructor prototypes
These define the syntax for constructing a variable of this external type
using an EGL new statement.

The concept of the ExternalType is similar to that of a Library or a Service. In each


of these cases, you use external functionality within your program. In the case of
the Service or the ExternalType, where EGL does not have direct access to the
code, you must provide certain prototypes so that EGL can perform the necessary
type checking.

An ExternalType definition reserves no storage. You must declare a variable that is


based on the part, optionally using the EGL new statement, to use its variables and
functions (unless they are declared to be static; see ″Syntax″ in this topic).

A number of the concepts used with the ExternalType part come from
object-oriented languages, such as Java and C#. These concepts include extension,
inheritance, and constructors. If you are unfamiliar with these terms, refer to a
basic Java reference.

One of the main uses for an ExternalType part is to create arrays of function
pointers for event handling. EGL text reports use ExternalTypes in this way; see
EGL text reports.

The ExternalType part can have any of three stereotypes:


v JavaObject, for Java code; for details, see External type for Java code
v JavaScriptObject, for JavaScript code; for details, see External type for JavaScript
code
v HostProgram, for host programs on IBM i; for details, see Accessing IBM i
programs as Web services

ExternalType functions

If the function is marked static, invoke it using the name of the ExternalType part
and dot syntax (typeName.methodName()). Otherwise, create a variable that is based
on the ExternalType and append the variable name to the name of the method by
using dot syntax (externalTypeVariable.methodName()). For more information, see
Example.

Serializable ExternalType

If you are mapping an ExternalType part to a Java class that implements the
java.io.Serializable interface, the ExternalType part must extend the predefined
Serializable ExternalType:
ExternalType CustomDate extends Serializable type JavaObject
{
packageName="com.mycompany",
javaName="CustomDate"
}

// functions

end

Serializable ExternalType variables can be saved directly to disk and restored later,
if the associated Java class implements the java.io.Serializable interface.
ExternalTypes that do not extend the Serializable ExternalType are assumed to be

118 EGL Programmer’s Guide


Transient, or unable to be saved directly to disk. If you want to save the
information in a non-Serializable ExternalType, you must use a data source.

The following code shows the Serializable ExternalType:


ExternalType Serializable type JavaObject
{
JavaName = "Serializable",
PackageName = "java.io"
}
end
Related tasks
Accessing IBM i programs as Web services
Related reference
ExternalType part
ExternalType parts map EGL to external language elements.
External type for Java code
External type for JavaScript code
Function prototypes
EGL text reports
EGL text reports offer a simplified alternative to more complex reporting tools.

Creating a WSDL file from a Service part


You can create a sample WSDL file as a point of reference to a Service part.

This method is provided mainly for compatibility and to preview the WSDL file
that will be created when you deploy your service. If you want to expose a Web
service to other applications through a WSDL file, add Web service binding
information to an EGL deployment descriptor file and then generate the project to
create a WSDL file. See “Exposing a service to other applications” on page 493.
1. In the Project Explorer view, right-click the file that contains the Service part
and then click EGL Services → Generate WSDL File. The Create WSDL file
window opens.
2. Fill out the Project Source, Folder, and WSDL file name fields with the
location and name of the new WSDL file.
3. Under Advanced, provide the deployment information to be added to the
WSDL file.
4. Click Finish.

The new WSDL file is created in the location that you specified. This file is not
updated automatically, so if the service information changes, you must recreate or
edit the WSDL file.
Related tasks
“Exposing a service to other applications” on page 493
Your EGL application can act as a service by exposing its functions to other
applications.
“Adding Web service deployment information to the deployment descriptor”
on page 496
After you have coded a service part that you want to expose as a Web service,
you must add information to the deployment descriptor that tells EGL to
generate the necessary Web service wrapper.

Contents of an EGL application 119


Introduction to build parts
Build parts control the generation process and set how an application will behave
at run time. The kinds of build part you need vary depending on the target
platform of your application and the type of application that you have created.
Build descriptor part
A build descriptor part controls the generation process and indicates what
other control parts are read during that process. Build descriptor parts
contain build descriptor options, which are covered in the EGL Generation
Guide. The information in this part is used at generation time, test time,
and run time.
Linkage options part
A linkage options part gives details on how a generated program calls or
transfers to and from other programs. The part also gives details on how a
generated COBOL program accesses files on remote CICS regions. The
information in this part is used at generation time, test time, and run time.
Resource associations part
A resource associations part relates an EGL record with the information
that is needed to access a file on a particular target platform; the
information in this part is used at generation time, test time, and run time.
Bind control part
A bind control part (which applies only when the target platform is z/OS®)
describes how to access a DB2 database from one or more programs. The
information in this part is used at generation time and preparation time.
Link edit part
A link edit part (which applies only when the target platform is z/OS)
describes how to form a load module from two or more programs. The
information in this part is used at generation time and preparation time.
Deployment descriptors
EGL deployment descriptors are not build parts, but they fit into the
category of files involved in generation and deployment. Deployment
descriptors contain information that describes either how a service part
from your application is exposed to other applications or how an external
service will be used in your application. For more information, see
Overview of EGL deployment descriptor file.

More information on build parts is available in the EGL Generation Guide.


Related concepts
“Introduction to EGL parts” on page 95
Parts are the building blocks of EGL applications.

Renaming parts
You can use the refactoring function of the workbench to rename parts and correct
references to those parts.
1. In one of the following places, select the part that you want to rename:
v Place the cursor on the part name in the EGL editor and right-click.
v Right-click the part in the Outline view, Parts List view, or Parts Reference
view.
v For generatable parts, right-click the file that contains the part in the Project
Explorer view
2. In the popup menu, click Refactor → Rename. The Rename window opens.

120 EGL Programmer’s Guide


3. In the Rename window, type a new name for the part, following EGL naming
conventions.
4. You can click Preview for a list of the changes that EGL will make if you
proceed.
5. If you clear the Update references check box, EGL will not search other files
for references to change. Generally, select this check box.
6. Click OK.

Renaming a part makes the following changes happen:


v EGL changes the name of the part to the new name
v EGL searches the build path for references to that part and changes the
references to match the new name of the part. For example, if you rename a
record part, EGL changes variable declarations to the new name of the record
v For generatable parts, EGL changes the name of the file to match the new part
name
v For JSF Handlers, EGL links the JSP file to the new part’s file, but it does not
change the name of the JSP file.
v For JSF Handlers, EGL updates references to the part’s file in the faces
configuration file.
v For Program parts within an EGL plug-in project, EGL also corrects the reference
to the program in the plugin.xml file.

You cannot rename functions in this way.


Related concepts
“Introduction to EGL parts” on page 95
Parts are the building blocks of EGL applications.
“Generatable parts and non-generatable parts” on page 96
EGL parts can be generatable or non-generatable.
Related tasks
“Renaming a source file” on page 91
You can use the refactoring function of the workbench to rename source files
and correct references to those files.
“Moving a source file” on page 92
You can use the refactoring function of the workbench to move source files and
correct references to those files.
“Moving parts”
You can use the refactoring function of the workbench to move parts between
source files and correct references to those parts.
“Renaming an EGL project” on page 75
If you rename an EGL project, you must manually correct most of the
references to that project.

Moving parts
You can use the refactoring function of the workbench to move parts between
source files and correct references to those parts.
1. In one of the following places, select the part that you want to move:
v Place the cursor on the part name in the EGL editor and right-click
v Right-click the part in the Outline view, Parts List view, or Parts Reference
view

Contents of an EGL application 121


v For generatable parts, right-click the file containing the part in the Project
Explorer view
2. In the popup menu, click Refactor → Move. The Textual Move window opens.
3. In the Textual Move window, select a new source file for the part. You can click
Create EGL file to create a new file to put the part into. If you are moving a
generatable part, the target source file must have the same name as the part.
4. You can click Preview for a list of the changes that EGL will make if you
proceed.
5. If you clear the Update references to the moved elements check box, EGL will
not search other files for references to change. Generally, select this check box.
6. Click OK.

Moving a part makes the following changes:


v EGL moves the part into the target source file
v EGL searches the build path for references to that part and changes the
references to match the new location of the part. For example, if you move a
record part, EGL changes variable declarations and any import statement to the
new location of the record
v For JSF Handlers, EGL links the JSP file to the new part’s file, but it does not
change the name of the JSP file.
v For JSF Handlers, EGL updates references to the part’s file in the faces
configuration file.
v For Program parts within an EGL plug-in project, EGL also corrects the reference
to the program in the plugin.xml file.
Related concepts
“Introduction to EGL parts” on page 95
Parts are the building blocks of EGL applications.
“Generatable parts and non-generatable parts” on page 96
EGL parts can be generatable or non-generatable.
Related tasks
“Renaming a source file” on page 91
You can use the refactoring function of the workbench to rename source files
and correct references to those files.
“Renaming parts” on page 120
You can use the refactoring function of the workbench to rename parts and
correct references to those parts.
“Moving a source file” on page 92
You can use the refactoring function of the workbench to move source files and
correct references to those files.

Properties
Properties set specific options for parts. In general, you specify the properties when
you create the part and then the properties are static. In certain circumstances,
however, it is possible to change a property dynamically.

The available properties are different for each part and for each stereotype, so
when creating a part, check to see what properties are appropriate. Some parts
have required properties, but most properties are optional.

The most common type of property is a simple property, a name-value pair that sets
an option for the part. Most parts can accept one or more simple properties by

122 EGL Programmer’s Guide


listing the name of the property and the value for the property within braces ( { } )
at the beginning of the part definition. If you specify more than one property for
the part, separate the name-value pairs with commas:
DataItem cost money(10,2)
{Currency = yes,
CurrencySymbol = "$"}
end

The code block that begins with the opening brace and ends with the closing brace
(that is, the list of properties and their values) is referred to as a set-value block.

Properties are useful only in specific situations. For example, DataItem parts can
include properties that apply only to specific types of user interfaces. As in the
previous example, you can specify the properties currency and currencySymbol on
any DataItem part to indicate that the DataItem represents a currency value and to
specify the monetary symbol used in displaying the value. From the topic
″currencySymbol″ in the EGL Language Reference, you can see that this property has
an effect when used on a Web page, but not in a Console User Interface
application.

Property values

You must provide a valid value for each property. Some properties accept string
literals, some accept a ″yes″ or ″no″ value, some accept values from lists of options
called enumerations, and others accept array literals. In most cases, you cannot use
a variable or constant as the value of a property. In other words, you cannot use a
boolean variable or a string variable set to ″yes″ or ″no″ for the value of the
currency property; you must specify a literal, unquoted ″yes″ or ″no″ value.

However, a few properties require that you supply the name of a variable or part
as a value. In this case, the property is not using the value of the variable or part;
it is referring to the variable or part itself. For example, the JSF Handler part
accepts the onPreRenderFunction property. This property specifies a function
within the handler that runs automatically each time the handler runs. In this case,
you might write the handler as follows:
handler myPage type JSFHandler
{onPreRenderFunction = refreshFunction}

function refreshFunction()
end

end

In this example, the onPreRenderFunction is set to the name of the function


refreshFunction. The handler must have a function with this name or EGL will
throw a validation error.

Some properties are provided for compatibility with previous versions or migrated
code and are unnecessary for new EGL applications. To know which properties are
provided for new code and which are used for compatibility, see the EGL Language
Reference topic that covers a particular part and its properties.

Inheriting and overriding properties

When you create a part based on another part, the new part inherits the properties
of the old part:

Contents of an EGL application 123


DataItem myRedVar int {color = red} end

Record myRedRecord type BasicRecord


myField myRedVar;
end

In this case, the field myField behaves as though you had specified the color
property on it.

However, properties do not transfer between most variables, as in this example:


myRedInt int {color = red};
myBlueInt int {color = blue};
myBlueInt = myRedInt;

In this case, myBlueInt still has the color property set to blue.

Reference variables are an exception to property transfers. See ″Properties″ in the


EGL Language Reference.

You can explicitly override properties, as in the following example:


DataItem myRedVar int {color = red} end

Record myBlueRecord type BasicRecord


myField myRedVar {color = blue};
end

In this case, the field myField overrides the red value with the blue value.

In this way, it is legal but not recommended to define a property twice for one part
or variable. The last property specification sets the value, as in this example:
myBlueVar int {color = red, color = blue};

In this case, the variable’s color property is set to blue because the second
definition overrides the first.
Related concepts
“Introduction to EGL parts” on page 95
Parts are the building blocks of EGL applications.
Related reference
Properties
Set-value blocks

Import and use statements


Use the EGL import and use statements to expand the visibility of code elements.

EGL import and use statements are commonly used in these situations:
v You import a logic part (such as a Program or Library) or a data part (such as a
Record or DataItem) so that you can refer to the part as though it were part of
the current package.
v You import an entire package so that you can refer to any of the parts that it
contains as if they were part of the current package.
v You use a library that is in your current package so that you can drop the
library prefix from any function names or variable names that you use from that
library.

124 EGL Programmer’s Guide


v You use a form group in your current package to gain unqualified access to the
forms in that group.
v You can use a data table so the program can directly access its fields.
v You can combine the import and use statements to refer to a function or variable
in a library from a different package.

For more information, see import and use/

Implicit import and use

You can refer directly to any of the parts that EGL defines without having to
import them, and you can refer directly to functions in system libraries or
EGL-defined enumerations without having to use them. These parts are therefore
described as implicitly imported and used.

For example, you can call the sysLib.writeStdOut() system function without
referring to the library because of this implicit use:
writeStdOut("Progam complete.");

Example

You might want to access customer information in your accounts receivable (AR)
package using the data definitions and functions from your customer relations
management (CRM) package. To call the function getCustomer() from the library
CustomerLib in the package com.companyb.crmpackage, you can use the following
code:
package com.companyb.arpackage;

import com.companyb.crmpackage.*; // home of CustomerLib library

program CustomerTest type BasicProgram


use CustomerLib; // add these functions to my scope

function main()
getCustomer();
end

end

The following aspects of the example are significant:


v The line import com.companyb.crmpackage.*; tells EGL to include the entire
CRMPackage in the scope of the current logic part. Only the parts you reference
will be added to the code.
v If you comment out the use statement, you cannot generate the program unless
you add the library name to the function name, as in
CustomerLib.getCustomer().
v If, later in the CustomerTest program, you define a local getCustomer() function,
EGL invokes that function in preference to the function of the same name in
com.companyb.crmpackage.CustomerLib. Similarly, if you have libraries named
CustomerLib in both the ARPackage and CRMPackage, EGL uses the local
(ARPackage) version.
Related reference
import
use
Scope

Contents of an EGL application 125


use considerations for DataTable parts
FormGroup properties
use considerations for FormGroup parts

126 EGL Programmer’s Guide


Working with EGL code
The EGL source editor provides a number of tools that you use to create EGL files.
Related concepts
“The EGL editor” on page 155
The EGL code editor looks and works like a standard text editor or code editor
for other languages, but it has additional features to help you edit EGL code.
The code editor highlights invalid syntax, provides an explanation for problems
in the code, colors keywords, strings, and comments, and helps you write EGL
code.
“Content assist” on page 157
“Code templates” on page 158
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can
be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.
Related tasks
“Enabling and disabling code templates” on page 159
“Creating code templates” on page 160
“Using cheat sheets” on page 166
Cheat sheets can assist you with common tasks in the Workbench. They
provide step-by-step instructions within a workbench view and can perform
some of the steps in the task automatically.
“Editing DataItem parts with the source assistant” on page 167

Common programming tasks


These topics contain information on how to complete several common
programming tasks in EGL.
Related tasks
“Turning lines of code into comment lines” on page 128
As in most languages, in EGL you can add comments in your code. EGL
ignores any text that is commented.
“Calling Java” on page 128
There are several ways to call Java code when you are generating Java from
EGL. This topic covers a few of the most common ways, including using the
system functions in the JavaLib system library such as javaLib.invoke(), and
declaring an ExternalType part.
“Encrypting passwords” on page 146
You can encrypt passwords with an EGL command-line utility. Password
encryption is supported only for Java programs and the debugger, not for
COBOL programs.
“Handling errors” on page 148
With EGL, you can decide how your program behaves in case of errors.
“Customizing runtime messages” on page 152

© Copyright IBM Corp. 1996, 2008 127


Turning lines of code into comment lines
As in most languages, in EGL you can add comments in your code. EGL ignores
any text that is commented.

You can comment a single line of code at once, or you can create a block of
commented lines.
v To comment a single line or a portion of a line, use two virgules or slashes (//):
myInt int; //This is an integer variable
//The following function is for error checking
function validateData (inputRecord myRecord inOut)
end
v To comment a block of lines, begin the comment with /* and end the comment
with */:
/*
This function is commented.
function myPlannedFunction()
end
*/

To comment lines, you can type the comment characters yourself, or you can tell
the EGL editor which lines to comment. Follow these steps to comment lines of
code in the EGL editor:
1. In the EGL editor, highlight one or more lines of code.
2. Right-click the highlighted lines and then click Comment. Comment indicators
(//) are placed at the beginning of each line in the selected range.

Use the same procedures to uncomment lines, but select Uncomment from the
pop-up menu.
Related concepts
“The EGL editor” on page 155
The EGL code editor looks and works like a standard text editor or code editor
for other languages, but it has additional features to help you edit EGL code.
The code editor highlights invalid syntax, provides an explanation for problems
in the code, colors keywords, strings, and comments, and helps you write EGL
code.
Related tasks
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.

Calling Java
There are several ways to call Java code when you are generating Java from EGL.
This topic covers a few of the most common ways, including using the system
functions in the JavaLib system library such as javaLib.invoke(), and declaring an
ExternalType part.

Prerequisites
v An EGL project generated to Java, not to COBOL
v An EGL program or other logic part

Calling a Java class once

If you need to use a method in a Java class only once, you can use the
javaLib.invoke system function.

128 EGL Programmer’s Guide


This example calls the method random. This method belongs to the class
java.lang.Math and returns a random number between 0 and 1. In this case, the
class resembles an EGL library and the method works like a function in this
library.

The only methods you can call in this way are the methods defined as static.
″Static″ is a Java term that has no parallel in EGL; in this context, it means that the
method is ready to be called at any time and needs no initialization before use.
1. In an EGL function within a logic part, declare any variables that you might
need to pass or that you might need to accept a return value:
myNumber float;
2. Use the javaLib.invoke() system function to call the method, passing the name
of the class and the method to call as parameters:
myNumber = javaLib.invoke("java.lang.Math", "random");
3. Then, you can use the results of the call:
sysLib.writeStderr(strLib.formatNumber(myNumber));

To pass a parameter to the method, use the argument parameter of


javaLib.invoke().

Calling a Java class multiple times

If you plan to use methods in a Java class several times, or if the method that you
want to call is not defined as static, you should create an ExternalType part, as in
″Creating an ExternalType part to represent a class″ that follows. However, for
compatibility with migrated programs, and with a little less EGL code, you can use
other functions in javaLib to initialize and use a class multiple times, even its
non-static methods.

The following example uses a different class that returns random numbers. The
method nextInt in the class java.util.Random provides an alternate way to return
a random integer. Because the method is not defined as static, you cannot use
javaLib.invoke() to call nextInt without any preparation:
//Error! The method nextInt() is not static.
myInt int = javaLib.invoke("java.util.Random", "nextInt");

Instead, you must first initialize the class and give it an identifier in EGL using
javaLib.storeNew(). Note the use of the casting operator, AS, to convert Java types
to EGL:
javaLib.storeNew("myRandomGenerator" AS "objId:java", "java.util.Random");

Then you can use the class repeatedly through javaLib.invoke:


myInt int = javaLib.invoke("myRandomGenerator" AS "objId:java", "nextInt");

In these examples, the string myRandomGenerator is an identifier that represents the


class. Each time you use the class, you tell EGL that this identifier refers not to an
EGL part or a string literal but a Java class with the code AS "objId:java". For
more information, see as operator. For more details on calling Java classes and
methods, see Java access functions.

Creating an ExternalType part to represent a class

If you plan to use the class often, or if the method that you want to use is not
defined as static, you can define an EGL ExternalType part, an EGL part that

Working with EGL code 129


represents a Java class directly. After you have defined the ExternalType part, you
can create variables based on it and use those variables just like you would use the
names of EGL libraries.

This example uses the class java.util.Random. This class has a non-static method
named nextInt which returns a random integer. Again, for the purposes of EGL
programming, imagine that the class is a library and the methods are functions.
1. In an EGL source file, begin defining the ExternalType part by giving it the
name of the Java class you want to use.
ExternalType Random type JavaObject
{packageName = "java.util",
javaName = "Random"}
//prototypes go here
end

Note that the name of the Java class is divided into two properties:
v packageName is the name of the package that holds the class. Java packages
and EGL packages work in much the same way.
v javaName is the name of the Java class itself. You can name the ExternalType
part with the same name as the class if you want to.
2. Within the ExternalType part, create function prototypes that represent the
methods in the class that you want to use:
ExternalType Random type JavaObject
{packageName = "java.util",
javaName = "Random"}
function nextInt() returns(int);
end

Again, function prototypes in Java are similar to function prototypes in EGL,


such as those in an Interface part. They list the function or method name, its
arguments, and its return value, but have no internal logic. Here, a prototype
links a function in the ExternalType part to a method in the Java class.
Also, you must be careful to match Java types to compatible EGL types and
vice versa. Tables associating EGL parts and Java parts are available in
Mapping EGL primitives to Java.
3. The ExternalType part also requires a constructor. In EGL terms, a constructor is
a function that runs when a new variable that is based on the part is created.
Constructors are not commonly used in EGL; for more information about them,
see new operator.
ExternalType Random type JavaObject
{packageName = "java.util",
javaName = "Random"}
function nextInt() returns(int);
constructor();
end
4. To create a variable based on an ExternalType part, you must first call its
constructor with the new keyword and the name of the part:
myRandomGenerator Random = new Random();

The code new Random() is actually a function call to the constructor() function
prototype in the part definition, which in turn refers to the constructor of the
Java class.
5. Use the functions in ExternalType just like you were using an EGL library:
myInt int = myRandomGenerator.nextInt();
sysLib.writeStderr(strLib.formatNumber(myInt));

130 EGL Programmer’s Guide


Here is an example of a complete program that uses an ExternalType part as
explained above:
/*
Writes a random integer to the console
using an ExternalType part
*/
program ExternalTypeTest type BasicProgram

function main()
myRandomGenerator Random = new Random();
myInt int = myRandomGenerator.nextInt();
SysLib.writeStderr(StrLib.formatNumber(myInt));
end

end

externalType Random type JavaObject


{packageName = "java.util",
javaName = "Random"}
constructor();
function nextInt() returns(int);
end

For more details on the ExternalType part, see ExternalType part.


Related tasks
“Common programming tasks” on page 127
These topics contain information on how to complete several common
programming tasks in EGL.
Adding a resource associations part to an EGL build file
Related reference
EGL library javaLib
The javaLib functions access local Java objects and classes through your
generated Java code.
Java access functions
invoke()
storeNew()
ExternalType part
ExternalType parts map EGL to external language elements.
Mapping EGL primitives to Java
as operator
new operator
Function prototypes

Calling C functions with the call statement


EGL programs can invoke C functions with the call statement. Follow these steps
to invoke a C function from EGL:
1. Identify the C function to call. This function must return an integer value; zero
indicates success and any other value prompts EGL to throw an
InvocationException from the statement that invoked the C function.
2. Link to the C function and the DLL containing that function using a callLink
element with type set to remoteCall, as explained in the EGL Generation Guide.
See If callLink type is remoteCall.
3. Call the function using the following syntax:

Working with EGL code 131


call functionName (parameters);

Use the pgmName property of the callLink element as functionName, and any
parameters to pass to the function as parameters. To map EGL data types to C
data types for use in these parameters, see “Mapping EGL data types to C.”
Related reference
“Mapping EGL data types to C”
If callLink type is remoteCall
call

Mapping EGL data types to C


The following table matches EGL primitive types to C primitive types for use in
calling C functions with the call statement, as explained in “Calling C functions
with the call statement” on page 131.
Table 26. EGL primitives and C primitives
EGL primitive C type
INT int (signed 4-byte integer)
SMALLINT short (signed 2-byte integer)
BIGINT long long (signed 8-byte integer)
NUM COBOL zoned format. For ASCII, the sign
bits are x30 for a positive number and x70
for a negative number. For EBCDIC, the sign
bits are xF0 for a positive number and xD0
for a negative number
NUMC COBOL zoned format. For ASCII, the sign
bits are x30 for a positive number and x70
for a negative number. For EBCDIC, the sign
bits are xC0 for a positive number and xD0
for a negative number
DECIMAL, MONEY COBOL packed format. The sign bits are xC
for a positive number and xD for a negative
number.
PACF COBOL packed format. The sign bits are xF
for a positive number and xD for a negative
number.
FLOAT double
SMALLFLOAT float
BOOLEAN char, with 1 representing true and 0
representing false
HEX unsigned char
CHAR char
MBCHAR, DBCHAR char; use mbstowcs from stdlib.h to convert
to wchar_t
UNICODE, STRING char, with data in the UTF-16 encoding, two
bytes per character. Use mbstowcs from
stdlib.h to convert to wchar_t. On Windows®
and Linux®, the data is in little-endian order;
on other systems, the data is in big-endian
order.

132 EGL Programmer’s Guide


Table 26. EGL primitives and C primitives (continued)
EGL primitive C type
DATE char, in yyyMMdd format, with digits stored
as ″0″ through ″9″
TIME char, in HHmmss format, with digits stored
as ″0″ through ″9″
TIMESTAMP char, with digits stored as ″0″ through ″9″
INTERVAL char, starting with ″+″ or ″-″ followed by the
digits of the value as ″0″ through ″9″

The values of the text types (CHAR, MBCHAR, DBCHAR, UNICODE, STRING),
data and time types (DATE, TIME, TIMESTAMP, and INTERVAL), and HEX do not
end with a null byte. You can use StrLib.setNullTerminator to convert trailing
blanks to null, or StrLib.setBlankTerminator to convert trailing nulls to blanks.

For arrays, the data passed to the C function is as follows, in this order:
1. An INT value representing the current length of the array
2. An INT value representing the maximum size of the array
3. The following data for each element in the array:
a. If the element is a STRING or a record, an INT value representing the
length of the element’s data
b. The data of the element
c. If the element is nullable, a SHORT representing the element’s nullability. If
the element is nullable and has a null value, the value of the SHORT is -1.
d. If the element is nullable, a SHORT as a filler value. EGL ignores this value.

For non-structured records, the data passed to the C function is as follows, in this
order:
1. An INT value, representing the number of fields
2. The following data for each field in the record:
a. An INT value representing the length of the field’s data
b. The field’s data
c. If the field is nullable, a SHORT representing the field’s nullability. If the
field is nullable and has a null value, the value of the SHORT is -1.
d. If the element is nullable, a SHORT as a filler value. EGL ignores this value.

For structured records, EGL passes the data of the lowest-level fields. You could
define a C struct with the same structure as the record.
Related reference
“Calling C functions with the call statement” on page 131
Primitive data types

Calling C functions through EGL libraries


EGL programs can invoke C functions through Library parts with the stereotype
nativeLibrary.

Follow these steps to prepare to invoke a C function from EGL:


1. Identify the C functions to use in your EGL program and make sure they
return an INT value of zero it they succeed.

Working with EGL code 133


2. Download the EGL runtimes and extract the stack library and application object
file to your computer:
a. Download the EGL runtime file as explained in Installing the EGL runtime
code for Java.
b. Unzip the file to a temporary directory and find the following files:
For the platform-specific stack libraries:
v AIX®: EGLRuntimes/Aix/bin/libstack.so
v Linux: EGLRuntimes/Linux/bin/libstack.so
v Win32:
EGLRuntimes/Win32/bin/stack.dll
EGLRuntimes/Win32/bin/stack.lib
For the platform-specific application object files:
v AIX: EGLRuntimes/Aix/bin/application.o
v Linux: EGLRuntimes/Linux/bin/application.o
v Win32: EGLRuntimes/Win32/bin/application.obj
3. Compile all C code into one shared library and link it with the appropriate
platform-specific stack library.
Your C code receives values from EGL using pop external functions and returns
values to EGL using return external functions.
To compile all C code into a shared library:
a. Using standard methods, compile all of your C code into one shared library
and link it with the appropriate platform-specific EGL stack library.
b. In the following platform-specific examples, file1.c and file2.c are C files
containing functions invoked from EGL:
On AIX (the ld command must be on a single line):
cc -c -Iincl_dir file1.c file2.c
ld -G -b32 -bexpall -bnoentry
-brtl file1.o file2.o -Lstack_lib_dir
-lstack -o lib1_name -lc
On Linux (the gcc command must be on a single line):
cc -c -Iincl_dir file1.c file2.c
gcc -shared file1.o file2.o -Lstack_lib_dir
-lstack -o lib1_name
On Windows (the link command must be on a single line):
cl /c -Iincl_dir file1.c file2.c
link /DLL file1.obj file2.obj
/LIBPATH:stack_lib_dir
/DEFAULTLIB:stack.lib /OUT:lib1_name
incl_dir
The directory location for the header files.
stack_lib_dir
The directory location for the stack library.
lib1_name
The name of the output library.

Note: If your C code is using any of the IBM Informix ESQL/C library
functions (BIGINT, DECIMAL, DATE, INTERVAL, DATETIME), then the
ESQL/C library must also be linked.
4. Create a function table.

134 EGL Programmer’s Guide


The function table is a C source file which includes the names of all C
functions to be invoked from the EGL program. In the following function table
example, c_fun1 and c_fun2 are names of the C functions. All of the functions
identified in the code must have been exported from the C shared library
created in a previous step.
#include <stdio.h>
struct func_table {

char *fun_name;
int (*fptr)(int);
};

extern int c_fun1(int);


extern int c_fun2(int);
/* Similar prototypes for other functions */

struct func_table ftab[] =


{
"c_fun1", c_fun1,
"c_fun2", c_fun2,
/* Similarly for other functions */
"", NULL
};
Create a function table based on the example above, and populate the function
table with the appropriate C functions. Indicate the end of the function table
with "", NULL.
5. Compile the function table and the appropriate platform-specific application
object file into a shared library, and link this shared library with the shared
library created in Step 2 and the stack library.
The application object file is the interface between the EGL code and the C
code.
The following two artifacts must be compiled into one shared library and
linked with the stack library and the library created in Step 2 above:
v function table
v application object file
Compile the new shared library using the following example, where ftable.c is
the name of the function table and mylib is the name of the C shared library
created in Step 2 and lib_dir is the directory location for mylib. Specify
lib2_name by using the dllName property or the vgj.defaultI4GLNativeLibrary
Java runtime property.
On AIX (the ld command must be on a single line):
cc -c ftable.c
ld -G -b32 -bexpall -bnoentry
-brtl ftable.o application.o
-Lstack_lib_dir -lstack -Llib_dir
-lmylib -o lib2_name -lc
On Linux (the gcc command must be on a single line):
cc -c ftable.c
gcc -shared ftable.o application.o
-Lstack_lib_dir -lstack -Llib_dir
-lmylib -o lib2_name
On Windows (the link command must be on a single line):
cl /c ftable.c
link /DLL ftable.obj application.obj
/LIBPATH:stack_lib_dir
/DEFAULTLIB:stack.lib
/LIBPATH:lib_dir
/DEFAULTLIB:mylib.lib /OUT:lib2_name

Working with EGL code 135


Link the three libraries together.

With your C shared library, function table, and stack library linked, you are now
ready to invoke the C functions from your EGL code. For information on how to
invoke a C function in EGL, see Invoking a C function from an EGL program.
Related concepts
Linkage options part
Related reference
“BIGINT functions for C” on page 138
“Mapping EGL data types to C” on page 132
“DATE functions for C” on page 139
“DATETIME and INTERVAL functions for C” on page 139
“DECIMAL functions for C” on page 140
“Invoking a C function from an EGL program”
“Return functions for C” on page 144
“Stack functions for C” on page 141

Invoking a C function from an EGL program


You can invoke (or call) a C function from an EGL program through a Library part
with the stereotype nativeLibrary. Prior to following the instructions below, you
must compile and link your C code as identified in “Calling C functions through
EGL libraries” on page 133.

To invoke a C function from an EGL program:


1. Using the function invocation statement, specify the following:
v The name of the C function
v Any arguments to pass to the C function
v Any variables to return to the EGL program
2. Create an EGL Library part with the stereotype nativeLibrary containing the
function definition.
3. With the USE statement, specify the EGL native library in the calling module.

For example, the following function invocation statement calls the C function
sendmsg( )
sendmsg(chartype, 4, msg_status, return_code);

It passes two arguments (chartype and 4, respectively) to the function and expects
two arguments to be passed back (msg_status and return_code, respectively). This
is made clear by defining the function in a native library as follows:
Library I4GLFunctions type nativeLibrary
{callingConvention = I4GL, dllName = "mydll"}
Function sendmsg(chartype char(10) in, i int in,
msg_status int out, return_code int out)
end
end

The arguments passed are specified using the ″in″ parameter and the arguments to
be returned are specified using the ″out″ parameter.
callingConvention
specifies that the arguments will be passed between functions and the calling
code using the argument stack mechanism.

136 EGL Programmer’s Guide


dllName
specifies the C shared library in which this function exists.

Note: The C shared library name can also be specified using the
vgj.defaultI4GLNativeLibrary system property. If both dllName and the system
property have been specified, the dllName will be used.

The C function receives an integer argument that specifies how many values were
pushed on the argument stack (in this case, two arguments). This is the number of
values to be popped off the stack in the C function. The function also needs to
return values for the msg_status and return_code arguments before passing control
back to the EGL program.

The C function should not assume it has been passed the correct number of
stacked values. The C function should test its integer argument to see how many
EGL arguments were stacked for it.

This example shows a C function that requires exactly one argument:


int nxt_bus_day(int nargs);
{
int theDate;
if (nargs != 1)
{
fprintf(stderr,
"nxt_bus_day: wrong number of parms (%d)\n",
nargs );
ibm_lib4gl_returnDate(0L);
return(1);
}
ibm_lib4gl_popDate(&theDate);
switch(rdayofweek(theDate))
{
case 5: /* change friday -> monday */
++theDate;
case 6: /* saturday -> monday*/
++theDate;
default: /* (sun..thur) go to next day */
++theDate;
}
ibm_lib4gl_returnDate(theDate); /* stack result */
return(1) /* return count of stacked */
}

The function returns the date of the next business day after a given date. Because
the function must receive exactly one argument, the function checks for the
number of arguments passed. If the function receives a different number of
arguments, it terminates the program (with an identifying message).
Related reference
“BIGINT functions for C” on page 138
“Mapping EGL data types to C” on page 132
“DATE functions for C” on page 139
“DATETIME and INTERVAL functions for C” on page 139
“DECIMAL functions for C” on page 140
Library part
Library parts support the sharing of functions and variables.
“Stack functions for C” on page 141
“Return functions for C” on page 144

Working with EGL code 137


“Calling C functions through EGL libraries” on page 133

BIGINT functions for C


Note: The following BIGINT functionality is available only to users of IBM
Informix ESQL/C. To use these functions, ESQL/C users will need to
manually link their C code to the ESQL/C libraries.

The BIGINT data type is a machine-independent method for representing numbers


in the range of -263-1 to 263-1. ESQL/C provides routines that facilitate the
conversion from the BIGINT data type to other data types in the C language.

The BIGINT data type is internally represented with the ifx_int8_t structure.
Information about the structure can be found in the header file int8.h, which is
included in the ESQL/C product. Include this file in all C source files that use any
of the BIGINT functions.

All operations on int8 type numbers must be performed using the following
ESQL/C library functions for the int8 data type. Any other operations,
modifications, or analyses can produce unpredictable results. The ESQL/C library
provides the following functions that allow you to manipulate int8 numbers and
convert int8 type numbers to and from other data types.

Function Name Description


ifx_int8add( ) Adds two BIGINT type values
ifx_int8cmp( ) Compares two BIGINT type numbers
ifx_int8copy( ) Copies an ifx_int8_t structure
ifx_int8cvasc( ) Converts a C char type value to a BIGINT type number
ifx_int8cvdbl( ) Converts a C double type number to a BIGINT type number
ifx_int8cvdec( ) Converts a decimal type value into a BIGINT type value
ifx_int8cvflt( ) Converts a C float type value into a BIGINT type value
ifx_int8cvint( ) Converts a C int type number into a BIGINT type number
ifx_int8cvlong( ) Converts a C long (int on 64 bit machine) type value to a
BIGINT type value
ifx_int8cvlong_long( ) Converts a C long long type (8-byte value, long long in 32 bit
and long in 64 bit) value into a BIGINT type value
ifx_int8div( ) Divides two BIGINT numbers
ifx_int8mul( ) Multiples two BIGINT numbers
ifx_int8sub( ) Subtracts two BIGINT numbers
ifx_int8toasc( ) Converts a BIGINT type value to a C char type value
ifx_int8todbl( ) Converts a BIGINT type value to a C double type value
ifx_int8todec( ) Converts a BIGINT type number into a decimal type number
ifx_int8toflt( ) Converts a BIGINT type number into a C float type number
ifx_int8toint( ) Converts a BIGINT type value to a C int type value
ifx_int8tolong( ) Converts a BIGINT type value to a C long (int on 64 bit
machine) type value
ifx_int8tolong_long( ) Converts a C long long (long on 64 bit machine) type to a
BIGINT type value

138 EGL Programmer’s Guide


For more information about the individual functions, see the following: IBM
Informix ESQL/C Programmer’s Manual.
Related reference
“DATE functions for C”
“DATETIME and INTERVAL functions for C”
“DECIMAL functions for C” on page 140
“Invoking a C function from an EGL program” on page 136

DATE functions for C


Note: The following DATE functionality is available only to users of IBM Informix
ESQL/C. To use these functions, ESQL/C users will need to manually link
their C code to the ESQL/C libraries.

The following date-manipulation functions are in the ESQL/C library. They convert
dates between a string format and the internal DATE format.

Function Name Description


rdatestr( ) Converts an internal DATE to a character string format
rdayofweek( ) Returns the day of the week of a date in internal format
rdefmtdate( ) Converts a specified string format to an internal DATE
rfmtdate( ) Converts an internal DATE to a specified string format
rjulmdy( ) Returns month, day, and year from a specified DATE
rleapyear( ) Determines whether the specified year is a leap year
rmdyjul( ) Returns an internal DATE from month, day, and year
rstrdate( ) Converts a character string format to an internal DATE
rtoday( ) Returns a system date as an internal DATE

For more information about the individual functions, see the following: IBM
Informix ESQL/C Programmer’s Manual.
Related reference
“BIGINT functions for C” on page 138
“DATETIME and INTERVAL functions for C”
“DECIMAL functions for C” on page 140
“Invoking a C function from an EGL program” on page 136

DATETIME and INTERVAL functions for C


Note: The following DATETIME and INTERVAL functionality is available only to
users of IBM Informix ESQL/C. To use these functions, ESQL/C users will
need to manually link their C code to the ESQL/C libraries.

The DATETIME and INTERVAL data types are internally represented with the
dtime_t and intrvl_t structures, respectively. Information about these structures can
be found in the header file datetime.h, which is included in the ESQL/C product.
Include this file in all C source files that use any of the DATETIME and INTERVAL
functions.

You must use the following ESQL/C library functions for the datetime and
interval data types to perform all operations on those types of values.

Working with EGL code 139


Function Name Description
dtaddinv( ) Adds an interval value to a datetime value
dtcurrent( ) Gets the current date and time
dtcvasc( ) Converts an ANSI-compliant character string to a
datetime value
dtcvfmtasc( ) Converts a character string with a specified format to a
datetime value
dtextend( ) Changes the qualifier of a datetime value
dtsub( ) Subtracts one datetime value from another
dsubinv() Subtracts an interval value from a datetime value
dttoasc( ) Converts a datetime value to an ANSI-compliant
character string
dttofmtasc( ) Converts a datetime value to a character string with a
specified format
incvasc( ) Converts an ANSI-compliant character string to an
interval value
incvfmtasc( ) Converts a character string with a specified format to
an interval value
intoasc( ) Converts an interval value to an ANSI-compliant
character string
intofmtasc( ) Converts an interval value to a character string with a
specified format
invdivdbl( ) Divides an interval value by a numeric value
invdivinv( ) Divides an interval value by another interval value
invextend( ) Extends an interval value to a different interval
qualifier
invmuldbl( ) Multiples an interval value by a numeric value

For more information about the individual functions, see the following: IBM
Informix ESQL/C Programmer’s Manual.
Related reference
“BIGINT functions for C” on page 138
“DATE functions for C” on page 139
“DECIMAL functions for C”
“Invoking a C function from an EGL program” on page 136

DECIMAL functions for C


Note: The following DECIMAL functionality is available only to users of IBM
Informix ESQL/C. To use these functions, ESQL/C users will need to
manually link their C code to the ESQL/C libraries.

The data type DECIMAL is a machine-independent method for representing


numbers of up to 32 significant digits, with or without a decimal point, and with
exponents in the range -128 to +126. ESQL/C provides routines that facilitate the
conversion of DECIMAL-type numbers to and from every data type allowed in the
C language. DECIMAL-type numbers consist of an exponent and a mantissa (or
fractional part) in base 100. In normalized form, the first digit of the mantissa must
be greater than zero.

140 EGL Programmer’s Guide


The DECIMAL date type is internally represented with the dec_t structure. The
decimal structure and the type definition dec_t can be found in the header file
decimal.h, which is included in the ESQL/C product. Include this file in all C
source files that use any of the decimal functions.

All operations on decimal type numbers must be performed using the following
ESQL/C library functions for the decimal data type. Any other operations,
modifications or analyses can produce unpredictable results.

Function Name Description


deccvasc( ) Converts C int1 type to DECIMAL type
dectoasc( ) Converts DECIMAL type to C int1 type
deccvint( ) Converts C int type to DECIMAL type
dectoint( ) Converts DECIMAL type to C int type
deccvlong( ) Converts C int4 type to DECIMAL type
dectolong( ) Converts DECIMAL type to C int4 type
deccvflt( ) Converts C float type to DECIMAL type
dectoflt( ) Converts DECIMAL type to C float type
deccvdbl( ) Converts C double type to DECMAL type
dectodbl( ) Converts DECIMAL type to C double type
decadd( ) Adds two DECIMAL numbers
decsub( ) Subtracts two DECIMAL numbers
decmul( ) Multiplies two DECIMAL numbers
decdiv( ) Divides two DECIMAL numbers
deccmp( ) Compares two DECIMAL numbers
deccopy( ) Copies a DECIMAL number
dececvt( ) Converts DECIMAL value to ASCII string
decfcvt( ) Converts DECIMAL value to ASCII string

For more information about the individual functions, see the following: IBM
Informix ESQL/C Programmer’s Manual.
Related reference
“BIGINT functions for C” on page 138
“DATE functions for C” on page 139
“DATETIME and INTERVAL functions for C” on page 139
“Invoking a C function from an EGL program” on page 136

Stack functions for C


To call a C function, EGL uses an argument stack, a mechanism that passes
arguments between the functions and the calling code. The EGL calling function
pushes its arguments onto the stack and the called C function pops them off of the
stack to use the values. The called function pushes its return values onto the stack
and the caller pops them off to retrieve the values. The pop and return external
functions are provided with the argument stack library. The pop external functions
are described below according to the data type of the value that each pops from
the argument stack. The return external functions are described in Return functions
for C.

Working with EGL code 141


Note: The pop functions were originally used with IBM Informix 4GL (I4GL);
hence the inclusion of ″4gl″ in the function names.

Library functions for returning values

You can call the following library functions from a C function to pop number
values from the argument stack:
v extern void ibm_lib4gl_popMInt(int *iv)
v extern void ibm_lib4gl_popInt2(short *siv)
v extern void ibm_lib4gl_popInt4(int *liv)
v extern void ibm_lib4gl_popFloat(float *fv)
v extern void ibm_lib4gl_popDouble(double *dfv)
v extern void ibm_lib4gl_popDecimal(dec_t *decv)
v extern void ibm_lib4gl_popInt8(ifx_int8_t *bi)

The following table and similar tables below map the return function names
between I4GL pre-Version 7.31 and Version 7.31 and later:

Pre-Version 7.31 name Version 7.31 and later name


popint ibm_lib4gl_popMInt
popshort ibm_lib4gl_popInt2
poplong ibm_lib4gl_popInt4
popflo ibm_lib4gl_popFloat
popdub ibm_lib4gl_popDouble
popdec ibm_lib4gl_popDecimal

Each of these functions, like all library functions for popping values, performs the
following actions:
1. Removes one value from the argument stack.
2. Converts its data type if necessary. If the value on the stack cannot be
converted to the specified type, an error occurs.
3. Copies the value to the designated variable.

The structure types dec_t and ifx_int8_t are used to represent DECIMAL and
BIGINT data in a C program. For more information about the dec_t and ifx_int8_t
structure types and library functions for manipulating and printing DECIMAL and
BIGINT variables, see the IBM Informix ESQL/C Programmer’s Manual.

Library Functions for Popping Character Strings

You can call the following library functions to pop character values:
v extern void ibm_lib4gl_popQuotedStr(char *qv, int len)
v extern void ibm_lib4gl_popString(char *qv, int len)
v extern void ibm_lib4gl_popVarChar(char *qv, int len)

Pre-Version 7.31 name Version 7.31 and later name


popquote ibm_lib4gl_popQuotedStr
popstring ibm_lib4gl_popString
popvchar ibm_lib4gl_popVarChar

142 EGL Programmer’s Guide


Both ibm_lib4gl_popQuotedStr( ) and ibm_lib4gl_popVarChar( ) copy exactly len
bytes into the string buffer *qv. Here ibm_lib4gl_popQuotedStr( ) pads with
spaces as necessary, but ibm_lib4gl_popVarChar( ) does not pad to the full length.
The final byte copied to the buffer is a null byte to terminate the string, so the
maximum string data length is len-1. If the stacked argument is longer than len-1,
its trailing bytes are lost.

The len argument sets the maximum size of the receiving string buffer. Using
ibm_lib4gl_popQuotedStr( ), you receive exactly len bytes (including trailing
blank spaces and the null), even if the value on the stack is an empty string. To
find the true data length of a string retrieved by ibm_lib4gl_popQuotedStr( ), you
must trim trailing spaces from the popped value.

Note: The functions ibm_lib4gl_popString( ) and ibm_lib4gl_popQuotedStr( ) are


identical, except that ibm_lib4gl_popString( ) automatically trims any
trailing blanks.

Library Functions for Popping Time Values

You can call the following library functions to pop DATE, INTERVAL, and
DATETIME (TIMESTAMP) values:
v extern void ibm_lib4gl_popDate(int *datv)
v extern void ibm_lib4gl_popInterval(intrvl_t *iv, int qual)

You can call the following library function to pop TIMESTAMP values:
v extern void ibm_lib4gl_popDateTime(dtime_t *dtv, int qual)

Pre-Version 7.31 name Version 7.31 and later name


popdate ibm_lib4gl_popDate
popdtime ibm_lib4gl_popDateTime
popinv ibm_lib4gl_popInterval

The structure types dtime_t and intrvl_t are used to represent DATETIME and
INTERVAL data in a C program. The qual argument receives the binary
representation of the DATETIME or INTERVAL qualifier. For more information
about the dtime_t and intrvl_t structure types and library functions for
manipulating and printing DATE, DATETIME, and INTERVAL variables, see the
IBM Informix ESQL/C Programmer’s Manual.

Library Functions for Popping BYTE or TEXT Values

You can call the following function to pop a BYTE or TEXT argument:
v extern void ibm_lib4gl_popBlobLocator(loc_t **blob)

Pre-Version 7.31 name Version 7.31 and later name


poplocator ibm_lib4gl_popBlobLocator

The structure type loc_t defines a BYTE or TEXT value, and is discussed in the
IBM Informix ESQL/C Programmer’s Manual.

Any BYTE or TEXT argument must be popped as BYTE or TEXT because EGL
provides no automatic data type conversion.
Working with EGL code 143
Related reference
“BIGINT functions for C” on page 138
“Mapping EGL data types to C” on page 132
“Calling C functions through EGL libraries” on page 133
“DATE functions for C” on page 139
“DATETIME and INTERVAL functions for C” on page 139
“DECIMAL functions for C” on page 140
“Invoking a C function from an EGL program” on page 136
“Return functions for C”

Return functions for C


To call a C function, EGL uses an argument stack, a mechanism that passes
arguments between the functions and the calling code. The EGL calling function
pushes its arguments onto the stack and the called C function pops them off of the
stack to use the values. The called function pushes its return values onto the stack
and the caller pops them off to retrieve the values. The pop and return external
functions are provided with the argument stack library. The return external
functions are described below; the pop external functions used are described in
Stack functions for C.

The external return functions copy their arguments to storage allocated outside the
calling function. This storage is released when the returned value is popped. This
situation makes it possible to return values from local variables of the function.

Note: The return functions were originally used with IBM Informix 4GL (I4GL);
hence the inclusion of ″4gl″ in the function names.

Library functions for returning values

The following library functions are available to return values:


v extern void ibm_lib4gl_returnMInt(int iv)
v extern void ibm_lib4gl_returnInt2(short siv)
v extern void ibm_lib4gl_returnInt4(int lv)
v extern void ibm_lib4gl_returnFloat(float *fv)
v extern void ibm_lib4gl_returnDouble(double *dfv)
v extern void ibm_lib4gl_returnDecimal(dec_t *decv)
v extern void ibm_lib4gl_returnQuotedStr(char *str0)
v extern void ibm_lib4gl_returnString(char *str0)
v extern void ibm_lib4gl_returnVarChar(char *vc)
v extern void ibm_lib4gl_returnDate(int date)
v extern void ibm_lib4gl_returnDateTime(dtime_t *dtv)
v extern void ibm_lib4gl_returnInterval(intrvl_t *inv)
v extern void ibm_lib4gl_returnInt8(ifx_int8_t *bi)

The following table maps the return function names between I4GL pre-Version 7.31
and Version 7.31 and later:

Pre-Version 7.31 name Version 7.31 and later name


retint ibm_lib4gl_returnMInt
retshort ibm_lib4gl_returnInt2

144 EGL Programmer’s Guide


Pre-Version 7.31 name Version 7.31 and later name
retlong ibm_lib4gl_returnInt4
retflo ibm_lib4gl_returnFloat
retdub ibm_lib4gl_returnDouble
retdec ibm_lib4gl_returnDecimal
retquote ibm_lib4gl_returnQuotedStr
retstring ibm_lib4gl_returnString
retvchar ibm_lib4gl_returnVarChar
retdate ibm_lib4gl_returnDate
retdtime ibm_lib4gl_returnDateTime
retinv ibm_lib4gl_returnInterval

The argument of ibm_lib4gl_returnQuotedStr( ) is a null-terminated string. The


ibm_lib4gl_returnString( ) function is included only for symmetry; it internally
calls ibm_lib4gl_returnQuotedStr( ).

The C function can return data in whatever form is convenient. If conversion is


possible, EGL converts the data type as required when popping the value. If data
type conversion is not possible, an error occurs.

C functions called from EGL must always exit with the statement return(n), where
n is the number of return values pushed onto the stack. A function that returns
nothing must exit with return(0).
Related reference
“BIGINT functions for C” on page 138
“Mapping EGL data types to C” on page 132
“Invoking a C function from an EGL program” on page 136
“Calling C functions through EGL libraries” on page 133
“DATE functions for C” on page 139
“DATETIME and INTERVAL functions for C” on page 139
“DECIMAL functions for C” on page 140
“Stack functions for C” on page 141

C data types and EGL primitive types


The following table shows the mapping between C data types, I4GL data types,
and EGL primitive types for use in a Library part with the stereotype
nativeLibrary.

C data types Equivalent I4GL data Equivalent EGL primitive type


type
char CHAR or CHARACTER UNICODE(1)
char NCHAR UNICODE(size)
char NVARCHAR STRING
char VARCHAR STRING
int INT or INTEGER INT
short SMALLINT SMALLINT
ifx_int8_t BIGINT BIGINT

Working with EGL code 145


C data types Equivalent I4GL data Equivalent EGL primitive type
type
dec_t DEC or DECIMAL(p,s,) DECIMAL(p)
or NUMERIC(p)
dec_t MONEY MONEY
double FLOAT FLOAT
float SMALLFLOAT SMALLFLOAT
loc_t TEXT CLOB
loc_t BYTE BLOB
int DATE DATE
dtime_t DATETIME TIMESTAMP
intvl_t INTERVAL INTERVAL

Related reference
Primitive data types
“Invoking a C function from an EGL program” on page 136

Working with substrings


You can use brackets to treat a CHAR(n) or STRING variable as an array of
characters.

The following tips and tricks make use of this idea.

Creating a substring
Tip: The following example shows how to use the bracket syntax to create a
substring:
myStringVar1 STRING = "abcdefghijklmn";
myStringVar2 STRING;

myStringVar2 = myStringVar1[3:6];
writeStdOut(myStringVar2); // displays "cdef"

Right-justifying a character variable


Tip: The following example shows how to create a fixed length character variable
to hold the right-justified contents of a STRING:
myCharVar CHAR(10);
myStringVar STRING = "abc";

myCharVar[10 - strLib.characterLen(myStringVar) : 10] = myStringVar;


writeStdOut(myCharVar); // displays " abc"

Encrypting passwords
You can encrypt passwords with an EGL command-line utility. Password
encryption is supported only for Java programs and the debugger, not for COBOL
programs.

When EGL generates output files, it automatically encrypts passwords in property


files and literals that are passed to system functions. For example, here is a call to
the sqlLib.connect system function:
sqlLib.connect(myDatabase, myUserid, "myPassword");

146 EGL Programmer’s Guide


Because the password parameter is specified as a string literal, it is automatically
encrypted in the generated code.

However, if you hard-code your password in a place other than the function call,
EGL does not encrypt the password:
myPasswordVariable string = "myPassword";
sqlLib.connect(myDatabase, myUserid, myPasswordVariable);

In this case, the password is not encrypted and is displayed in the generated
source.

You can manually encrypt your password by running the command-line utility and
using the returned encrypted value in your code:
myPasswordVariable string = "crypto:abcdef12345";
sqlLib.connect(myDatabase, myUserid, myPasswordVariable);

Following are some places where you might need to manually encrypt hard-coded
passwords:
v Variables in which you store passwords
v CallLink element properties, such as ctgKeyStorePassword
v Calls to system functions, such as sqlLib.connect, sysLib.setRemoteUser, or
VGLib.connectionService in which you do not pass the password as a literal in
the function call

When an EGL system function receives a password with the crypto: prefix, it
decrypts the password automatically. For this reason, you must encrypt any
passwords beginning with the characters crypto:; otherwise, EGL will attempt to
decrypt the non-encrypted password.

Follow these steps to encrypt a password:


1. Add your Java executable to the system’s path:
a. Obtain and install a Java SDK if you do not already have one. IBM offers a
Java SDK for download at the following Web site: http://www.ibm.com/
developerworks/java/jdk/.
b. In your system’s PATH environment variable, add the location of the Java
SDK. See your operating system’s documentation for instructions.
2. Open a command prompt.
3. Navigate to the following location:
shared_resources\plugins\
com.ibm.etools.egl.java.runtime_version
shared_resources
The shared resources directory for your product, such as C:\Program
Files\IBM\SDP70Shared on a Windows system or /opt/IBM/SDP70Shared on
a Linux system. If you installed and kept a previous version of an IBM
product containing EGL before installing your current product, you may
need to specify the shared resources directory that was set up in the earlier
install.
version
The installed version of the plugin, including three numbers separated by
periods, a string separator, and the date and time that the plugin was built;
for example, 7.0.0.RFB_20070120_1300. If more than one is present, use the
one with the most recent version number, unless you have a reason to use
an older version.

Working with EGL code 147


4. Type the following command to invoke the program:
java -classpath fda7.jar com.ibm.javart.security.PasswordEncrypter

The program displays the prompt Enter text to encrypt:.


5. Type your password and press Enter. The program returns an encrypted string
beginning with the prefix crypto:.
6. Copy the entire returned string, including the crypto: prefix, into places in
which you would ordinarily hard-code your password.
7. Save the changed files and regenerate the project.
Related tasks
“Common programming tasks” on page 127
These topics contain information on how to complete several common
programming tasks in EGL.

Handling errors
With EGL, you can decide how your program behaves in case of errors.

Handling errors means anticipating the kinds of problems that might occur in your
program and providing a code path for each of them. If you decide not to handle
errors, all but the most trivial (see ″I/O errors″ later in this topic) will cause your
program to terminate.

Error handling in EGL grows out of the concept of the exception, which is a
stereotype that applies to a record. EGL has a number of predefined exceptions
(see ″EGL Exception records″ in the appendix to the EGL Language Reference), or
you can define your own. Each exception record contains at least these fields:
messageID
A STRING that contains the EGL message for the exception. For example,
if you try to use an uninitialized array, EGL sets the messageID in the
NullValueException record to EGL0106E.
message
A STRING that contains a brief explanation of the problem. For example,
the message that goes with messageID EGL0106E is ″A null reference was
used.″

The exception record can contain additional fields where appropriate. For example,
the IndexOutOfBoundsException has an additional field for indexValue, which
contains the value of the array index that EGL could not process.

The try block


The EGL try keyword introduces a block of code in which you can catch and
handle exceptions. If an exception occurs inside a try block, EGL looks for an
onException statement within the try block that matches the exception type. Each
onException statement includes the declaration of an exception variable. This is a
record variable similar to variables that you declare elsewhere in EGL; the
declaration looks something like the following:
onException(myEx NullValueException)

This means that if EGL throws a NullValueException inside this try block, you can
access fields in that exception record. For example, you can find the EGL message
ID in myEx.msgID, as in the following example:

148 EGL Programmer’s Guide


try
intArray[10] = 0; // this may not be initialized
onException(myEx NullValueException)
writeStdErr(myEx);
myErrorHandler(myEx);
end

The myErrorHandler() function could, for example, take care of initializing the
array and perform the assignment again.

A special type of exception, AnyException, is available to catch any exception and


is comparable to the ANY primitive type. You declare a record variable for
AnyException, and if EGL throws an exception, your variable takes on the type of
the actual exception record. Consider the following example:
try
get next mySerialRecord
onException(myEx AnyException)
myErrorHandler(myEx);
end

If you had a specific code path that you wanted to follow if EGL throws a
FileIOException, you could add a special check for that as follows:
try
get next mySerialRecord
onException(myEx FileIOException)
myErrorHandler1(myEx);
onException(myEx AnyException)
myErrorHandler2(myEx);
end

Here, myErrorHandler2() deals with any exception other than a FileIOException.

If EGL throws an exception but no onException block catches the exception, the
function ends immediately and control returns to the function that called the
function that threw the error. In this way, EGL passes the exception upward until a
function catches the exception with an onException block or the exception reaches
the main function. If the main function fails to catch the exception, the program
ends immediately and writes the message field of the exception to the log. When
an exception occurs in a remotely called program, the calling program receives an
InvocationException rather than the original exception. Similarly, an exception in a
service function delivers a ServiceInvocationException to the calling program.

In other words, a function can catch exceptions thrown in functions it calls, as in


this example:
function FuncOne(myRec serialRecordType)
try
FuncTwo(myRec);
onException(myEx AnyException)
myErrorHandler2(myEx);
end
end

function FuncTwo(myRec serialRecordType)


get next myRec;
end

Exceptions do not pass from function to function like this in V6 exception


compatibility mode, explained below.

Working with EGL code 149


Hard and soft I/O errors
When you are reading or writing to a file, EGL makes a distinction between hard
and soft I/O errors. The following errors are considered soft, that is, not likely to
cause a loss of data:
Table 27. Soft I/O errors
Error Meaning
duplicate For an indexed or relative record, this error indicates
a second record has the same key.
endOfFile For a serial, indexed, or relative record, this error
indicates an attempt to read past the end of the file.
noRecordFound For any record type, the error indicates an attempt to
read a record that could not be found.

Other errors, such as an invalid file format or a full file, are considered hard errors.
A hard I/O error on an indexed, relative, or serial file throws a FileIOException. A
hard I/O error on an SQL database throws an SQLException.

Soft I/O errors associate the error value with record, but do not cause an exception
to be thrown. To test for this situation, use the is or not operator. You do not have
to place the I/O statement in question inside a try block to use these operators.
However, unless you put the I/O statement inside a try block, you cannot check at
the same time for hard I/O errors:
while(TRUE) // endless loop
try
get next mySerialRecord;
if(mySerialRecord is endOfFile)
exit while;
end
onException(myEx AnyException)
myErrorHandler(myEx);
end
end

throwNrfEofExceptions property
By default, the throwNrfEofExceptions program property is set to NO, which
means that the program continues after the soft I/O errors noRecordFound and
endOfFile, even if the error occurs outside of a try block, as in the following
example:
get myCustomer;
if(myCustomer is noRecordFound)
add myCustomer;
end

However, you may prefer to have EGL throw an exception when one of these
errors occurs. You can do so by setting the throwNrfEofExceptions program
property to YES. In that case, EGL throws one of the following exceptions:
v If you are performing file I/O, EGL throws a RuntimeException.
v If you are performing SQL I/O, EGL throws an SQLException.
You must catch this error in a try block, or the program will terminate. Using the
previous example, if no record is found for the get statement, the program
terminates. However, either of the following techniques enables you to handle the
exception:
v Continue after the soft error:

150 EGL Programmer’s Guide


try
get myCustomer;
end

if (myCustomer is noRecordFound)
add myCustomer;
end
v Catch the exception, which is the preferred technique:
try
get myCustomer;
onException (myEx FileIOException)
if (myCustomer is noRecordFound)
add myCustomer;
else
myErrorHandler(myEx);
end
end

Throwing your own exceptions


Using an EGL throw statement, you can throw any of the predefined system
exceptions. As in exception handling, you must declare a variable based on the
record:
nullEx NullValueException{};
...
throw nullEx;

In addition to the exceptions that the system defines, you can create your own
exception records. As with other records, you must define a Record part first, and
then declare a variable based on it.
Record CustomerException type Exception
customerNumber INT;
end
...
throw new customerException {
customerNumber = custNum,
message = "Illegal customer number" };

Custom exceptions records like this one automatically include the messageID and
message fields, just like the system exception records.

V6 exception compatibility
For compatibility with earlier versions, you can still use the error handling
methods from version 6 of EGL.

You specify V6 exception mode on a program-by-program basis when you set the
program’s v60ExceptionCompatibility property to YES. However, for best results
use the same setting for all of your programs.

V6 exceptions are typically handled through a try block. The difference is that V6
exceptions allow only a single onException statement, and do not specify an
exception type. The behavior is thus the same as if the onException statement had
an implied AnyException modifier:
try
posNum = abs(myVar);
onException
if(sysVar.errorCode = "00000008") // invalid input
myErrorHandler1();
if(sysVar.errorCode = "00000012") // cannot assign value

Working with EGL code 151


myErrorHandler2();
else
myErrorHandler3();
end

Instead of being based on exception records, V6 exception compatibility relies on


the sysVar.errorCode system variable. If you are running in V6 exception mode,
sysVar.errorCode is set in the following cases:
v At the completion of a call statement
v After a call to a service
v After a file I/O statement such as get or replace
v After invoking many of the EGL system functions
In addition, for SQL I/O errors, V6 exception compatibility relies on the system
variables in sysVar.sqlData.

You do not need a try block to access sysVar.errorCode in V6 exception mode if


you have the vgVar.handleSysLibraryErrors system variable (for functions in
system libraries) or vgVar.handleHardIOErrors (for file and SQL I/O) set to 1:
vgVar.handleSysLibraryErrors = 1;
posNum = abs(myVar);
if(sysVar.errorCode == "00000008") // invalid input
myErrorHandler1();
else
if(sysVar.errorCode == "00000012") // cannot assign
myErrorHandler2();
else
exit program (-1);
end
end

If, however, vgVar.handleSysLibraryErrors is set to 0 (the default) and you do not


use a try block to catch exceptions, any exception will cause the program to
terminate.

For more information, see Exception handling.


Related tasks
“Common programming tasks” on page 127
These topics contain information on how to complete several common
programming tasks in EGL.
Related reference
EGL core Exception records
I/O error values
throwNrfEofExceptions
handleSysLibraryErrors

Customizing runtime messages


When an error occurs at Java run time, an EGL system message is displayed by
default. You can specify a customized message for each of those system messages
or for a subset of messages.

The customized messages are stored in a properties file that you identify in the
vgj.messages.file Java runtime property. This property is set with the
userMessageFile build descriptor option. For more information about the format of
a Java properties file, see Program properties file.

152 EGL Programmer’s Guide


When a message is required, EGL first searches the properties file specified in
vgj.messages.file. EGL compares the message ID of the required message to the
IDs of the messages in the properties file. If EGL finds a message in the properties
file with a matching ID, it uses that message. If there is no message in the
properties file with a matching ID, EGL uses the default system message. You can
also use the sysLib.getMessage system function to return a message from the
properties file specified in vgj.messages.file.

In many cases, a system message includes placeholders for the message inserts that
EGL retrieves at run time. For example, if your code submits an invalid date mask
to a system function, the message has two placeholders; one (placeholder 0) for the
date mask itself, the other (placeholder 1) for the name of the system function. In
properties-file format, the entry for the default message is as follows:
EGL0049E = Overflow when assigning {0} to {1}.

You can change the wording of the message to include all or some of the
placeholders in any order, but you cannot add placeholders. Valid examples are as
follows:
EGL0049E = Tried to assign {0} to {1} and failed.

EGL0049E = {1} = {0} : Overflow on assignment.

The program terminates if the file that is identified in the vgj.messages.file


property cannot be opened.

Other details are available in Java language documentation:


v For details on how messages are processed and on what content is valid, see the
documentation for the Java class java.text.MessageFormat.
v For details on handling characters that cannot be directly represented in the ISO
8859-1 character encoding (which is always used in properties files), see the
documentation for the Java class java.util.Properties.

Creating a customized message file


You can create a properties file that contains customized messages that are shown
when errors occur at Java run time. These messages replace the default system
messages.
1. To create a properties file for the customized messages:
a. In the Project Explorer view, right-click the Java Resources folder of your
EGL project.
b. Click New → Other.
c. In the New window, expand General and click File.
d. Click Next.
e. In the Enter or select the parent folder field, ensure that your project’s Java
Resources folder is selected.
f. In the File name field, type a name for the properties file, ending in
.properties. An example of a valid file name is messages.properties.
g. Click Finish. The new file is created and opens in the editor.
2. To add customized messages to the messages file:
a. Find the message ID of the system message you want to replace, or create a
new message ID if you are adding a new message.

Working with EGL code 153


The documentation contains information about the system messages, their
message IDs, and any placeholders in the message. See
../../com.ibm.egl.messages.doc/topics/rjavrun0001.dita.
b. Add a line to the messages file in the following format:
messageID = customMessage
messageID
The ID of the system message.
customMessage
The custom message to display in place of the system message,
including any placeholders in the message.
For example, the following properties file line replaces the system message
ID EGL0049E, which by default is Overflow when assigning {0} to {1}.:
EGL0049E = Tried to assign {0} to {1} and failed.
In this example, the code strings {0} and {1} are placeholders for message
inserts that EGL retrieves at run time. These placeholders are optional in
your customized message.
c. When you are finished adding messages, save and close the messages file.
3. Set the genProperties build descriptor option to GLOBAL or PROGRAM.
4. Using one of the following methods, specify the messages file:
v Set the userMessageFile build descriptor option to specify name of the
messages file without the .properties extension. For example, if the
messages file is named messages.properties, set the userMessageFile build
descriptor option to messages.
The userMessageFile build descriptor option sets the vgj.messages.file Java
runtime property, the runtime property that specifies the message file. This
method applies to any type of EGL project.
v Set the vgj.messages.file Java runtime property in the J2EE deployment
descriptor (not the EGL deployment descriptor) to specify the name of the
messages file. This method applies only to projects used within the J2EE
framework. To set the vgj.messages.file runtime property in the J2EE
deployment descriptor, follow these steps:
a. In the Project Explorer view, double-click the project’s J2EE deployment
descriptor. The deployment descriptor opens in the deployment
descriptor editor.
b. Click the Variables tab.
c. Under Environment Variables, click Add. The Add Environment Entry
window opens.
d. In the Name field, type vgj.messages.file.
e. In the Type field, select String.
f. In the Value field, type the name of the messages file without the
.properties extension. For example, if the messages file is named
messages.properties, type messages.
g. Click Finish.
v Set the vgj.messages.file property in the file rununit.properties to specify the
name of the messages file. This method applies only to projects used within
the J2EE framework. To set the vgj.messages.file runtime property in the file
rununit.properties, follow these steps:
a. Open the file rununit.properties in the Java Resources folder. This file is
created the first time that you generate a file with the genProperties
property set to GLOBAL. If you generate with genProperties set to PROGRAM,

154 EGL Programmer’s Guide


the properties file is named pgmNameOrAlias.properties and is located in
the Java package of the generated program.
b. In the properties file, add the following code:
vgj.messages.file = messageFileName
c. Replace messageFileName with the name of the name of the messages file
without the .properties extension. For example, if the messages file is
named messages.properties, type vgj.messages.file = messages.
d. Save and close the properties file.
5. If you want to localize messages into other languages, create additional
properties files for those languages:
a. Create new properties files for each language you want to provide, adding a
locale suffix to the new files to represent their language. For example, if
your original properties file was named messages.properties, a file with
messages in German might be named messages_de.properties. For more
information on locales, see “Locales for resource bundles” on page 431.
b. In each new file, repeat the message IDs that you used in the first
properties file.
c. In the new files, translate the text of the message, without changing the
message ID.
d. Set the application to use the specified language by either generating with
the targetNLS build descriptor option to the name of the language or by
setting the language with the sysLib.setLocale() system function.
6. Generate any EGL file in the project.
Related concepts
Program properties file
Related tasks
“Localizing text in Web applications” on page 426
Related reference
EGL Java runtime error codes
Overview of Java runtime properties
errorCode
getMessage()
userMessageFile

The EGL editor


The EGL code editor looks and works like a standard text editor or code editor for
other languages, but it has additional features to help you edit EGL code. The code
editor highlights invalid syntax, provides an explanation for problems in the code,
colors keywords, strings, and comments, and helps you write EGL code.

The basics

You can open an EGL source file in the EGL editor either by double-clicking it in
the Project Explorer view or by right-clicking it and then clicking Open with →
EGL Editor.

The editor uses many of the same editing functions as the other text and code
editors in the workbench:
v Cut, copy, and paste code with commands in the Edit menu.

Working with EGL code 155


v Save the current file by pressing CTRL+S, clicking the Save button on the
toolbar, or clicking File → Save.
v Generate the current file by pressing CTRL+G or right-clicking the file in the
Project Explorer view and then clicking Generate.
v Undo your most recent change by pressing CTRL+Z or by clicking Edit → Undo.
v Switch between open files, by clicking the tabs at the top of the editor.
v Locate the file in a different view by clicking Navigate → Show In and then click
Project Explorer, Outline, or Navigator.
v To indent or outdent code, select one or more lines, right-click, and then click
Shift Right or Shift Left.
v To comment or uncomment one or more lines of code, select one or more lines,
right-click, and then click Comment or Uncomment.

Some functions of the editor require that you select one or more lines of code
(sometimes referred to as a block of code). You can select code in any of these ways
v Click and drag the mouse over one or more lines of code.
v Double-click a single word to select that word.
v Put the cursor at the beginning of a code block, hold the Shift key, and use the
arrow keys to move the cursor to the end of the block. Also, you can
double-click at the beginning or end of a code block to select the entire code
block.
v Press Ctrl+A to select the entire file.

You can control how EGL code is displayed in the editor. See “Setting preferences
for EGL text” on page 180.

Writing code faster

The main tool that the EGL editor provides to speed up code development time is
code assist. Code assist searches for valid keywords, variables, or part names that
begin with the first few characters that you type and the matching code. To
activate code assistance, press CTRL+Space and choose a keyword, variable, part,
or function from the list of options. You can also type the first few characters of a
keyword, part, or variable to filter the list. See “Content assist” on page 157.

Code assist can also insert larger code templates into your code, such as a
framework for a part. See “Code templates” on page 158.

The editor also includes wizards that can generate EGL code into the file you are
editing. For example, the DataItem part source assistant can help you set the
properties for a DataItem part. See “Editing DataItem parts with the source
assistant” on page 167.

Getting help

The editor provides dynamic help for most EGL keywords. To activate dynamic
help, highlight an EGL keyword, such as package, and press F1. Additionally, the
F1 key provides dynamic help when you are in most EGL-related wizards and
windows.

156 EGL Programmer’s Guide


Organizing code

The EGL editor can help organize your import statements. To organize import
statements, right-click in the editor and then click Organize Imports. The editor
changes your import statements in the following ways:
v The editor arranges the import statements in the order specified in the Organize
Imports preference page. See “Setting preferences for organizing import
statements in the EGL editor” on page 178.
v The editor removes any unused import statements.
v The editor combines multiple import statements to the same package into a
single import statement with a wildcard character, based on the settings in the
preference page.
v The editor attempts to add import statements for any parts that are used in the
file but are not in scope.

With the editor, you can also ″fold″ code. Folding a block of code hides that code
temporarily, so that you can see only the parts of the source file that you want to
see. To fold a block of code, click the minus icon on the left side of the editor; the
code collapses temporarily. You can also fold arbitrary lines of code by selecting
them, right-clicking, and then clicking Fold Text. Click the icon again to restore the
code. Folding does not change the behavior of your code in any way.

Depending on the folding preference settings, certain blocks of code may be folded
automatically when you open a source file in the editor. See “Setting preferences
for folding in the EGL editor” on page 176.

Customizing the EGL editor

The formatting preferences affect how the code is formatted in the editor, including
what characters and how many characters to use for indentation, whether to use
upper or lower case for keywords, and how much white space to include in the
source code.

You can create one or more EGL editor profiles using the EGL Editor Formatter
preference. There are two formatting profiles defined within EGL:
v EGL [build in]
v VA Gen [build in]
You cannot change the formatting preferences within these two profiles or remove
these profiles. Any profile that you create is added to the list of available profiles.
You can change or remove any profile that you create.

See “Setting preferences for formatting in the EGL editor” on page 177 for defining
editor profile preferences.
Related tasks
“Working with EGL code” on page 127

Content assist
The EGL content assist is a tool that you can use to complete programming
statements without having to type the entire statement. It provides a way to
quickly insert an EGL keyword, function, variable, property, or code template.

Working with EGL code 157


When you initiate the content assist, it presents all of the available keywords that
are legal at that position, which may be a long list. However, you can control the
amount of information that is displayed when you initiate the content assist. You
can filter the displayed information by entering the beginning characters of the
function that you want to insert and then initiate the content assist. For example, if
you are looking for program, type pr and press Ctrl+Space. The displayed list will
contain those commands, templates, and code statements that begin with pr. You
can narrow the list more by increasing the number of characters that you type for
the search argument (for example, type progr).

To use the content assist, do the following steps:


1. Within an EGL source file, press Ctrl + Space. The content assist displays a list
of EGL keywords and code templates legal at your current position.
To reduce the number of items in the list, type at least one character of the
keyword or template you are searching for before or after activating the content
assist.
2. Select the desired code from the list by doing one of the following:
v Use the arrow keys to select an option and press Enter.
v Click on an option in the list.
3. The code is inserted into the current location of the cursor. You can then
modify the inserted code.
4. If you inserted a code template with variables rather than a single keyword,
those variables are highlighted in the inserted code temporarily. Press the Tab
key to move to a highlighted variable.

The content assist is context-sensitive. For example, if you are in a set-value block
for a program, the content assist offers only properties that are valid for programs.
You can use the content assist to add additional properties as follows:
1. Type a comma (,) after the last property-value pair.
2. Position the cursor after the comma and press Ctrl+Space to initiate the content
assist. The resulting list shows properties that are both valid for the program
and not yet included in the program.
3. Select the desired code as described above.
Related concepts
“Code templates”
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can
be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.

Code templates
A code template is an outline of code that can be reused. Typically, templates are
used for functions that are routine, such as retrieving data from a data source. To
use a template, that template must be enabled in the code template preferences.

You can create, edit, remove, import, or export a template by using the Preferences
window. If you have modified the list of default templates, you can restore the list
to its default value. You can also restore a removed template if you have not exited
from the workbench since it was removed.

To see the templates, you must type a prefix and then press Ctrl+Space. All
templates whose name begins with that prefix are included in the code assist list,

158 EGL Programmer’s Guide


provided the on-screen cursor is in a position where the code produced by the
template is syntactically allowed. The templates are always at the bottom of the list
for code assist. For example, if the cursor is position in a place where a function is
permitted, and you type w, the webservice_function templates are listed in code
assist. If you select one of the templates, the w is replaced by the code from the
template.

Content and naming considerations for code templates

The that name you give your code templates is significant because that name is the
keyword that represents the code template, not the first word of the code in the
template itself. For example, assume you have created a code template named
″myFunction″ that consists of an EGL function, beginning with the keyword
function. When you want to insert this template, you must begin by typing letters
from the name, such as my or myFunc, not f or fun. Templates are displayed in code
assist only when you have typed at least one character to filter the list of options.

Also, if you begin the code template with an EGL keyword such as function, the
template will be available only when the cursor is in a place where that keyword is
valid. In this case, the function template would be an option only if the cursor is in
a place where a function would be valid. If the beginning of the template is not an
EGL keyword, the template can be inserted anywhere.
Related concepts
“Content assist” on page 157
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can
be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.
Related tasks
“Enabling and disabling code templates”
“Creating code templates” on page 160
“Editing code templates” on page 161
“Removing code templates” on page 163
“Importing code templates” on page 162
“Exporting code templates” on page 162
“Restoring default code templates” on page 163

Enabling and disabling code templates


To limit the list of code templates that is offered to you in the editor, you can
enable or disable specific templates.

To enable code templates in the EGL editor, follow these steps:


1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL → Editor and then click Templates. A list
of templates is displayed.
3. From the Preferences window, select the check box to the left of a template
name that you want to be available in the EGL editor. Similarly, to make a
template unavailable, clear the related check box.
4. To save your changes, click Apply.
5. Click OK to close the window.

To disable code templates in the EGL editor, follow these steps:

Working with EGL code 159


1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL → Editor and then click Templates. A list
of templates is displayed.
3. From the Preferences window, clear the check box to the left of the template
names that you do not want to show in the EGL editor.
4. To save your changes, click Apply.
5. Click OK to close the window.
Related concepts
“Code templates” on page 158
Related tasks
“Creating code templates”
“Importing code templates” on page 162
“Exporting code templates” on page 162
“Removing code templates” on page 163
“Restoring default code templates” on page 163

Creating code templates


You can create your own code template. After the template is created it is shown in
the list of templates.

To create a new code template, follow these steps:


1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL → Editor and then click Templates.
3. From the Preferences window, click New.
4. In the New Template window, specify both a name and a description to
uniquely identify the template. When you want to use the new template, you
will type all or the beginning of the name and then activate code assist. For
more information on naming considerations, see “Code templates” on page 158.
5. In the Pattern field, type the template itself:
v Type any text that you want to display.
v To place an existing variable at the current cursor position, click Insert
Variable, then double-click a variable. When you insert the template in the
EGL editor, each of those variables resolves to the appropriate value.
v To create a custom variable, type a dollar sign ($) followed by a left brace ({),
a string, and a right brace (}), as in this example:
${variable}
You might find it easier to insert an existing variable and change the name
for your own use.
When you insert a custom template in the EGL editor, each variable is
highlighted to indicate that a value is required.
v You can select an area of functionality for the template from the Context list,
but user-defined templates are not filtered by capability like the default
templates are. For user-defined templates, this value is for informational
purposes only.
6. Click OK to create the template.
7. To save your changes, click Apply.
8. Click OK to close the window.
Related concepts
“Content assist” on page 157

160 EGL Programmer’s Guide


“Code templates” on page 158
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can
be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.
Related tasks
“Enabling and disabling code templates” on page 159
“Importing code templates” on page 162
“Exporting code templates” on page 162
“Removing code templates” on page 163
“Restoring default code templates” on page 163

Editing code templates


You can modify existing code templates to fit your specific coding needs.

To edit an existing code template, follow these steps:


1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL → Editor and then click Templates. A list
of templates is displayed.
3. Click the desired template from the table and click Edit.
4. Change the desired fields in the Edit Template dialog box. Click OK when you
are finished.
5. To save your changes, click Apply.
6. Click OK to close the window.

If the code template you edited is one of the templates provided with the product,
you can revert to the original template as follows:
1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL → Editor and then click Templates. A list
of templates is displayed.
3. Click the desired template from the table and then click Revert to Default.
4. To save your changes, click Apply.
5. Click OK to close the window.
Related concepts
“Content assist” on page 157
“Code templates” on page 158
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can
be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.
Related tasks
“Enabling and disabling code templates” on page 159
“Creating code templates” on page 160
“Importing code templates” on page 162
“Exporting code templates” on page 162
“Removing code templates” on page 163
“Restoring default code templates” on page 163

Working with EGL code 161


Exporting code templates
You can export code templates to a file system.

To export code templates, follow these steps:


1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL → Editor and then click Templates. A list
of templates is displayed.

Note: As in other applications on Windows 2000/NT/XP, you can click an


entry to select it; can use Ctrl-click to select or deselect an entry without
affecting other selections; and can use Shift-click to select a set of entries
that are contiguous to the entry you last clicked.
3. Select the desired templates from the table and click Export.
4. Select the location to save the template file in the Exporting Templates window.
You can browse the various locations to locate the place that you want to save
the templates.
5. Click Save to save the templates in the specified location.
Related concepts
“Content assist” on page 157
“Code templates” on page 158
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can
be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.
Related tasks
“Enabling and disabling code templates” on page 159
“Creating code templates” on page 160
“Importing code templates”
“Removing code templates” on page 163
“Restoring default code templates” on page 163

Importing code templates


You can import code templates from a file system. To import code templates,
follow these steps:
1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL → Editor and then click Templates. A list
of templates is displayed.
3. Click Import.
4. Select the location of the template file to be imported in the Importing
Templates window. You can browse the various locations to locate the template
file that you want to import.
5. Select the template file to be imported and click Open.
6. The templates are added to the existing templates.
Related concepts
“Content assist” on page 157
“Code templates” on page 158
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can
be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.

162 EGL Programmer’s Guide


Related tasks
“Enabling and disabling code templates” on page 159
“Creating code templates” on page 160
“Exporting code templates” on page 162
“Removing code templates”
“Restoring default code templates”

Removing code templates


You can remove code templates from the list of available templates. You can restore
the templates if you have not exited the workbench. After you exit the workbench,
the removed templates cannot be restored.

To remove an existing code template, follow these steps:


1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL → Editor and then click Templates. A list
of templates is displayed.

Note: As in other applications on Windows 2000/NT/XP, you can click an


entry to select it; can use Ctrl-click to select or deselect an entry without
affecting other selections; and can use Shift-click to select a set of entries
that are contiguous to the entry you last clicked.
3. In the table, click the templates that you want to remove, and then click
Remove.
4. To save your changes, click Apply.
5. Click OK to close the window.
Related concepts
“Content assist” on page 157
“Code templates” on page 158
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can
be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.
Related tasks
“Enabling and disabling code templates” on page 159
“Creating code templates” on page 160
“Importing code templates” on page 162
“Exporting code templates” on page 162
“Restoring default code templates”

Restoring default code templates


You can reset the code template list to the original list of templates when the
workbench was installed. When restoring the list of code templates any
modifications or templates you created will be removed.

Alternately, you can restore a single code template to the default shipped with the
product. See “Editing code templates” on page 161.

To restore the default code templates, follow these steps:


1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL → Editor and then click Templates. A list
of templates is displayed.

Working with EGL code 163


3. To return to the template list that was in effect at installation time, click Restore
Defaults.
4. To save your changes, click Apply.
5. Click OK to close the window.
Related concepts
“Content assist” on page 157
“Code templates” on page 158
“Code snippets”
Snippets are code objects that are reusable programming objects. Snippets can
be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.
Related tasks
“Enabling and disabling code templates” on page 159
“Creating code templates” on page 160
“Importing code templates” on page 162
“Exporting code templates” on page 162
“Removing code templates” on page 163
“Restoring default code templates” on page 163

Code snippets
Snippets are code objects that are reusable programming objects. Snippets can be a
piece of code or a complete programming task. In addition to the default snippets
provided in the workbench, you can create your own snippets.

The Snippets view provides access to the snippets available for use. The Snippets
view contains several pieces of EGL code, as well as code for many other
technologies. The following table lists the snippets that are available in EGL.
Table 28. Snippets available in EGL
Snippet name Description
Set cursor focus (JSP) A JavaScript function that sets the cursor
focus to a specified form field on a Web
page. See “Setting the focus to a form field”
on page 418.
Auto redirect (JSP) A JavaScript function that tests for the
presence of a session variable. If the session
variable is not present, it forwards the
browser to a different page. See “Testing
browsers for a session variable” on page 425.
Get clicked row value An EGL function that retrieves the
hyperlinked value of a clicked row in a data
table. See “Retrieving the value of a clicked
row in a data table” on page 417.
database update An EGL function that updates a single row
of a relational table when passed a record
from a JSF Handler. See “Updating a row in
a relational table” on page 423.

Related concepts
“Content assist” on page 157
“Code templates” on page 158

164 EGL Programmer’s Guide


Related concepts
Adding snippets from the Snippet view
Snippets view
Related tasks
“Inserting code snippets into EGL and JSP files”
“Setting the focus to a form field” on page 418
The Set cursor focus snippet in the EGL drawer of the Snippets view is a
JavaScript function that sets the cursor focus to a specified form field on a Web
page. It must be placed within a <script> tag in a JSP page.
“Testing browsers for a session variable” on page 425
The Auto redirect snippet in the JSP drawer of the Snippets view tests for the
presence of a session variable. If the session variable is not present, the
customized code forwards control to a different Web page.
“Retrieving the value of a clicked row in a data table” on page 417
The getClickedRowValue snippet in the EGL drawer of the Snippets view is a
function that retrieves the hyperlinked value of a clicked row in a data table.
“Updating a row in a relational table” on page 423
The database update snippet in the EGL drawer of the Snippets view is a
function that updates a single row of a relational table when passed a record
from a JSF Handler. This snippet is intended to be placed in an EGL library.

Inserting code snippets into EGL and JSP files


To insert an EGL code snippet into your code, follow these steps:
1. Open the file to which you want to add a snippet.
2. Open the Snippets view.
a. Click Window → Show View → Other.
b. Expand General and click Snippets.
c. Click OK.
3. In the Snippets view, expand the EGL drawer. This drawer contains the
available EGL code snippets.
4. Use one of these methods to insert a snippet into the file:
v Double-click a snippet to insert that snippet at the current cursor position.
You may see a window describing the variables in the snippet. If so, enter
values for these variables and then click Insert.
v Click and drag a snippet into the source code. This method works only when
putting a snippet on a JSP file.
If you selected a snippet that contains variables, you will be prompted to enter
the variables.

Note: If the cursor turns into a circle with a strike through it, indicating that
the snippet can not be inserted at that point, you may be trying to insert
the snippet into the wrong place. Check the snippet’s details to find out
where it should be inserted in the code.
5. Change the predefined names of functions, variables, and data parts in the
snippet as appropriate to your code. Most snippets include comments that
explain what names need to be changed.
Related concepts
Snippets view
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can

Working with EGL code 165


be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.
Related tasks
“Content assist” on page 157
“Setting the focus to a form field” on page 418
The Set cursor focus snippet in the EGL drawer of the Snippets view is a
JavaScript function that sets the cursor focus to a specified form field on a Web
page. It must be placed within a <script> tag in a JSP page.
“Testing browsers for a session variable” on page 425
The Auto redirect snippet in the JSP drawer of the Snippets view tests for the
presence of a session variable. If the session variable is not present, the
customized code forwards control to a different Web page.
“Retrieving the value of a clicked row in a data table” on page 417
The getClickedRowValue snippet in the EGL drawer of the Snippets view is a
function that retrieves the hyperlinked value of a clicked row in a data table.
“Updating a row in a relational table” on page 423
The database update snippet in the EGL drawer of the Snippets view is a
function that updates a single row of a relational table when passed a record
from a JSF Handler. This snippet is intended to be placed in an EGL library.

Using cheat sheets


Cheat sheets can assist you with common tasks in the Workbench. They provide
step-by-step instructions within a workbench view and can perform some of the
steps in the task automatically.

Follow these instructions to open and use a cheat sheet:


1. Click Help → Cheat Sheets. The Cheat Sheet Selection window opens.
2. Expand EGL and select an EGL cheat sheet.
3. Click OK. The cheat sheet opens in a workbench view.
4. Click Click to Begin to start through the cheat sheet.
5. Follow the steps in the cheat sheet.
As the steps in the cheat sheet expand, they provide the information necessary
to perform each step. Depending on the step, you might need to perform the
step manually or there might be other options available as follows:
v In some cases, the cheat sheet can perform the step or a portion of the step
for you. If this option is available, you can click the Click to Perform link.
For example, the cheat sheet might be able to open a wizard for you, but you
must fill out the wizard to complete the step.
v In some cases, the cheat sheet provides an option to skip a step. If this
option is available and you have already met the criteria, you can click on
the Click to Skip link. For example, if you already have an EGL Web project,
then you can skip the step of creating an EGL Web project.
6. As you complete each step, click the Click to Complete link. The next step in
the cheat sheet expands automatically.

For more information on cheat sheets, see Working with cheat sheets.

EGL offers the following cheat sheets:


Create an EGL Hello World Web application
Creates a simple Web application with EGL.

166 EGL Programmer’s Guide


Create an EGL data access Web application from a database connection
If you already have a connection to a database, you can use this cheat
sheet to connect to the database and create a simple Web application based
on the database schema. This cheat sheet is similar to the method
described in “Creating a data access application” on page 208.
Create an EGL data access Web application from a UML model
If you have a UML model that describes a database, you can use this cheat
sheet to create a transformation parameters file and run the EGL data
access transformation to create an application based on the UML model.
Create a Web service
Creates a simple Web service using EGL.
Create a Web service client
If you have a WSDL file that describes a Web service, you can use this
cheat sheet to create an EGL application that acts as a client for that
service.
Related concepts
“Working with EGL code” on page 127

Editing DataItem parts with the source assistant


Like most parts, DataItem parts can have one or more properties assigned to them.
The source assistant helps you assign the correct properties and values for the
DataItem by displaying only the valid properties for DataItem parts and by
validating the values that you enter for the properties.

To modify DataItem properties, follow these steps:


1. Open an EGL source file.
2. Select the DataItem that you want to edit. The cursor must be on the DataItem.
3. Open the source assistant by using one of these methods:
v Press Ctrl + Shift + Z.
v Right-click the DataItem and then click Source Assistant.
4. In the EGL Source Assistant window, type the name of the DataItem in the
Name field and select the type from the Type field.
5. If the type of DataItem requires a length or a number of decimal places, specify
these values in the Length and Decimals fields. These fields are not available if
the DataItem does not require a length or number of decimal place values.
6. Specify values for the properties of the DataItem. You can switch between
different pages of properties by clicking the tabs below the Type field.
7. When you are finished editing the values, click Validate.
The source assistant validates the values you enter and lists any errors at the
bottom of the window. Correct any errors that are listed in the window and
click Validate again.
8. When there are no more validation errors listed, click OK. The source assistant
closes and updates the DataItem properties to match the properties that you
specified.
9. Save the EGL source file.
Related concepts
“Introduction to data parts” on page 97
Data parts define a structure that stores one or more pieces of data. Data parts
form the basis for a variable that you can use in a logic part.

Working with EGL code 167


Searching for EGL files and parts
The workbench provides several options for searching for and viewing EGL files
and parts.
File Search view
With the File Search view, you can perform a textual search of the entire
workspace or a subset of your files and projects. You type a string and
specify the search scope, and the workbench searches the files for a textual
match. This method of searching is not customized for EGL use; you can
use it for all types of files.
EGL Search view
With the Search view, you can search for EGL parts or references to those
parts. Click Search → EGL from the menu bar and type in a search string.
See “Searching for parts.”
Parts List view
The Parts List view displays a table of EGL parts with details about their
location and type. To use the Parts List view, select one or more EGL files
in the Project Explorer view, right-click the files, and then click Open in
Parts List. See “Viewing lists of parts” on page 169.
Parts Reference view
The Parts Reference view displays all the parts that are referenced by a
single generatable logic part, such as a program. To open the Parts
Reference view, right-click a file containing a generatable logic part in the
Project Explorer view and then click Open in Parts Reference. See
“Viewing part references” on page 171.
Project Explorer view
If you have a file open in the EGL editor and you want to locate that file
in the Project Explorer view, right-click the open file in the editor and then
click Show In → Project Explorer. See “Locating an EGL source file in the
Project Explorer view” on page 172.
Related tasks
“Searching for parts”
You can search for parts among the EGL projects in your workspace.
“Viewing lists of parts” on page 169
You can choose one or more EGL parts and group those parts in a list to filter
or sort them.
“Viewing part references” on page 171
The EGL Parts Reference view shows a hierarchical view of the parts that are
referenced in a generatable logic part, such as functions, parameters, and the
types used to create variables.
“Locating an EGL source file in the Project Explorer view” on page 172

Searching for parts


You can search for parts among the EGL projects in your workspace.

This search returns part definitions and references; it does not search your project
for a text match to a string. For a textual search of your project, click Search → File.

To search for a list of available parts, follow these steps:


1. From the main menu, click Search → EGL. The Search window opens to the
EGL Search tab.

168 EGL Programmer’s Guide


If you do not see Search → EGL, click Search → Search and switch to the EGL
Search tab.
2. Type the criteria for the search in the Search string field. You can use the
following wildcard symbols in your search:
v A question mark (?) represents any one character
v An asterisk (*) represents a series of any characters of any length
For example, type my?Part to locate parts named ″my1Part″ and ″my2Part″, but
not ″my10Part″. Type my*Part to locate parts named ″my1Part″, ″my2Part″, and
″my10Part″. Click the Case sensitive check box for a case-sensitive search.
3. In the Search For section, select the type of part you are searching for, or select
Any element to expand your search to all part types.
4. In the Limit To section, select the option to limit your search to part
declarations, part references, or any occurrence of the search string.
5. In the Scope section, select where to search:
Workspace
Searches the current workspace.
Selected resources
Searches the resources currently selected in the Project Explorer view or
other view.
Enclosing projects
Searches the project or projects that contain the files selected in the
Project Explorer view or other view.
Working set
Searches a set of projects, called a working set. Click Choose to select the
working sets to search.
6. Click Search. The results are displayed in the Search view.
7. If you double-click a file in the Search view, the file opens in the EGL editor,
and the matching part is highlighted. If there is more than one match in the
file, the first match is highlighted.
Arrows in the left margin of the editor indicate the locations of each matching
part.
Related concepts
“Contents of an EGL application” on page 67
This topic describes the artifacts found in a typical EGL application.
“Introduction to EGL parts” on page 95
Parts are the building blocks of EGL applications.
Related tasks
“Viewing lists of parts”
You can choose one or more EGL parts and group those parts in a list to filter
or sort them.
“Viewing part references” on page 171
The EGL Parts Reference view shows a hierarchical view of the parts that are
referenced in a generatable logic part, such as functions, parameters, and the
types used to create variables.
“Locating an EGL source file in the Project Explorer view” on page 172

Viewing lists of parts


You can choose one or more EGL parts and group those parts in a list to filter or
sort them.

Working with EGL code 169


To populate the EGL Parts List view with parts, do one of the following:
v In the Project Explorer view, select one or more EGL resources, such as files,
projects, or packages. Then, right-click the selected resources and click Open in
Parts List.
v In the EGL Parts Reference view, select one or more EGL parts. Then, right-click
the selected parts and click Open in Parts List. This method can be useful for
viewing all the parts that are referenced by another part.

After the EGL Parts List view is open and populated with parts, you can do the
following tasks with the list of parts:
v Double-click a part to open it in the EGL editor.
v Click a column header to sort the list by the part name, type, project, package,
or filename.
v Click the Refresh button at the top right of the view to refresh the information
in the view.
v Open the History list at the top right of the view to return to a list of parts you
have viewed in the EGL Parts List view previously.
v Filter the list of parts with the Filters list at the top right of the view.
v Go to the part in the Project Explorer view by right-clicking it and then clicking
Show in Project Explorer.
v Generate a generatable part by right-clicking it and then clicking Generate or
Generate With Wizard.
v Debug a program by right-clicking it and then clicking Debug EGL Program.
v Open a part in the EGL Parts Reference view by right-clicking a program,
library, handler, or service and then clicking Open in Parts Reference. See
“Viewing part references” on page 171.
v Search for related EGL code by right-clicking on the part, clicking References or
Declarations, and then selecting a scope for the search.

Filtering lists of parts

While viewing a list of parts in the EGL Parts List view, you can filter the list to
include only certain parts:
1. Populate the EGL Parts List view with EGL parts.
2. From the list at the top right corner of the EGL Parts List view, click Filters.
The EGL Parts List Filter window opens.
3. In the EGL Parts List Filter window, set the criteria for the filter:
v To filter by project, folder, package, or file, select or deselect the resources
under Part Resources.
v To filter by type of part, select or deselect the types of parts under Part Type.
v To filter by part name, enter a part name in the Part name filter field. A
question mark (?) represents any one character and an asterisk (*) represents
a series of any characters.
4. When you are finished setting the filter in the EGL Parts List Filter window,
click OK. Only the parts that match the filter criteria are shown in the EGL
Parts List view.
Related concepts
“Introduction to EGL parts” on page 95
Parts are the building blocks of EGL applications.
Related tasks

170 EGL Programmer’s Guide


“Searching for parts” on page 168
You can search for parts among the EGL projects in your workspace.
“Locating an EGL source file in the Project Explorer view” on page 172
“Viewing part references”
The EGL Parts Reference view shows a hierarchical view of the parts that are
referenced in a generatable logic part, such as functions, parameters, and the
types used to create variables.

Viewing part references


The EGL Parts Reference view shows a hierarchical view of the parts that are
referenced in a generatable logic part, such as functions, parameters, and the types
used to create variables.

To open a generatable logic part in the EGL Parts Reference view, right-click the
file that contains the part in the Project Explorer view and then click Open in Parts
Reference. After the part opens in the view, you can expand its hierarchy to see
the parts that are referenced. Alternatively, you can right-click the part in the
Outline view or the EGL Parts List view and then click Open in Parts Reference.

In the EGL Parts Reference view, you can perform several tasks on a part or its
referenced parts:
v Open a part in the EGL editor by double-clicking the part.
v Search for related EGL code by right-clicking on the part, clicking References or
Declarations, and then selecting a scope for the search.

You can also search for parts or text strings among the parts in the view:
1. Right-click the EGL Parts Reference view and then click Find in tree.
The EGL Parts Reference Find window opens.
2. Type a search string into the Search string field.
v A question mark (?) represents any one character
v An asterisk (*) represents a series of any characters
For example, type my?Part to locate parts named ″my1Part″ and ″my2Part″, but
not ″my10Part″. Type my*Part to locate parts named ″my1Part″, ″my2Part″, and
″my10Part″.
3. Choose a search type. Part search searches for EGL parts and Text search
searches for text within the part.
4. Select the options for the search.
v If you selected Part search, you can select a type of part to search for by
clicking a radio button under Search For.
v Under Direction, choose to search Forward or Backward from the currently
selected part.
v To make a text search case-sensitive, select the Case sensitive check box.
v To continue searching from the other end if the search reaches the bottom or
the top of the tree, select the Wrap search check box.
v To search for only a complete part name or text string, select the Whole
word check box.
5. When you are finished setting the criteria for the search, click Find. The first
result of the search is highlighted in the EGL Parts Reference view.
6. To move to the next result, click Find.
7. When you are finished, click Close.

Working with EGL code 171


Related concepts
“Introduction to EGL parts” on page 95
Parts are the building blocks of EGL applications.
Related tasks
“Searching for parts” on page 168
You can search for parts among the EGL projects in your workspace.
“Viewing lists of parts” on page 169
You can choose one or more EGL parts and group those parts in a list to filter
or sort them.
Related reference
“The EGL editor” on page 155
The EGL code editor looks and works like a standard text editor or code editor
for other languages, but it has additional features to help you edit EGL code.
The code editor highlights invalid syntax, provides an explanation for problems
in the code, colors keywords, strings, and comments, and helps you write EGL
code.

Locating an EGL source file in the Project Explorer view


If you are editing an EGL source file, you can quickly locate the file in the Project
Explorer view, Outline view, or Navigator view.

To locate an EGL source file in one of these views, right-click the open file in the
EGL editor and then click Show in → ProjectExplorer. You can also click Show in →
Outline or Show in → Navigator to display where the file is in one of those views.

This menu option does the following tasks:


v Opens the specified view, if it is not already open
v Expands the tree nodes needed to locate the source file
v Highlights the source file
Related tasks
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.
Related reference
“The EGL editor” on page 155
The EGL code editor looks and works like a standard text editor or code editor
for other languages, but it has additional features to help you edit EGL code.
The code editor highlights invalid syntax, provides an explanation for problems
in the code, colors keywords, strings, and comments, and helps you write EGL
code.

Preferences
EGL preferences affect the way the workbench displays and works with EGL.
Related tasks
“Enabling EGL capabilities” on page 11
Capabilities keep the workbench menus from becoming cluttered by hiding
items you do not use. You can always perform these tasks, but to make them
appear in the menus, you must enable the capability for that area of
functionality.
“Enabling and disabling code templates” on page 159
“Setting general preferences” on page 173

172 EGL Programmer’s Guide


“Setting build descriptor preferences” on page 174
“Setting preferences for the EGL debugger” on page 604
This topic tells you how to change your preferences for the EGL debugger.
Setting the default build descriptors
“Setting preferences for the EGL editor” on page 175
“Setting EGL-to-EGL migration preferences” on page 42
“Setting generation preferences” on page 180
“Setting preferences for source styles” on page 179
“Setting preferences for Web projects” on page 465
These preferences control defaults for EGL Web projects and JSF Handler parts.
“Setting preferences for SQL retrieve” on page 220
“Creating an SQL database connection” on page 197
The New Connection wizard creates an SQL database connection that you can
use either at design time or at run time.
“Setting preferences for EGL text” on page 180
“Setting preferences for Rich UI” on page 345
“Setting preferences for the Text Form editor” on page 510
“Setting bidirectional text preferences for the Text Form editor” on page 511
“Setting preferences for the Text Form editor palette entries” on page 512

Setting general preferences


Set the basic EGL preferences as follows:
1. From the main menu, click Window → Preferences.
2. In the Preferences window, click EGL in the tree.
3. In the EGL Base section, select whether VisualAge Generator compatibility is
needed in your environment. Ensure that the VisualAge Generator
compatibility check box is selected if your environment requires compatibility.
4. In the Encoding field, select the character-encoding set that will be used when
you create new EGL build (.eglbld) files. The setting has no effect on existing
build files. The default value is UTF-8.
5. Select features to be enabled by default for a new EGL project in the Default
EGL Project Features Choices.
6. Select facets to be enabled by default for a new EGL Web project in the Default
EGL Web Project Facet Choices section.
7. Click Apply to save the changes and remain in the Preferences window. Click
OK to save the changes and exit the window.
Related concepts
VisualAge Generator compatibility
“Features and facets of EGL projects” on page 76
EGL projects can have additional abilities, added through features and facets.
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related tasks
“Enabling EGL capabilities” on page 11
Capabilities keep the workbench menus from becoming cluttered by hiding
items you do not use. You can always perform these tasks, but to make them
appear in the menus, you must enable the capability for that area of
functionality.

Working with EGL code 173


“Setting preferences for the EGL debugger” on page 604
This topic tells you how to change your preferences for the EGL debugger.
“Setting preferences for the EGL editor” on page 175
“Setting preferences for source styles” on page 179
“Setting preferences for EGL text” on page 180
“Setting preferences for service generation” on page 498
You can set defaults for how your services are generated.

Setting build descriptor preferences


To specify preferences for build descriptors, follow these steps:
1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL and click Default Build Descriptor.
3. In the Preferences window, you can set the following EGL build descriptor
settings:
Target system build descriptor
Sets the default build descriptor for generating code in the workbench.
EGL uses this build descriptor if you do not specify another one for the
project.
Debug build descriptor
Sets the default build descriptor to be used when debugging EGL code
in the workbench. EGL uses this build descriptor if you do not specify
another one for the project.
Update default build options for project when runtime data source is
modified.
This setting controls what happens when you select a database
connection in the EGL Runtime Data Connections properties page for a
project as explained in “Using an SQL database connection at run time”
on page 202.
Prompt
When you select a database connection in the EGL Runtime
Data Connections property page, EGL asks you if you want to
update the build descriptor options in the master build
descriptor for the project.
Always
When you select a database connection, EGL updates build
descriptor options automatically.
Never When you select a database connection, EGL does not update
build descriptor options.
4. Click Apply to save the changes and remain in the Preferences window. Click
OK to save the changes and exit the window.
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related tasks
“Setting general preferences” on page 173
Setting the default build descriptors

174 EGL Programmer’s Guide


Setting preferences for the EGL editor
To specify the EGL editor preferences, follow these steps:
1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL and click Editor.
3. In the Preferences window, you can set the following EGL editor settings:
Show line numbers
Displays the line numbers in the EGL file.
Annotate errors in text
Underlines errors in the source code with a red line. Errors are shown
after saving the file.
Annotate errors in overview ruler
Shows a red error indicator in the right margin of the editor (overview
ruler) whenever an error is found in the source code. Errors are shown
after saving the file.

When the check box next to the setting is clear, the setting is turned off. Click
the check box to turn the setting on.
4. Click Apply to save the changes and remain in the Preferences window. Click
OK to save the changes and exit the window.

There are other pages with additional options for the EGL editor under the EGL
page in the navigation tree. To set these options, see the following topics:
v “Setting preferences for folding in the EGL editor” on page 176
v “Setting preferences for organizing import statements in the EGL editor” on
page 178
v “Setting preferences for source styles” on page 179
v “Enabling and disabling code templates” on page 159
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related tasks
“Enabling EGL capabilities” on page 11
Capabilities keep the workbench menus from becoming cluttered by hiding
items you do not use. You can always perform these tasks, but to make them
appear in the menus, you must enable the capability for that area of
functionality.
“Setting general preferences” on page 173
“Setting preferences for the EGL debugger” on page 604
This topic tells you how to change your preferences for the EGL debugger.
“Setting preferences for folding in the EGL editor” on page 176
Folding enables you to collapse blocks of code in the EGL editor to hide them.
“Setting preferences for organizing import statements in the EGL editor” on
page 178
EGL can automatically organize the import statements in your code.
“Setting preferences for source styles” on page 179
“Setting preferences for EGL text” on page 180
“Setting the fonts used in the EGL editor” on page 176
The EGL editor uses the fonts and colors from the general preferences in the
workbench.

Working with EGL code 175


Related reference
“Content assist” on page 157
“Code templates” on page 158

Setting the fonts used in the EGL editor


The EGL editor uses the fonts and colors from the general preferences in the
workbench.

To change the fonts and colors used in the EGL editor, follow these steps:
1. Click Window → Preferences.
2. In the Preferences window, click General → Appearance → Colors and fonts.
3. On the Colors and Fonts page, expand EGL and click EGL Editor Text Font.
4. Click Change.
5. In the Font window, select the font to use in the EGL editor, including the
typeface, size, and color.
6. Click OK.
7. If you want to restore settings, you can click Reset to return to the defaults for
the workbench, and you can click Use System Font to use your computer’s
default font.
8. Click OK to close the Preferences window.
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related tasks
“Setting preferences for the EGL editor” on page 175
“Setting general preferences” on page 173

Setting preferences for folding in the EGL editor


Folding enables you to collapse blocks of code in the EGL editor to hide them.

Folding has no effect on EGL source code or generated source; it is only a tool to
view the active parts of your source code while hiding parts that you are not
currently working with.

To set folding preferences:


1. From the main menu, click Window → Preferences.
2. In the Preferences window, expand EGL → Editor and click Folding.
3. On the Folding page of the Preferences window, select the Enable folding
check box to enable the EGL editor to collapse sections of your code.
4. Under Initially fold these elements, select the check boxes next to the sections
of EGL code that you want the editor to fold automatically when you open a
file.
5. In the Number of property block lines needed to enable folding field, enter
the minimum number of lines in a block of properties that you want to be able
to fold. If you select the Properties Block check box, EGL will automatically
fold blocks of properties of the given size or larger.
6. Click Apply to save the changes and remain in the Preferences window. Click
OK to save the changes and exit the window.
Related concepts

176 EGL Programmer’s Guide


“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related tasks
“Enabling EGL capabilities” on page 11
Capabilities keep the workbench menus from becoming cluttered by hiding
items you do not use. You can always perform these tasks, but to make them
appear in the menus, you must enable the capability for that area of
functionality.
“Setting preferences for the EGL editor” on page 175
“Setting preferences for organizing import statements in the EGL editor” on
page 178
EGL can automatically organize the import statements in your code.

Setting preferences for formatting in the EGL editor


To specify the EGL editor formatting preferences, follow these steps:
1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL and click Editor → Formatter.
3. In the Formatter window, you can add, change, or remove editor formatting
profiles.
v To create a new profile, click New and select the features for the profile on
the Edit Profile window.
v To work with an existing profile, select the profile from the drop-down list
and click Edit to change the settings defined in the profile. Click Rename to
change the name of the profile.
v To remove a profile, select the profile and click Remove.
Related concepts
“The EGL editor” on page 155
The EGL code editor looks and works like a standard text editor or code editor
for other languages, but it has additional features to help you edit EGL code.
The code editor highlights invalid syntax, provides an explanation for problems
in the code, colors keywords, strings, and comments, and helps you write EGL
code.
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related tasks
“Enabling EGL capabilities” on page 11
Capabilities keep the workbench menus from becoming cluttered by hiding
items you do not use. You can always perform these tasks, but to make them
appear in the menus, you must enable the capability for that area of
functionality.
“Setting general preferences” on page 173
“Setting preferences for the EGL debugger” on page 604
This topic tells you how to change your preferences for the EGL debugger.
“Setting preferences for folding in the EGL editor” on page 176
Folding enables you to collapse blocks of code in the EGL editor to hide them.
“Setting preferences for organizing import statements in the EGL editor” on
page 178
EGL can automatically organize the import statements in your code.
“Setting preferences for the EGL editor” on page 175
“Setting preferences for source styles” on page 179

Working with EGL code 177


“Setting preferences for EGL text” on page 180
Related reference
“Content assist” on page 157
“Code templates” on page 158

Setting preferences for organizing import statements in the


EGL editor
EGL can automatically organize the import statements in your code.

Organizing import statements involves reordering and grouping the statements by


the package name. Also, EGL removes unnecessary import statements from your
code.

Follow these steps to set preferences for organizing the import statements in your
code:
1. From the main menu, click Window → Preferences.
2. In the Preferences window, expand EGL → Editor and click Organize Imports.
3. On the Organize Imports page of the Preferences window, set the order for
import statements in the list of package names:
v To add a new package or prefix to the list, click New and type the new
name. You can use the asterisk character as a wild card at the end of the
package name.
v To reorder the packages and prefixes, click a package or prefix in the list to
select it and then click Up or Down.
4. In the Number of imports needed field, enter the minimum number of
individual import statements in the same package to simplify into an import
statement with a wild card character.
For example, your file might have the following similar import statements:
import com.mypackage.myPart1;
import com.mypackage.myPart2;
import com.mypackage.myPart3;

If you set the Number of imports needed field to 3, the editor will simplify
these import statements into the following single import statement:
import com.mypackage.*;
5. Click Apply to save the changes and remain in the Preferences window. Click
OK to save the changes and exit the window.

To organize your import statements, open a source file in the editor, right-click the
file, and then click Organize Imports. Alternatively, you can organize the import
statements for every file in a project or package by right-clicking the project or
package in the Project Explorer view and then clicking Organize Imports.
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related tasks
“Enabling EGL capabilities” on page 11
Capabilities keep the workbench menus from becoming cluttered by hiding
items you do not use. You can always perform these tasks, but to make them
appear in the menus, you must enable the capability for that area of
functionality.

178 EGL Programmer’s Guide


“Setting preferences for the EGL editor” on page 175
“Setting preferences for folding in the EGL editor” on page 176
Folding enables you to collapse blocks of code in the EGL editor to hide them.

Setting preferences for source styles


You can change how EGL code is displayed in the EGL editor:
1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL → Editor and click Source Styles.
3. The Source Styles page of the Preferences window shows the following EGL
style preferences:
Background color
Select one of the following options to define the background color in
the EGL source file:
System Default
Use the colors currently defined as part of the system
configuration.
Custom
Click the radio button to select a color from the color palette.
The color palette is displayed when clicking the button next to
the Custom label. After you have selected a color, click OK to
save your choice. The color is shown in the Preview field.
Element
Select the color for each element of source data in your file. You can
also make the data bold. To set a color, follow these steps:
a. Select the type of text in the Element list.
b. Click the box next to the Color label. A color palette is displayed.
c. Select the desired color and click OK.
d. Click the check box for the Bold field to bold the text.
Repeat the steps for each type of text. The results are shown in the
Preview box.
4. Click Apply to save the changes and remain in the Preference window. Click
OK to save the changes and exit the window.
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related tasks
“Enabling EGL capabilities” on page 11
Capabilities keep the workbench menus from becoming cluttered by hiding
items you do not use. You can always perform these tasks, but to make them
appear in the menus, you must enable the capability for that area of
functionality.
“Setting general preferences” on page 173
“Setting preferences for the EGL debugger” on page 604
This topic tells you how to change your preferences for the EGL debugger.
“Setting preferences for the EGL editor” on page 175
“Setting preferences for EGL text” on page 180

Working with EGL code 179


“Setting the fonts used in the EGL editor” on page 176
The EGL editor uses the fonts and colors from the general preferences in the
workbench.

Setting generation preferences


To specify preferences for EGL generation, follow these steps:
1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL and click Generation.
3. In the Generation window, you can set the following preferences:
Build before generate
If you select this check box, EGL builds the project automatically prior
to generation if it has not been built since the last change. This
preference takes effect only when the workbench is not set to build the
project automatically.
Auto generate
If you select the check box next to a type of part, EGL will generate
that part automatically each time you save a file that contains that type
of part. Clearing these check boxes improves workbench performance
because you will not have to wait for EGL to generate the parts each
time you save. However, if you clear the check boxes, you must
remember to generate the appropriate files manually before running
your application.
Generation Destination User Information
If you are generating code to a computer other than this one, type the
user ID and password for the computer on which the generated code is
saved. These fields behave like default values for the destUserID and
destPassword build descriptor options. The values of these build
descriptor options take precedence over the settings in the Preferences
window.
4. Click Apply to save the changes and remain in the Preference window. Click
OK to save the changes and exit the window.
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Introduction to EGL generation
Related reference
destUserID
destPassword

Setting preferences for EGL text


To change how text is displayed in the EGL editor, follow these steps:
1. From the main menu, click Window → Preferences.
2. In the navigation tree, expand General → Appearance and then click Colors
and Fonts.
3. In the Colors and Fonts window, expand EGL in the tree and then click EGL
Editor Text Font.
4. Click Change.
5. In the Font window you can specify one or more of the following settings:
v Type or select a font style in the Font field.

180 EGL Programmer’s Guide


v Type or select a font style in the Font style field.
v Type or select a font size in the Size field.
v Type or select a color in the Color field.
v Select the Strikeout check box if you want a line to run through the middle
of the text.
v Select the Underline check box if you want a line under the text.
You can see a preview of your selections in the Sample section. When you are
finished making your selections, click OK.
6. To use the default operating system font, click the Use System Font button.
7. To use the default workbench font, click the Reset button.
8. To set the font for all editors (not just the EGL editor) to the default workbench
font, click the Restore Defaults button.
9. Click Apply to save the changes and remain in the Preference window. Click
OK to save the changes and exit the window.
Related tasks
“Setting preferences for the EGL editor” on page 175
“Setting preferences for source styles” on page 179

Working with EGL code 181


182 EGL Programmer’s Guide
Accessing data with EGL code
If your program is going to store any of the information that it works with, it
needs to use a file. If you plan to work with large amounts of information,
typically you use a database or other type of data source for storage and retrieval.
Commercial software (such as IBM DB2) helps you manage the information that
you store in the database

The most common type of database is the relational database. In very simple terms,
the information in a relational database resides in tables that can refer to each
other. A relational database management system (RDBMS) keeps track of the tables
and relationships. You use a special language, called SQL, to communicate with the
database manager. Some popular types of RDBMS include IBM DB2, Microsoft®
SQL Server, Oracle, and the open-source MySQL.

In the mainframe world, it is still common to see hierarchical databases. A


hierarchical database contains a tree-like structure, where segments (equivalent to
tables) can have a parent segment (only one each) and multiple child segments.
IMS is an example of a hierarchical database manager, which you can talk to
through the DL/I language.

Another option is to use a lower level data structure that is provided by your
operating system. Using this type of data source enables you to manage more of
the details of data storage and retrieval yourself. IBM MVS™ systems use a file
access method called VSAM (Virtual Storage Access Method) that enables you to
write directly to several different types of file, including plain sequential access
files and indexed files (which keep track of data by means of a key).

The EGL strategy is to provide a few basic commands (like get, which fetches
information and puts it into a record) that focus on business logic rather than
implementation details. For an overview of how this works, see “Reading and
writing records” on page 184.
Related tasks
“Reading and writing records” on page 184
“Creating a data access application” on page 208
EGL can create a simple data access application based on a database to which
you are connected. The resulting application contains data parts, logic parts and
(optionally) Web pages that are based on one or more database tables.
“Viewing implicit SQL statements” on page 217

Common data access tasks


EGL helps you perform common data processing tasks such as reading and writing
to files, while protecting you from the implementation details.

The goal of information processing is to transform data (raw facts and figures) into
information (data that means something and increases knowledge). Common
processes include:

© Copyright IBM Corp. 1996, 2008 183


Retrieval
EGL uses the get statement (and its variants) to read data from files,
databases, and message queues. For more details, see “Reading and
writing records.”
Processing
What you do with the data you receive—whether retrieved from storage or
input through a user interface (UI)—depends on your business processes.
For example, you might be receiving orders from a Web site, generating
picking tickets for your warehouse, and making adjustments to inventory
and customer balances.
Storage
EGL uses the add and replace statements to modify existing data in
storage. For more details, see “Reading and writing records.”
Reporting and analysis
EGL can present reports that include everything from checks and invoices
to general ledgers and Web statistics. EGL uses the JasperReports
open-source reporting package to provide this functionality. For more
details, see “Creating reports with EGL” on page 531.
Related concepts
“Creating reports with EGL” on page 531
EGL offers different ways to create reports, using external engines to generate
the report contents.
Related tasks
“Reading and writing records”

Reading and writing records


The acronym CRUD refers to the basic I/O functions that you typically perform on
records within a file. The following table shows the CRUD functions and the EGL
keywords that provide those functions:
Table 29. CRUD functions in EGL
CRUD function EGL keyword
Create add
Read get
Update replace
Delete delete

Furthermore, EGL tailors the way it executes each of these functions based on the
particular type of file with which you are working. For example, if you write a get
next statement for a SQL database, EGL generates a series of SQL statements to
locate and retrieve the appropriate row from an SQL result set. The same EGL
statement generated for a sequential file would simply read the next record in the
file.

EGL accomplishes these tasks by means of stereotyping. In everyday use, a


stereotype is a common pattern that you can use to characterize an individual. In
much the same way, when you apply a stereotype to a record, you tell EGL how it
should perform I/O functions that involve that record. For more on stereotypes,
see “Introduction to Record parts” on page 100 and topics that focus on the
specific stereotypes in the EGL Language Reference.

184 EGL Programmer’s Guide


The I/O processing cycle
Assuming that you have an existing database (typically created by a database
administrator), regular processing generally involves the create, read, update, and
delete (CRUD) functions. More specific examples are presented in the topics that
deal with specific data access technologies. The following general scenario is
possible only because EGL is so efficient at shielding you from implementation
details.

Start by defining a Record, which you must do outside of a generatable part:


package com.companyb.customer

Record CustomerRecord type Stereotype


customerNumber INT;
customerName STRING;
customerBalance MONEY;
end

The details of the record, and its properties, will vary depending on how you plan
to use it.

Next, within the body of your program, declare a variable based on this Record
part:
myCustomer CustomerRecord;

To find an existing customer record, you will need a unique piece of information
about the record. Typically this means some kind of ID number, often used as a key
to the file. A key is a piece of data used to index a file, so you don’t have to look
at every record to find the one that you want. Assume that you have separately
written a function called getCustomer() that asks the user for a customer number
and returns that number:
myCustomer.customerNumber = getCustomer();

To read the information that matches the requested number, simply code the
following:
get myCustomer forUpdate;

EGL generates the appropriate code to read the data from the file or database and
then places the information in your record variable. The forUpdate keyword tells
EGL to place a hold on the data so you have the option to replace or delete it.

You can then offer the information to your user with the option to change it.
Assume that you have separately written a function called showCustomer() that
returns a –1 if the user wants to delete the record, 0 if the record is unchanged,
and 1 if the user made any changes to the record:
case (showCustomer(myCustomer))
when (-1)
delete myCustomer;
when (1)
replace myCustomer;
end

If you handle errors (see “Handling errors” on page 148), you can do a bit more
with the number that getCustomer() returns. Assume that you have separately
written a function called getReply() that returns TRUE or FALSE depending on
whether the user answers Y or N to the specified question:

Accessing data with EGL code 185


set myCustomer empty; // all fields blank or 0
myCustomer.customerNumber = getCustomer(); // sets cust #

try
get myCustomer forUpdate;
onException (ex AnyException) // couldn't get the record
if(myCustomer is noRecordFound) // because customer # not on file
if(getReply("Do you want to add this customer? (y/n)") == TRUE)
showCustomer(myCustomer); // let user fill in remaining fields
add myCustomer;
end
else
myErrorHandler(ex);
end

With these few lines of code you have the heart of a customer file service program
that you can use with an SQL database or your own VSAM indexed file. The only
difference in your program between VSAM and SQL is the stereotype you apply to
the CustomerRecord definition.
Related concepts
“Introduction to Record parts” on page 100
Record parts are collections of other data parts. The data parts within the
Record part are referred to as fields. A Record part can contain any number of
fields, and the fields can be primitives, data items, or other records.
Related tasks
“Handling errors” on page 148
With EGL, you can decide how your program behaves in case of errors.

Writing and reading to files


Reading and writing to files, such as sequential or comma-separated value (CSV)
files, is similar to writing and reading records in any other type of data source.
However, the process of connecting to the data source is different, and you are
restricted to particular variations of the EGL data access statements.

EGL allows you to write and read several types of files, including indexed files,
sequential files, and comma-separated value (CSV) files, also known as delimited files.
These types of files differ mostly in the way they store information to the file; the
process of reading the file and writing to the file is similar for each type. This topic
deals with sequential files and CSV files.

Prerequisites
v An EGL project

Setting up a resource association

To connect to a file, you must first define a resource associations part that points to
that file. The file itself can be a data set as well as a file on your system, but this
example uses a local file.
1. Open the project’s build descriptor.
2. Add a resource associations part to the build descriptor and open that part in
the build parts editor. See ″Adding a resource associations part to an EGL build
file.″
3. In the new resource associations part, add a new association to the location
where the sequential file will go:

186 EGL Programmer’s Guide


a. In the resource associations part, click the Add Association button. A new
entry is displayed under Association elements.
b. In the File Name field of the new entry, type a mnemonic for the sequential
file that conforms to EGL naming requirements, such as myFile. This field is
not the name of the actual file on disk; this field corresponds to the value of
the fileName property of serial record parts that use this file.
c. Set the System field to the type of system you are using, such as win for
Windows or linux for Linux.
d. Set the File type field to seqws to represent a sequential record.
e. Set the systemName field to the fully qualified location of the file. For
example, in a Windows operating system, systemName should be set to
something like this:
C:\myFolder\myFile.dat

If you point to a file that does not exist, EGL will create the file when you
write to it.
The resource associations part looks like this, with your own values in the
fields:

f. Save and close the resource associations part.


4. Set the value of the resourceAssociations build descriptor option to the name
of the resource associations part.
5. Define a Record part to represent the records that will be stored in the file. For
example, if you want to use a sequential file, define a serialRecord:
record mySerialRecord type serialRecord
10 myInteger int;
10 myChar char(50);
end
6. Set the fileName property to the value of the File Name field in the resource
association part entry:
record mySerialRecord type serialRecord
{fileName = "myFile"}
10 myInteger int;
10 myChar char(50);
end

Now you can use the record part in your code to access the sequential file.

For more information on resource associations parts, see the EGL Generation Guide.

Writing to the file

Writing to a file is similar to writing to any other data source.


1. Open an EGL program or other logic part.
2. Make sure that your serial record part is in scope and is associated with the
sequential file as in ″Setting up a resource association″ above. You might need
to use an import statement to bring it into scope:

Accessing data with EGL code 187


import myProject.myData.mySerialRecord;
3. In an EGL program, declare a variable that is based on your serial record:
variableRecord mySerialRecord;
4. Add data to the fields in the new variable:
variableRecord.myInteger = 45;
variableRecord.myChar = "Hello!";
5. Use an appropriate EGL data access statement, such as add to write the record
to the file:
add variableRecord;
6. Save, generate, and run the program. The new record is written to the end of
the sequential file.

Reading from the file

Reading data from a sequential or CSV file is similar to reading from any other
data source, except that you must read the records in order.

In general, use the get next statement to read a single record and the get statement
to read multiple records when you deal with serial records. In this context, get
next begins with the first record in the sequential file and reads the records in
order.
1. Open an EGL program or other logic part.
2. Make sure that your serial record part is in scope and is associated with the
sequential file as described in ″Setting up a resource association″ above. You
might need to use an import statement to bring it into scope:
import myProject.myData.mySerialRecord;
3. In an EGL logic part, declare a variable that is based on your serial record:
variableRecord mySerialRecord;
4. Retrieve a record from the sequential file using the variable:
get next variableRecord;
5. Use the data from the sequential file:
sysLib.writeStderr(variableRecord.myChar);
6. Save, generate, and run the program. The program reads the sequential file and
displays the data from the record in the console:
Hello!

Using CSV files

One of the advantages of CSV files is that they are human-readable. Here is a
simple example of a CSV file:
123,yes,3/9/2007,Rahima
-1,no ,9/9/1999,Jorge
92,yes,,Ludmilla

This example shows three lines of data, each with four pieces of information. Each
piece of information is separated by a character called a delimiter, in this case a
comma. Note that the third piece of data in the third line is null, as indicated by
no data between the delimiters. CSVRecord parts treat each of these pieces of
information as a field. A CSVRecord for this file would look like this example:
record CsvRec type CSVRecord
{
fileName = "CSVFile",
delimiter = ",",

188 EGL Programmer’s Guide


textQualifier = "\"",
style = CsvStyle.quoted
}

jobCode int;
permStatus char(3);
hireDate date?;
firstName string;
end

The fileName field performs the same purpose as the serialRecord; it refers to an
element in a resource associations part that points to a file. However, the
CSVRecord has some additional properties. The delimiter property indicates the
character that separates each piece of information, in this case a comma. The
textQualifier and style properties are closely related; this configuration indicates
that strings in the file can be enclosed in quotes if they contain reserved characters.
See CSVRecord stereotype for more information.

If you saved the example of a CSV file above to a file and created a resource
associations element to point to it, you could use this record to read from and
write to the file using a program like this:
program readCSV type BasicProgram {}

oneRecord CsvRec;

function main()

//get the first record


get next oneRecord;

if (oneRecord is endOfFile)
//if there are no records
SysLib.writeStdout("This file is empty.");
else
while (oneRecord not endOfFile)
//perform this action for each record found
SysLib.writeStdout(oneRecord.firstName);
get next oneRecord;
end
end
end

end

This program reads from the file in the same way as the previous examples that
used the sequential record, using the get next statement. You can write to the CSV
file with the add statement in the same way.
Related tasks
Adding a resource associations part to an EGL build file
Related reference
resourceAssociations
Resource associations part
SerialRecord stereotype
CSVRecord stereotype

Specifying database options at project creation


This topic tells you how to specify SQL database options at project creation.

Accessing data with EGL code 189


1. Create a database connection as explained in ″The New Connection Wizard″
in “Creating an SQL database connection” on page 197.
2. Open the New EGL Project window:
a. Click File → New → Other.
b. Expand EGL and click EGL Project Wizard.
c. Click Next.
3. Give the project a name and select a type of project.
4. Click Next.
5. On the next page of the wizard, under Build Descriptor Options, click Create
new project build descriptor(s) automatically.
6. Click Options.
7. In the Project Build Options window, clear the Use Default SQL Connection
check box.
8. Select the connection you created earlier from the Connection list.
9. Click OK to close the Project Build Options window.
10. Finish setting options for the project as explained in “Creating an EGL
project” on page 71.
Related tasks
“Creating an EGL project” on page 71
This topic covers how to create an EGL project.

Accessing an LDAP-compliant server


EGL provides a code sample that you can customize to retrieve security or other
details from a server accessed by way of Lightweight Directory Access Protocol
(LDAP).

When you are creating a new EGL project whose code will access an
LDAP-compliant server, select the EGL project feature EGL with LDAP Support
by updating an Advanced Setting. Similarly, when you are adding LDAP support
to an existing project, add the EGL project feature EGL with LDAP Support from
the Properties of the project. The effect in each case is to add the server-access files
LDAPExternalTypes.egl and LDAPLib.egl to the project.

For more information about LDAP, see Sample: EGL LDAP access.

The keystroke details for an existing project are as follows:


1. In the Project Explorer view, right-click the project and then click Properties.
2. In the Properties window, click EGL Project Features.
3. Select the EGL with LDAP support check box
4. Click OK.

Working with SQL data


SQL (pronounced as three separate letters) refers to a language that is designed to
communicate with the software that controls a relational database.

A relational database maintains information in interconnected tables. SQL


databases are the workhorses of the computer world.

EGL provides two options in dealing with SQL data. If you are doing fairly
common and straightforward tasks, you can simply use EGL statements to perform

190 EGL Programmer’s Guide


all your I/O operations (see “Reading and writing records” on page 184). In this
case EGL creates all the actual SQL statements for you. In the second option, you
can use a #sql directive to include your own SQL statements in your EGL code.
With EGL, you can even combine the two styles. You can access the SQL
statements that EGL generates from your EGL code and modify them (see
“Viewing implicit SQL statements” on page 217).

Topics in this section will show you how to connect EGL to your SQL database
(see “Creating an SQL database connection” on page 197), as well as shortcuts for
creating SQL records (see “Retrieving SQL table data” on page 205) and complete
SQL applications (see “Creating a data access application” on page 208).

Best practices
The following table shows where to use each of the EGL SQL techniques:
Table 30. Best practices for EGL SQL
SQL objective EGL approach
Simple SQL data manipulation (SELECT, Use EGL keywords (get, replace, add,
UPDATE, INSERT, DELETE). Primary key delete) and let EGL generate implicit SQL.
controls WHERE and ORDER BY.
Simple SQL data manipulation with reusable Place the custom WHERE clause in the
custom WHERE clause. defaultSelectCondition property.
SQL SELECT statements with custom Use explicit SQL through the #sql directive.
WHERE clause.
SQL table JOIN statement. Use the Retrieve SQL feature in the
workbench, then create use the
defaultSelectCondition property to correctly
join the tables on primary and foreign keys,
as in the following example:
defaultSelectCondition = #sqlCondition{
customer.customer_ID =
orders.customer_ID }
Derived data in SELECT command (such as Use explicit SQL through the #sql directive,
MAX() or AVG()) placing the derived fields inside the braces.
Create a custom SQLRecord, where the
column property for the individual fields
specifies the derived or computed
expression.
Complex or custom SQL UPDATE, INSERT, Use EGL replace, add, or delete statements
or DELETE statement. with explicit SQL (#sql directive).
Use explicit SQL through the execute #sql
statement.
SQL statements other than simple data Use explicit SQL through the execute #sql
manipulation (such as CREATE TABLE). statement.
Dynamic SQL (prepared SQL statement). Use explicit SQL through the execute #sql
statement.
Stored procedure. Use explicit SQL such as the following:
open result_set with #sql{
CALL stored_proc ( :host_var) }

Accessing data with EGL code 191


Table 30. Best practices for EGL SQL (continued)
SQL objective EGL approach
Processing of individual rows of the result Use the EGL open command to open the
set from a SQL SELECT statement. result set, then initiate a loop with one of
the following statements:
v forEach (from result_set)
v while (sqlLib.sqlData.sqlcode == 0)
Programmatic paging for online searches. Use the Data Access Application wizard.
Addition of data to SQL table. Use the Table Editor in the workbench Data
Perspective.
SQL statement validation In the EGL editor, select Validate SQL from
the context menu.
Run interactive SQL using the SQL Editor in
the workbench Data Perspective.

Result-set processing
A common way to update a series of rows is as follows:
1. Declare and open a cursor by running an EGL open statement with the
forUpdate option; that option causes the selected rows to be locked for
subsequent update or deletion.
2. Fetch a row by running an EGL get next statement.
3. Do the following in a forEach loop:
a. Retrieve data from the result set into the host variables. A host variable is a
variable in an SQL statement with the same name as a variable in the host
language (in this case, EGL hosts the SQL statements), with an additional
initial colon character (:).
b. Update or delete the row by running an EGL replace or delete statement.
c. Fetch another row by running an EGL get next statement.
4. Commit changes by running the EGL commit() function.

The statements that open the cursor and that act on the rows of that cursor are
related to each other by a result-set identifier, which must be unique across all
result-set identifiers and program variables within the program. You specify that
identifier in the open statement that opens the cursor, and you reference the same
identifier in the forEach statement that creates the loop. You also reference the
identifier in the get next, delete, and replace statements that affect an individual
row, as well as on the close statement that closes the cursor.

You can use a specialized type of EGL record, the SQLRecord, to hold the
information that you read from or write to a relational database. The following
example shows how to update a series of rows when you are coding the SQL
yourself:
try
open selectEmp forUpdate for emp;
onException(sqlx SqlException)
myErrorHandler(sqlx); // exits program
end

foreach(emp)
emp.empname = emp.empname :: " " :: "III";
try
replace emp;

192 EGL Programmer’s Guide


onException(sqlx SqlException)
myErrorHandler(sqlx); // exits program
end
end // end while; cursor is closed automatically
// when the last row in the result set is read

sysLib.commit();

If you want to commit changes periodically as you process an EGL open statement
(regardless of whether you use SQL records), you can use the hold statement
option, which maintains cursor position after a commit. If a program targeted for
CICS is segmented, however, the hold option has no effect because a converse in a
segmented program ends the CICS transaction and prevents the program from
retaining any file or database position.

SQL records and their uses


After you define an SQLRecord part, you declare a variable based on that part.
You can then use this record variable to access a relational database as though you
were accessing a file. If the variable myEmpRecord is based on an SQLRecord part
that references the database table EMPLOYEE, for example, you can use
myEmpRecord in an EGL add statement:
add myEmpRecord;

In this case, EGL inserts the data from myEmpRecord into EMPLOYEE. After the
EGL statement runs, the record variable contains information about error
conditions:
try
add myEmpRecord;
onException(sqlx SqlException)
if (myEmpRecord is unique) // if a table row had the same key
myErrorHandler(sqlx);
end
end

A record variable like myEmpRecord allows you to interact with a relational


database as follows:
v Define an SQLRecord part and declare the related record variable.
v Write EGL statements that perform I/O using the SQL record.
v Accept the default behavior of the EGL statements (which should give you what
you want in most cases) or make SQL changes that are appropriate for your
business logic.

Define an SQLRecord part and the related record


You define an SQLRecord part and associate each of the fields with a column in a
relational table or view. EGL can do this for you automatically; see “Retrieving
SQL table data” on page 205.

If the SQLRecord part is not a fixed record part, you can include primitive fields as
well as other variables. You are especially likely to include the following kinds of
variables:
v Other SQL records. The presence of each represents a one-to-one relationship
between the parent and child tables.
v Arrays of SQL records. The presence of each represents a one-to-many
relationship between the parent and child tables.

Only fields of a primitive type can represent a database column.

Accessing data with EGL code 193


If level numbers precede the fields, the SQLRecord part is a fixed record part. The
following rules apply:
v The structure in each SQLRecord part must be flat (without hierarchy)
v All of the fields must be primitive fields, but not of type BLOB, CLOB, or
STRING
v None of the record fields can be a structure-field array

After you define an SQLRecord part, you declare a record variable that is based on
that part.

Writing SQL-related EGL statements


You can create a set of EGL statements that each use the record variable as the I/O
object in the statement. For each statement, EGL provides an implicit SQL statement,
which is not in the source but is implied by the combination of record variable and
EGL statement. In the case of an EGL add statement, for example, an implicit SQL
INSERT statement places the values of the fields in the given record into the
associated table column. If your record variable includes a field for which no table
column was assigned, EGL forms the implicit SQL statement on the assumption
that the name of the field is identical to the name of the column.

The following EGL statements correspond to the SQL statements shown:


Table 31. Implicit SQL statements
EGL statement SQL statement
add INSERT
delete DELETE
get, open SELECT
replace UPDATE

Using implicit SELECT statements: When you define an EGL statement that uses
a record variable and that generates either an SQL SELECT statement or a cursor
declaration, EGL provides an implicit SQL SELECT statement. (That statement is
embedded in the cursor declaration, if any.) For example, you might declare a
variable based on the following SQLRecord part:
Record Employee type sqlRecord
{ tableNames = [["EMPLOYEE"]],
keyItems = ["empnum"] }
empnum decimal(6,0);
empname char(40);
end

Next, declare a variable based on this Record:


myEmpRecord Employee;

Then, you might code a get statement:


get myEmpRecord;

The implicit SQL SELECT statement is as follows:


SELECT empnum, empname
FROM EMPLOYEE
WHERE empnum = :empnum

EGL also places an INTO clause into the standalone SELECT statement (if no
cursor declaration is involved) or into the FETCH statement associated with the

194 EGL Programmer’s Guide


cursor. The INTO clause lists the host variables that receive values from the
columns listed in the first clause of the SELECT statement:
INTO :empnum, :empname

The implicit SELECT statement reads each column value into the corresponding
host variable; references the tables specified in the record variable; and has a
search criterion (a WHERE clause) that depends on a combination of two factors:
v The value you specified for the defaultSelectCondition record property.
v A relationship (such as an equality) between two sets of values:
– Names of the columns that constitute the table keys
– Values of the host variables that constitute the record keys
EGL infers the relationship from the tableNames record property or the
usingKeys clause of the EGL statement.

For details on the implicit SELECT statement, see individual keyword topics in the
EGL Language Reference.

Using SQL records with cursors: When you are using SQL records, you can relate
cursor-processing statements by using the same record variable in several EGL
statements, much the same way as you can by using a result-set identifier.
However, any cross-statement relationship that is indicated by a result-set identifier
takes precedence over a relationship indicated by the record variable; and in some
cases you must specify a resultSetID.

In addition, only one cursor can be open for a particular record variable. If an EGL
statement opens a cursor when another cursor is open for the same record
variable, the generated code automatically closes the first cursor.

Customizing the SQL statements


Given an EGL statement that uses an SQL record variable as the I/O object, you
can progress in either of two ways:
v You can accept the implicit SQL statement. In this case, changes made to the
SQLRecord part affect the SQL statements used at run time. If you later indicate
that a different field is to be used as the key of the SQL record, for example,
EGL changes the implicit SELECT statement used in any cursor declaration that
is based on that SQLRecord part.
v You can choose instead to make the SQL statement explicit. EGL can insert the
implicit SQL statements into your code for you so you can modify them. In this
case, the details of that SQL statement are isolated from the SQLRecord part, and
any subsequent changes made to the SQLRecord part have no effect on the SQL
statement that is used at run time.
If you remove an explicit SQL statement from the source, the implicit SQL
statement (if any) is again available at generation time.

Example of using a record in a record


To allow a program to retrieve data for a series of employees in a department, you
can create two SQLRecord parts and a function, as in the following example:
DataItem DeptNo { column = "deptNo" } end

Record Dept type SQLRecord


deptNo DeptNo;
managerID CHAR(6);
employees Employee[];
end

Accessing data with EGL code 195


Record Employee type SQLRecord
employeeID CHAR(6);
empDeptNo DeptNo;
end

Function getDeptEmployees(myDeptRecord Dept)


get myDeptRecord.employees usingKeys myDeptRecord.deptNo;
end

Testing for and setting NULL


If you want a variable to be nullable, that is, to be able to accept a null value,
declare the variable with the ″?″ type extension character, as in this example:
Record Employee type SQLRecord
employeeID CHAR(6);
empDeptNo INT?;
end

To test for a null value, use a standard EGL if statement, as in the following
example:
if (myEmpRecord.empDeptNo == null)
...
end

You can directly assign a null value to a variable:


myEmpRecord.empDeptNo = null;

The syntax works even if the target is not nullable. In that case, the statement has
the same effect as the following statement:
set myEmpRecord.empDeptNo empty;

Compatibility
Table 32. Compatibility considerations for SQL
Platform Issue
CICS for z/OS, z/OS The generated code can access DB2 UDB directly
batch, iSeriesC
AIX, HP-UX, iSeriesJ, JDBC provides access to DB2 UDB, Oracle, Informix, or
Linux, Solaris, z/OS Microsoft SQL Server
UNIX® System Services,
Windows 2000/NT/XP

Related tasks
“Creating an SQL database connection” on page 197
The New Connection wizard creates an SQL database connection that you can
use either at design time or at run time.
“Reading and writing records” on page 184
“Retrieving SQL table data” on page 205
“Creating a data access application” on page 208
EGL can create a simple data access application based on a database to which
you are connected. The resulting application contains data parts, logic parts and
(optionally) Web pages that are based on one or more database tables.
“Viewing implicit SQL statements” on page 217

196 EGL Programmer’s Guide


Creating an SQL database connection
The New Connection wizard creates an SQL database connection that you can use
either at design time or at run time.

EGL offers two other ways to create an SQL connection:


v The sqlLib.connect() system function, to activate a connection at run time; see
connect().
v The vgLib.connectionService() system function, for programs migrated from
VisualAge Generator or EGL version 5; see connectionService().

Even if you plan to use either of these functions, it is still recommended that you
have a default connection in place.

Prerequisites
You must have a database set up and running. The database must be one of the
products that EGL supports. See “Supported SQL database managers” on page 200
for more information.

Opening the New Connection wizard


In EGL, you can access the New Connection wizard from many of the places
where an SQL connection is required. The workbench provides several places to
find the New Connection wizard:
v From the workbench menu, click Window → Preferences → EGL → SQL Database
Connections. To the right of the list labeled Connection, click the button labeled
New.
v Right-click an EGL project and then click Properties. In the Properties window,
click EGL Runtime Data Source and then click New.
v Open the Data perspective (Window → Open Perspective → Other → Data). The
Database Explorer view is available in this perspective, by default in the lower
left corner of the workbench. Right-click Connections and pick New Connection
from the menu.

Note: The Data perspective is not filtered for EGL, and includes information for
other products. Thus if you run the New Connection wizard from the
Data perspective, you might see databases listed (such as Generic JDBC or
Sybase) that EGL does not support. Use the table in ″Supported database
managers″ to determine the database managers that you can use with
EGL.

The information the wizard needs varies with the type of database that you use.
When you choose from the Select a database manager list, the wizard fills in as
many default values as it can. For the list of supported databases and the
information that each requires, see “Supported SQL database managers” on page
200.

When you have given the wizard enough information, the Test Connection button
becomes available. Click this button to verify your connection information. If you
get an error message, check your settings or work with your database
administrator to resolve the problem.

If the test is successful, you have everything you need to use the EGL features that
require a design-time connection, such as “Creating a data access application” on
page 208 or “Retrieving SQL table data” on page 205. You are not, however,

Accessing data with EGL code 197


automatically set up to have an SQL connection at run time. To specify that
connection, see “Using an SQL database connection at run time” on page 202.

Creating the new connection


Once you have opened the New Connection wizard as explained above, you can
start filling in the information:
1. Under Select a database manager, select the type and version of database you
are connecting to. You should do this step first because the remainder of the
fields on the page depend on this choice.
2. Once you have selected the database type, fill in the remainder of the fields on
the page. Which fields you need to fill in depends on which database you are
connecting to. See “Fields in the New Connection wizard”for information on
the individual fields.
3. When you have filled out the fields in the wizard, you can click Test
Connection to make sure that the connection is working.
4. Click Next.
5. On the Filter page, you can select schemas from the database to be included or
ignored in the connection.
By default, the New Connection wizard will retrieve information for each
schema in the database and each table in each of those schemas. Retrieving this
information can take time on large databases. The EGL Data Access Application
wizard requires this connection information to produce parts from the database,
but the other areas of EGL design-time access functionality, such as the SQL
retrieve functionality described in “Retrieving SQL table data” on page 205, do
not require this information. For this reason, you can save time by filtering out
schemas or tables that you do not want to use with the Data Access
Application wizard, or by filtering out all of the schemas and tables if you do
not want to use this connection with the Data Access Application wizard at all.
6. If you do not want to filter schemas out of the connection, click Finish.
7. If you want to filter schemas out of the connection, follow these additional
steps:
a. Clear the Disable filter check box.
b. Click the Selection radio button. The schemas in the database are listed
below.
c. In the list under Selection, select Include selected items or Exclude
selected items, depending on whether you want to select the schemas to
include or the schemas to exclude from the connection.
d. Select or clear the check boxes next to the schemas in the list. You must
select at least one schema.
Schemas that you filter out of the connection will not be available if you use
this connection with the Data Access Application wizard.
e. Click Finish.
Alternately, you can select the Expression radio button and enter a search
string to indicate which tables should be included.

Fields in the New Connection wizard


The New Connection wizard fills in the following fields automatically:
JDBC driver
This is the EGL name for the driver that is used to talk to the database
manager, such as ″IBM DB2 Universal.″

198 EGL Programmer’s Guide


JDBC driver class
This is the name of the Java class that contains the driver:
v For IBM DB2 Universal Driver, the driver class is
com.ibm.db2.jcc.DB2Driver
v For IBM DB2 APP DRIVER for Windows, the driver class is
COM.ibm.db2.jdbc.app.DB2Driver
v For the Oracle JDBC thin client-side driver, the driver class is
oracle.jdbc.driver.OracleDriver
v For the Informix JDBC NET driver, the driver class is
com.informix.jdbc.IfxDriver
v For the DataDirect SequeLink JDBC Driver for SQL Server, the driver
class is com.ddtek.jdbc.sqlserver.SQLServerDriver
v For the Microsoft JDBC Driver for SQL Server 2005, the driver class is
com.microsoft.jdbc.sqlserver.SQLServerDriver; for SQL Server 2000,
the driver class is com.microsoft.sqlserver.jdbc.SQLServerDriver
v For Derby, the driver class is org.apache.derby.jdbc.EmbeddedDriver
v For Cloudscape®, the driver class is com.ibm.db2j.jdbc.DB2jDriver
v For other driver classes, refer to the documentation for the driver.
Connection URL
This is the address that EGL uses to contact the database, such as
″jdbc:db2://localhost:50000/
SAMPLE:retrieveMessagesFromServerOnGetMessage=true;″ This URL
contains a hostname, port number, and attributes.

You can override the default values in these fields by selecting Other for your
JDBC driver and specifying the appropriate JDBC driver class.

The wizard will complete as many of the other fields as it can, but might require
you to fill in some or all of the following:
Connection Name
You will not need to complete this field if you check the Use default
naming convention option, which typically uses the name of your
database.
SID The ID of the server where your database is located.
Host The host name of your database server.
Port number
The port number that you connect to on the host.
Server The address of your database server.
Database
The name of the specific database to which you want to connect.
Class location
The fully qualified location of the *.jar or *.zip file that contains the driver
class:
v For IBM DB2 Universal Driver, type the fully qualified filenames to the
db2jcc.jar and db2jcc_license_cu.jar files
v For IBM DB2 APP DRIVER for Windows, type the fully qualified
filename to the db2java.zip file; for example, d:\sqllib\java\
db2java.zip

Accessing data with EGL code 199


v For the Oracle THIN JDBC DRIVER, type the fully qualified pathname
to the ojdbc14.jar file; for example, d:\Ora81\jdbc\lib\ojdbc14.jar or, if
you require Oracle trace, ojdbc14_g.jar
v For the Informix JDBC NET driver, type the fully qualified filename to
the ifxjdbc.jar file
v For the DataDirect SequeLink JDBC Driver for SQL Server, type the fully
qualified filenames to the base.jar, util.jar, and sqlserver.jar files
v For the Microsoft JDBC Driver for SQL Server, type the fully qualified
filenames to the msbase.jar, msutil.jar, and mssqlserver.jar files
v For Derby, type the fully qualified filename to the derby.jar file
v For Cloudscape, type the fully qualified filename to the db2j.jar file
v For other driver classes, refer to the documentation for the driver
User ID
If your database is password protected, you can store the user ID here.
Note that the Tomcat server ignores the userID and password that you
provide here and uses the values from its server configuration.
Password
If your database is password protected, you can store the password here.
Note that the Tomcat server ignores the userID and password that you
provide here and uses the values from its server configuration.
Related tasks
“Creating a data access application” on page 208
EGL can create a simple data access application based on a database to which
you are connected. The resulting application contains data parts, logic parts and
(optionally) Web pages that are based on one or more database tables.
“Retrieving SQL table data” on page 205
“Using an SQL database connection at run time” on page 202
To use an SQL connection at run time, you must point to the connection from
your project’s build descriptor and, for EGL Web projects, set options in the
J2EE deployment descriptors based on information in the connection.
“Editing or deleting an SQL database connection” on page 205
Related reference
“Supported SQL database managers”
The following table provides a list of the SQL databases that EGL supports.

Supported SQL database managers


The following table provides a list of the SQL databases that EGL supports.

To create a connection, the New Connection wizard requests some or all of the
information in the right column. This information is provided so that you can
obtain the right information from a database administrator, if necessary. For more
information about these connection fields, see “Fields in the New Connection
wizard” on page 198.

200 EGL Programmer’s Guide


Table 33. Supported databases
Database
Manager Versions Setup Information
Cloudscape 5.1 v JDBC driver
v JDBC driver class
v Class location
v Connection URL
v User ID
v Password
DB2 UDB V8.1, V8.2, V9.1 v JDBC driver
v Host
v Port number
v JDBC driver class
v Class location
v Connection URL
v User ID
v Password
DB2 UDB V5R2, V5R3, V5R4 v JDBC driver
iSeries
v JDBC driver class
v Class location
v Connection URL
v User ID
v Password
DB2 UDB V7, V8 (Compatibility v JDBC driver
zSeries® Mode or
v Host
New-Function Mode)
v Port number
v JDBC driver class
v Class location
v Connection URL
v User ID
v Password
Derby 10.0, 10.1 v JDBC driver
v Database location
v JDBC driver class
v Class location
v Connection URL
v User ID
v Password

Accessing data with EGL code 201


Table 33. Supported databases (continued)
Database
Manager Versions Setup Information
Informix 9.2, 9.3, 9.4, 10.0 v JDBC driver
v Database
v Host
v Port number
v Server
v JDBC driver class
v Class location
v Connection URL
v User ID
v Password
Oracle 8, 9, 10 v JDBC driver
v SID
v Host
v Port number
v JDBC driver class
v Class location
v Connection URL
v Catalog
v User ID
v Password
SQL Server 2000, 2005 v JDBC driver
v Host
v Port number
v JDBC driver class
v Class location
v Connection URL
v User ID
v Password

Related tasks
“Creating a data access application” on page 208
EGL can create a simple data access application based on a database to which
you are connected. The resulting application contains data parts, logic parts and
(optionally) Web pages that are based on one or more database tables.
“Creating an SQL database connection” on page 197
The New Connection wizard creates an SQL database connection that you can
use either at design time or at run time.

Using an SQL database connection at run time


To use an SQL connection at run time, you must point to the connection from your
project’s build descriptor and, for EGL Web projects, set options in the J2EE
deployment descriptors based on information in the connection.

202 EGL Programmer’s Guide


Prerequisites
You will need a working connection to an SQL database, or you can create one in
the process. For instructions on setting up this connection, see “Creating an SQL
database connection” on page 197.

Creating the runtime connection for EGL Web projects


For EGL Web projects, you need to set options in the project based on the
information in the connection. Through the project’s EGL Runtime Data Source
property page, EGL can do much of this work for you automatically:
v EGL updates the following build descriptor options in the project’s master build
descriptor:
– dbms
– sqlDB
– sqlID
– sqlJDBCDriverClass
– sqlJNDIName
– sqlPassword
– sqlValidationConnectionURL
Whether EGL updates the build descriptor options or not depends on the build
descriptor preferences, as explained in “Setting build descriptor preferences” on
page 174. If you want EGL to update your build descriptor options, set Update
default build options for project when runtime data source is modified to
Prompt or Always.
v If the Web project is acting as a module of an enterprise application resource
(EAR) project, EGL adds a data source to the EAR project’s deployment
descriptor. This data source associates the JNDI name with the database itself.
Now, other projects acting as modules within this EAR project can access the
database through the JNDI name.
If the Web project is not a module within an EAR project, you must associate the
JNDI name with a database on the server manually. Refer to the server
documentation for how to create a JDBC data source.
v EGL adds a reference to the JNDI name in the project’s Web deployment
descriptor. Now the project can use the data source through the JNDI name, as
long as the EAR project or server links that JNDI name to a data source.
1. Right-click your project and then click Properties.
2. In the Properties window, click EGL Runtime Data Source.
3. On the EGL Runtime Data Source page, select Load values from a data tools
connection and select your database connection in the Connection list. You can
also click New and create a new connection; for information on creating the
connection, see “Creating an SQL database connection” on page 197.
4. When you select a connection, EGL uses the information in that connection to
fill in the fields on the page. To edit these values, you can select Input/modify
values manually and edit the values in the fields. For information on the
individual fields, see “Fields in the New Connection wizard” on page 198.
In addition to the information from the database connection, EGL creates a
JNDI name for the connection. By default, this name is the name of the
database connection plus the prefix jdbc/. You can accept the default or edit
the JNDI name field.

Accessing data with EGL code 203


5. If you do not want EGL to set up a data source in the EAR deployment
descriptor associated with this project, click Input/modify values manually and
clear the Deploy database and connection properties when application is run
on unit test server.
6. Click OK to make the updates to your project.
If the Update default build options for project when runtime data source is
modified preference is set to Always, EGL automatically updates the build
descriptor options based on the connection information. If the preference is set
to Prompt, EGL asks before updating the build descriptor options. If the
preference is set to Never, no changes are made to the build descriptor options.

Creating the runtime connection for EGL projects


1. Double-click the build descriptor for your project. Typically, the build
descriptor file is located in the top level of the EGLSource directory of your
project and is named project.eglbld. The build descriptor opens in the build
parts editor.
2. Select the database connection to use from the Load DB options using
Connection list. If you have not already created this connection, see “Creating
an SQL database connection” on page 197.
When you select a connection, the build parts editor updates the following
build descriptor options to match the connection:
v dbms
v sqlDB
v sqlID
v sqlJDBCDriverClass
v sqlPassword
v sqlValidationConnectionURL
3. Save the build descriptor and close the window.
4. Generate any parts that use the database connection.

Error conditions
EGL uses a different process to connect with the database at run time than it does
at design time. These differences might result in errors when you try to run your
code:
v EGL might not be able to find the Java class containing the driver for your
database manager, even though you specified a Class location in the New
Connection wizard. To correct this error, make sure the driver is on the classpath
for your project:
1. Right-click on your project name in the Project Explorer view and click
Properties from the pop-up menu.
2. Select Java Build Path from the left pane of the Properties window.
3. Click the Libraries tab on the Java Build Path page.
4. If the correct class location is not displayed, click Add External JARs and
add the class and location. You can copy this information from your
Connection; see “Editing or deleting an SQL database connection” on page
205
.
Related tasks
“Creating an SQL database connection” on page 197
The New Connection wizard creates an SQL database connection that you can
use either at design time or at run time.
“Editing or deleting an SQL database connection” on page 205
204 EGL Programmer’s Guide
Editing or deleting an SQL database connection
Prerequisites
v An existing database connection

Editing an existing connection


To edit an existing database connection, do as follows:
1. Click Window → Open → Perspective → Other. At the Select Perspective dialog,
select the Show all check box and double-click Data.
2. In the Database Explorer view, right-click the database connection, then select
Edit Connection. Step through the pages of the database connection wizard
and change information as appropriate. For help, press F1. For a list of the
required fields for each database type, see “Supported SQL database managers”
on page 200.
3. To complete the edit, click Finish.

Alternately, you can edit an existing connection from the EGL preferences:
1. Click Window → Preferences.
2. Expand EGL and click SQL Database Connections.
3. Select the connection from the Connection list.
4. Click Edit.
5. Change information in the connection as appropriate.
6. When you are finished editing the connection, click Finish and then click OK
to close the Preferences window.

Deleting an existing connection


To delete an existing database connection, do as follows:
1. Select Window > Open Perspective > Other. In the Select Perspective dialog
box, select the Show all check box and double-click Data.
2. In the Database Explorer view, right-click the database connection, and then
click Delete.
Related reference
“Creating an SQL database connection” on page 197
The New Connection wizard creates an SQL database connection that you can
use either at design time or at run time.
“Supported SQL database managers” on page 200
The following table provides a list of the SQL databases that EGL supports.

Retrieving SQL table data


With EGL, you can create SQL record fields from the definition of an SQL table,
view, or join.

To create SQL record fields from the definition of an SQL table:


1. Ensure that you have set SQL preferences as appropriate. For details, see
“Setting preferences for SQL retrieve” on page 220.
2. Set the default database connection, which is the connection that EGL will use
to retrieve the table data:
a. Click Window → Preferences.
b. Expand EGL and click SQL Database Connections.

Accessing data with EGL code 205


c. Select your database connection from the Connection list or create a new
database connection. The connection selected in the Connection list is the
default database connection.
3. Decide where to do the task:
v In an EGL source file, as you develop each SQL record; or
v In the Outline view, as may be easier when you already have SQL records.
4. If you are working in the EGL source file, proceed in this way. If you are
working in the Outline view, skip to the next step.
a. If you do not have the SQL record, create it:
1) Type R, press Ctrl+Space, and in the content-assist list, select one of the
SQL table entries (usually SQL record with table names).
2) Type the name of the SQL record, press Tab, and then type a table name,
or a comma-delimited list of tables, or the alias of a view.
You also can create an SQL record by typing the minimal content, as
appropriate if the name of the record is the same as the name of the table,
as in this example:
Record myTable type sqlRecord
end
b. Right-click anywhere in the record.
c. In the menu, click SQL record > Retrieve SQL.
5. If you are working in the Outline view, right click the entry for the SQL record
and, in the pop-up menu, click Retrieve SQL.

Note: You cannot retrieve an SQL view that is defined with the DB2 condition
WITH CHECK OPTIONS.

After you create record fields, you may want to gain a productivity benefit by
creating the equivalent DataItem parts for the fields in the record:
1. Open the record in the EGL editor and then open the Outline view. The Outline
view shows a hierarchical view of the parts and other EGL code on the page.
2. In the Outline view, right-click the field and then click Create DataItem Part.
EGL creates a dataItem part based on the field in the record and uses that
dataItem as the field type.

Compatibility of SQL data types and EGL primitive types


An EGL host variable (see “Host variables” on page 211) and the corresponding
SQL table column are compatible in any of the following situations:
v The SQL column is any form of character data, and the EGL host variable is of
the type CHAR with a length less than or equal to the length of the SQL
column.
v The SQL column is any form of DBCHAR data, and the EGL host variable is of
the type DBCHAR with a length less than or equal to the length of the SQL
column.
v The SQL column is any form of number and the EGL host variable is of one of
these types:
– BIN(4,0)/SMALLINT
– BIN(9,0)/INT
– BIN(18,0)/BIGINT
– DECIMAL, with a maximum length of 18 digits, including decimal places.
The number of digits for a DECIMAL variable should be the same for the
EGL host variable and for the column.

206 EGL Programmer’s Guide


v The SQL column is of any data type, the EGL host variable is of type HEX, and
the column and host variable contain the same number of bytes. No data
conversion occurs during data transfer.
EGL host variables of type HEX support access to any SQL column of a data
type that does not correspond to an EGL primitive type.

If character data is read from an SQL table column into a shorter host variable,
content is truncated on the right. To test for truncation, use the reserved word
trunc in an EGL if statement.

Default mapping
EGL uses a default mapping when it creates records with the Retrieve SQL feature.
The following table shows the default mapping.
Table 34. EGL variable characteristics
SQL data type EGL variable characteristics
Primitive type Digits/characters Number of bytes
BIGINT BIGINT n/a 8
BIT SMALLINT n/a 2
BLOB BLOB n/a n/a
BOOLEAN BOOLEAN n/a 1
CHAR CHAR 1–32767 1–32767
CLOB CLOB n/a n/a
DATE DATE n/a 8
DECIMAL DECIMAL 1-18 1–10
DOUBLE FLOAT n/a 8
FLOAT FLOAT n/a 8
GRAPHIC DBCHAR 1–16383 2–32766
INTEGER INT n/a 4
LONG VARBINARY HEX 65534 32767
LONG VARCHAR CHAR >4000 >4000
LONG VARGRAPHIC DBCHAR >2000 >4000
NUMERIC DECIMAL 1-18 1–10
REAL SMALLFLOAT n/a 4
SMALLINT SMALLINT n/a 2
TIME TIME n/a 6
TIMESTAMP TIMESTAMP n/a 14
VARBINARY HEX 2–65534 1–32767
VARCHAR CHAR ≤4000 ≤4000
VARGRAPHIC DBCHAR ≤2000 ≤4000

The definition of an SQL table column of the type VARCHAR or VARGRAPHIC


includes a maximum length, and the retrieve command uses that maximum to
assign a length to the EGL host variable. The definition of an SQL table column of
the type LONG VARCHAR or VARGRAPHIC, however, does not include a
maximum length, and the retrieve command uses the SQL-data-type maximum to
assign a length.

Accessing data with EGL code 207


Compatibility
Table 35. Compatibility considerations for SQL data
Platform Issue
Java generation If numeric data is read from an SQL table column into a
shorter host variable, EGL treats the situation as it would an
overflow on an assignment statement.
COBOL generation If numeric data is read from an SQL table column into a
shorter host variable, leading zeros are truncated on the left. If
the number still does not fit into the host variable, fractional
parts of the number (in decimal) are deleted on the right, with
no indication of error. If the number still does not fit, a
negative SQL code is returned to indicate an overflow
condition.

Related concepts
“Accessing data with EGL code” on page 183
“Working with SQL data” on page 190
SQL (pronounced as three separate letters) refers to a language that is designed
to communicate with the software that controls a relational database.
Related tasks
“Creating a data access application”
EGL can create a simple data access application based on a database to which
you are connected. The resulting application contains data parts, logic parts and
(optionally) Web pages that are based on one or more database tables.
“Setting preferences for SQL database connections” on page 219
“Setting preferences for SQL retrieve” on page 220

Creating a data access application


EGL can create a simple data access application based on a database to which you
are connected. The resulting application contains data parts, logic parts and
(optionally) Web pages that are based on one or more database tables.

Prerequisites

Before you begin, connect to an SQL database. See “Creating an SQL database
connection” on page 197.

Files created for the application

For each table that you select, the EGL Data Access Application wizard creates the
following parts. You can choose to put these parts into a new project or into one or
more existing projects.
v Data parts based on the table:
– An SQLRecord part that represents the table
– DataItem parts that represents the columns in the table
v Data access functions that perform operations on the database, such as adding,
retrieving, and deleting records. You can choose to put these data access
functions in libraries or in services.

Also, you have the option of creating a Web interface for the data access
application. If you choose to create a Web interface, the wizard creates these
additional files and parts:

208 EGL Programmer’s Guide


v A set of JSF handler parts that you later generate into a set of parts that run
under JavaServer Faces
v A set of JSP files that provide the following Web pages:
– A selection condition page, which accepts selection criteria from the user
– A list page, which displays multiple rows, based on the user’s criteria
– A create detail page, which enables the user to display or insert one row
– A detail page, which enables the user to display, update, or delete one row

Projects in the application

Before you begin creating the application, make two decisions about where the
new files and parts will go:
v You can put all the new files and parts into one project, or you can put the files
and parts into different projects, based on the kind of file and part. Data parts,
logic parts, and JSF handler parts (with the associated Web pages) can all go into
separate projects.
v You can put files and parts into a new project or into an existing project. If you
choose to put parts into different projects, some can go into an existing project
and others can go into a new project.

Creating the application


1. Click File → New → Other.
2. In the New window, expand EGL and click EGL Data Access Application.
3. Click Next.
4. In the Project Name field, either select an existing EGL project or type the
name of a new project. Later, you will be able to fine-tune where the new data
parts, logic parts, and Web pages will go, but at least one kind of part will go
into the project you specify here.
5. In the Database Connection list, select a database connection. You can create a
new one by clicking the New button. For more information, see “Creating an
SQL database connection” on page 197.
After you have selected a database connection, the tables in the database
schema are listed in the Table Name list.
6. In the Table Name list, select the check box next to the tables that you want
to include in the data access application.
7. If you want to create a Web interface for the application, including JSF
handler parts and Web pages, select the Generate to EGL Web project check
box. If you clear this check box, your application will contain logic parts and
data parts that enable you to access the database, but no JSF handler parts or
Web pages.
8. Click Next.
The Define the Fields page has a tab for each table that you selected on the
previous page. On this page, you select the key fields for each table and
which fields you want to be able to search.
9. Select the key fields for each table in the Choose key fields list. If the table
already had a key field in the database, that field is selected as a key already.
You cannot remove a key field that is defined in the database.
10. If you are creating a Web interface, select the search fields for each table in the
Choose search UI fields list. The wizard creates a search page for each table
you selected, and that search page will have an input field for each field that
you select here.

Accessing data with EGL code 209


11. Click Next.
If you are creating a Web interface, you will see the Configure the Fields page.
Otherwise, the wizard skips ahead to the Define Generation options page.
As in previous steps, the Configure the Fields page also has a tab for each
table that you selected. On this page, you select how the Web pages will
display the data.
12. Set the display name for each field in the Modify field display name list. The
value in the Display As column will be that field’s label wherever it appears
on a Web page. In EGL terms, this value becomes the value of the
displayName data item property.
13. Select the fields to show on the search results page by selecting check boxes in
the Choose summary fields list.
14. Click Next.
The Define project creation options page has options for the new projects and
packages.
15. In the Default package name field, type the name of the top-level package
that will contain the new EGL parts. The default value is the name of the
database connection.
16. Under Data access method, select whether you want to create library parts or
service parts to hold the new data access functions.
17. If you want to prefix the names of the tables with the name of the database
schema, select Qualify table names with schema. This check box determines
whether the EGL code will refer to the database table simply by the table
name or by the schema name and the table name.
Whether you select this check box or not depends on how you are connecting
to the database. For most testing databases, or if you want to create a simple
application as quickly as possible, you specify the schema name in the EGL
code to avoid specifying the table name in other places; in this case, select the
check box. For most production databases, you specify only the table name in
the EGL code and specify the schema name in a bind step in the JCL; in this
case, clear the check box.
18. If the names of any of the tables or columns in the database are SQL reserved
words, or if the table or column names include any characters that are not
valid in ANSI SQL, such as characters from DBCS languages, select the Use
delimited SQL identifiers check box. If you select this check box, the EGL
code will use quoted strings for the table and column names.
19. If you want to put all of the new files and parts into one project, clear the
Create multiple projects check box. All of the new files and parts will be
created in the project that you entered in the Project Name field on a previous
page. Then, click Finish.
20. If you want to put the new files and parts into different projects, select the
Create multiple projects check box and then click Next. Specify additional
options about the projects on the next page.
The Define alternate project locations page enables you to select separate
projects to hold the new data parts, logic parts, and Web interface files and
parts, with the following restrictions:
v At least one of the projects must be the same as the project you entered in
the Project Name field on a previous page.
v You cannot put all of the files and parts in the same project. If you want to
put all of the files in the same project, go back one page and clear the
Create multiple projects check box.
21. For each kind of file or part, choose a project.

210 EGL Programmer’s Guide


v In the Data Project Name field, select a project to hold the new data parts.
v In the Data Access Project Name field, select a project to hold the new
logic parts (services or libraries, depending on your choices on the previous
page).
v In the UI Project Name field, select a project to hold the new Web pages
and JSF handler parts.
22. For each project, select the EGL Web Project field if you want the respective
project to be an EGL Web project.
23. Click Next.
24. The final page of the wizard shows a summary of your choices so far. You can
click Finish and complete the process or go back to previous pages and
change your selections.
25. After the projects and files are created, you might need to add the projects to
the EGL and Java build paths of other projects. See “The EGL build path” on
page 83.
Related concepts
SQL data access
Related tasks
“Creating an SQL database connection” on page 197
The New Connection wizard creates an SQL database connection that you can
use either at design time or at run time.
Related reference
displayName

Working with SQL statements


With EGL you can deal with explicit SQL code in your EGL program.

You can do some reasonably sophisticated database manipulation in EGL without


writing a word of SQL. Experienced SQL programmers, however, might want the
level of control that writing in SQL gives them. EGL accommodates those
programmers through the #sql directive.

The #sql directive


The EGL keyword #sql introduces a section of explicit SQL code, delimited by
braces, as in the following example:
get myCustomer with #sql{
select C_NUMBER, C_NAME, C_ADDR1, C_ADDR2, C_ADDR3, C_BALANCE
from ADMINISTRATOR.CUSTOMER L1
where C_NUMBER = :myCustomer.customerNumber };

You may modify this code to fine tune your SELECT statement. For more
information, see “Viewing implicit SQL statements” on page 217. You can also use
the #sql directive to call a stored procedure (see “Calling a stored procedure” on
page 212).

Host variables
You might have noticed in the preceding example that the variable
myCustomer.customerNumber has a colon in front of it. This tells EGL to look for the
variable name within the EGL program, not the SQL table. Such variables are
called host variables, because EGL is the programming language that is hosting SQL;
SQL cannot run as an independent language.
Related tasks

Accessing data with EGL code 211


“Executing a prepared statement” on page 215
The prepare keyword constructs an SQL statement from a string. Then, you can
run that prepared statement with another data-access statement.
“Calling a stored procedure”
You can call an SQL stored procedure with the open or execute statements and
the #sql directive.
“Viewing implicit SQL statements” on page 217

Calling a stored procedure


You can call an SQL stored procedure with the open or execute statements and the
#sql directive.

A stored procedure is a set of instructions for a database, like a function in EGL.


Stored procedures differ from prepared statements because the stored procedure is
kept permanently in the database itself, while a prepared statement is local to your
program or logic part and is cached by the database only temporarily. Also, a
stored procedure can consist of many SQL statements, while a prepared statement
can consist of only one SQL statement. Fundamentally, however, you can execute
the same instructions with a stored procedure as you can with a prepared
statement.

Prerequisites
v An EGL project and program or other logic part
v An SQL database with a stored procedure

Using execute to call a stored procedure

The execute keyword is appropriate for calling stored procedures that do not
return a result set. You can also use execute to call stored procedures that return
one or more result sets, but in that case any result sets are ignored.

To call a stored procedure with execute, use the #sql directive and specify the
name of the stored procedure in the explicit SQL:
execute #sql{
CALL MYSTOREDPROCEDURE
};

If the stored procedure accepts parameters, pass EGL variables as host variables
(see “Host variables” on page 211):
myParameter int = 5;
execute #sql{
CALL MYSTOREDPROCEDURE(:myParameter)
};

The following example uses a prepared statement in combination with the execute
statement:
prepare p1 from "CALL MYSTOREDPROCEDURE(?)";
execute p1 using myParameter;

Using open to call a stored procedure

You can use the open keyword to call only stored procedures that return exactly
one result set. To call a stored procedure that does not return a result set or that
returns more than one result set, use execute.

212 EGL Programmer’s Guide


To call a stored procedure with open, use the #sql directive and specify the name
of the stored procedure in the explicit SQL:
open myResultSet with #sql{
CALL GETCUSTOMERS
};

Then you can access the result set through the myResultSet identifier, as in the
following example, which assumes a SQLRecord part named myCustomers:
myCustomers myCustomers;
get next from myResultSet into myCustomers;

If the stored procedure accepts parameters, pass EGL variables as host variables:
myParameter int = 5;
open myResultSet with #sql{
CALL GETCUSTOMERS(:myParameter)
};

The following example uses a prepared statement in combination with the open
statement:
prepare p1 from "CALL GETCUSTOMERS(?)";
open myResultSet with p1 using myParameter;

Special considerations for the Oracle DBMS

When you work with an Oracle database, you can call either a stored procedure or
a stored function.

There are specific rules that apply to using the open statement to call a stored
procedure when you use an Oracle database:
v The procedure must have at least one parameter.
v The first parameter must be have an out or inOut modifier, and must be a REF
CURSOR type (an example of how to define this type is shown later). A variable
based on this type, called a cursor variable, can pass result sets between the
parts of a program.
v The SQL code that the open statement runs should represent the first parameter
of the procedure with a question mark.
v If the procedure call is in a prepared statement, do not include anything in the
using clause for the first parameter. If there are no other parameters, omit the
using clause.

In the first example, using the #sql directive, the procedure has no parameters
except the cursor variable:
open rs1 with #sql { call p1( ? ) };

In the next example, also using #sql, the procedure has two parameters in addition
to the cursor variable:
x int = 10;
y int = 1000;
open rs2 with #sql { call p2( ?, x, y ) };

In the next example, using a prepared statement, the procedure has no parameters
except the cursor variable:
prepare pstmt3 from "call p1( ? )";
open rs3 with pstmt3;

Accessing data with EGL code 213


In the next example, using a prepared statement, the procedure has two
parameters in addition to the cursor variable:
prepare pstmt4 from "call p2( ?, ?, ? )";
open rs4 with pstmt4 using x, y;

The following example shows one way to define a REF CURSOR type to Oracle.
(For other ways, refer to your Oracle documentation.)
execute #sql{ CREATE OR REPLACE PACKAGE MYPKG
AS
TYPE RC12 IS REF CURSOR;
END; };

The preceding code creates a new type named MYPKG.RC12 that you can use for
the type of a parameter that holds the results of a query. The following EGL code
defines a stored procedure that you can call using an EGL open statement:
execute #sql{ CREATE PROCEDURE ZPQPRM2( c IN OUT MYPKG.RC12, x IN CHAR )
AS
BEGIN
OPEN c FOR SELECT firstnme, empno FROM empx WHERE empno > x ORDER BY empno;
END; };

In addition, you can create stored functions in Oracle. A stored function is the
same as a stored procedure, except that it returns a value (Oracle’s stored
procedures cannot return a value). You can call an Oracle stored function from
EGL, using a slightly different SQL syntax than in the stored procedure call.

In this first example, the called function is passed a string and returns an integer:
x int;
y string = "hello";
execute #sql{ call :x := func1( :y ) };
writeStdout( "The function returned " :: x );

This next example calls the same function using a prepared statement:
prepare q from "call ? := func1( ? )";
execute q using x, y;
writeStdout( "The function returned " :: x );

EGL can call Oracle stored functions that return the results of a query. The
following rules apply:
v Call the function with an EGL open statement.
v The function must return a REF CURSOR type.
v The SQL code that the open statement runs must include a question mark to
represent the value that the function returns.
v If the function call is in a prepared statement, do not include anything in the
using clause for the first question mark. If the function has no parameters, omit
the using clause.

In the first example, using the #sql directive, the function has no parameters except
the cursor variable:
open rs5 with #sql { call ? := f5() };

In the next example, also using #sql, the function has two parameters in addition
to the cursor variable:
x int = 10;
y int = 1000;
open rs6 with #sql { call ? := f6( :x, :y ) };

214 EGL Programmer’s Guide


In the next example, using a prepared statement, the function has no parameters
except the cursor variable:
prepare pstmt7 from "call ? := f5()";
open rs7 with pstmt7;

In the next example, using a prepared statement, the function has two parameters
in addition to the cursor variable:
prepare pstmt8 from "call ? := f6( ?, ? )";
open rs8 with pstmt8 using x, y;

Limitations

The following limitations apply to using stored procedures in EGL:


v You can call stored procedures with open only if the stored procedure returns
exactly one result set.
v You cannot use open to call a stored procedure when generating for COBOL
platforms.
v You cannot call a stored procedure on a Microsoft SQL Server DBMS if the
stored procedure contains any out parameters.
Related tasks
“Executing a prepared statement”
The prepare keyword constructs an SQL statement from a string. Then, you can
run that prepared statement with another data-access statement.
“Viewing implicit SQL statements” on page 217
Related reference
SQL data access
open
open considerations for SQL
execute considerations for SQL
SQLRecord stereotype
#sql directive
Host variables
Host variables allow SQL statements to use EGL variables.

Executing a prepared statement


The prepare keyword constructs an SQL statement from a string. Then, you can
run that prepared statement with another data-access statement.

Using prepared statements instead of explicit SQL code can improve performance
for data access operations that you use repeatedly. When you create a prepared
statement, the database performs much of the processing necessary for the
statement ahead of time. Then, the database has to perform less processing when
you execute the prepared statement. Whether you use a prepared statement or
explicit SQL depends on how many times you use the data access operation.

Fundamentally, executing a prepared statement is no different from executing any


explicit SQL code. The following two functions are equivalent:
function executeExplicitSQL()
myCustomers myCustomers[0];
get myCustomers with #sql{
SELECT CUSTOMER_ID, LAST_NAME
FROM MYSCHEMA.MYTABLE
};

Accessing data with EGL code 215


end

function executePreparedStatement()
myCustomers myCustomers[0];
prepare myStatement from
"SELECT CUSTOMER_ID, LAST_NAME FROM MYSCHEMA.MYTABLE";
get myCustomers with myStatement;
end

The previous examples used the get statement to execute the prepared statement,
but you can also use execute or open. In each case, the prepared statement must
be appropriate for the data access statement. In other words, if you can execute the
string as explicit SQL, you can also prepare and execute the string as a prepared
statement. You can use prepare for standard SQL statements such as SELECT, for
dynamic SQL statements that include variables, and for calls to stored procedures.

Preparing and executing the statement

To prepare the statement, first create a string variable to hold the statement. Like
any string, you can assign a value to the variable directly or assemble the value
from multiple strings or variables:
myString string = "SELECT ";
myString += "CUSTOMER_ID, LAST_NAME ";
myString += "FROM MYSCHEMA.MYTABLE";

Then, use prepare to create the prepared statement from the variable, assigning the
statement to a new identifier:
prepare myStatement from myString;

Also, you can add a for clause to specify the SQLRecord to use with the prepared
statement:
myCustomer myCustomers;
prepare myStatement2 from myString for myCustomer;

Finally, execute the statement and put the results into a variable:
myCustomerArray myCustomers[];
get myCustomerArray with myStatement2;

Using variables in the prepared statement

Prepared statements are especially useful when you want to insert variables into
the statement. Variables in prepared statements are even more powerful than host
variables in normal explicit SQL code, because you can do more than just insert an
EGL variable value; you can change which variable the dynamic statement uses.

When creating a prepared statement, you use a question mark (?) to represent
variables. The question mark acts as a placeholder into which you can insert a
value later with the using clause:
myCustomerID int = 5;
myCustomerArray myCustomers[];
myHostVarString string = "SELECT CUSTOMER_ID, LAST_NAME";
myHostVarString += " FROM MYSCHEMA.MYTABLE";
myHostVarString += " WHERE CUSTOMER_ID = ?";
prepare myStatement from myHostVarString;
get myCustomerArray with myHostVarString using myCustomerID;

In this case, you can change the using myCustomerID clause to use different
variables in different situations.

216 EGL Programmer’s Guide


Creating a detailed prepared statement

EGL also provides a tool that creates a prepare statement and the related execute,
get, or open statement.
1. Within a function in your logic part, right-click a blank line and then click Add
SQL Prepare Statement. The Add SQL Prepare Statement window opens.
2. In the Prepared statement identifier field, type a name to identify the EGL
prepare statement. For rules, see ″Naming conventions″ in the EGL Language
Reference.
3. In the SQL record variable name field, select a record variable from the list or
type a name for a new variable and then select an SQL record part using the
Browse button. You must eventually define an SQL record variable with that
name in the EGL source code.
4. In the Execution statement type field, select execute,get, or open.
5. If you selected open in the Execution statement type field, type an identifier
for the result set in the Result set identifier field.
6. Click OK. EGL creates the prepare statement and related data access statement.
Related concepts
“Working with SQL statements” on page 211
With EGL you can deal with explicit SQL code in your EGL program.
Related tasks
“Calling a stored procedure” on page 212
You can call an SQL stored procedure with the open or execute statements and
the #sql directive.
Related reference
SQL data access
open
open considerations for SQL
execute considerations for SQL
SQLRecord stereotype
prepare considerations for SQL
#sql directive
Host variables
Host variables allow SQL statements to use EGL variables.
Naming conventions

Viewing implicit SQL statements


EGL creates implicit SQL statements whenever you use an EGL data-access
statement (such as add or get) that specifies an SQL record variable as its target.
This feature enables you to write functions that access a relational database even if
you do not know any SQL at all. It also enables you to generate default SQL code
that you can customize.

EGL can also display a default SELECT statement based on an SQL Record
definition.

The default SELECT statement: Right-click within the first line of an SQL Record
definition and select SQL Record. A second menu offers you the following choices:
Retrieve SQL
If you are in the process of defining the record, this option asks EGL to

Accessing data with EGL code 217


construct the record definition for you, based on fields in the database
table. See “Retrieving SQL table data” on page 205.
View Default Select
This option pops up a window that contains the SQL SELECT statement
that returns all information in the current record. You can copy the
contents of this window by highlighting it and pressing Ctrl+C.
Validate Default Select
This option compares the information in the SELECT statement to the
structure of the referenced SQL database and makes sure that such a query
would work correctly.

Implicit SQL statements: The opposite of an implicit SQL statement is an


embedded SQL statement. Here you include explicit SQL code as part of an EGL I/O
statement that is introduced by a #sql directive. For details of the #sql syntax, see
#sql directive.

To deal with the transformation of implicit SQL code to embedded SQL code,
right-click anywhere in an EGL I/O statement that references a record variable
based on a Record part with the SQLRecord stereotype. Choose SQL Statement
from the menu. The examples in this section all use the following Record part:
record CustomerRecord type SQLRecord
{tableNames = [["ADMINISTRATOR.CUSTOMER", "L1"]],
keyItems = [customerNumber]}

customerNumber STRING {column="C_NUMBER", maxLen=6};


customerName STRING {column="C_NAME", isSQLNullable=yes, maxLen=25};
customerAddr1 STRING {column="C_ADDR1", isSQLNullable=yes, maxLen=25};
customerAddr2 STRING {column="C_ADDR2", isSQLNullable=yes, maxLen=25};
customerAddr3 STRING {column="C_ADDR3", isSQLNullable=yes, maxLen=25};
customerBalance MONEY {column="C_BALANCE", isSQLNullable=yes};

end

The following options are available from the SQL Statement menu:
Add This option converts implicit SQL code to embedded SQL code and adds it
to your program. The Add option converts the simple I/O statement get
myCustomer to the following:
get myCustomer with #sql{
select
C_NUMBER, C_NAME, C_ADDR1, C_ADDR2, C_ADDR3, C_BALANCE
from ADMINISTRATOR.CUSTOMER L1
where
C_NUMBER = :myCustomer.customerNumber
};
Add with Into
This option functions the same as Add, but includes an EGL into clause for
the field names in the EGL record variable. This is useful if you want to
update only some of the fields; you can remove the field names you do not
want to update from the into and select clauses:
get myCustomer
into myCustomer.customerNumber, myCustomer.customerName,
myCustomer.customerAddr1, myCustomer.customerAddr2,
myCustomer.customerAddr3, myCustomer.customerBalance with
#sql{
select
C_NUMBER, C_NAME, C_ADDR1, C_ADDR2, C_ADDR3, C_BALANCE

218 EGL Programmer’s Guide


from ADMINISTRATOR.CUSTOMER L1
where
C_NUMBER = :myCustomer.customerNumber
};
View This option displays the implicit SQL code without adding to the code.
You can, however, highlight the code in the pop-up display and copy it by
pressing Ctrl+C. From the View dialog you also have the option to Add,
Add with Into, Reset, and Validate the SQL statement.
Validate
This option checks to see whether the implicit SQL code is well-formed
and will work correctly.
Remove
This option removes the embedded SQL code and returns you to your
original I/O statement.
Reset If you have edited the embedded code that EGL added to your program,
this will undo all of your edits and restore the original embedded code.
Related concepts
“Accessing data with EGL code” on page 183
Related tasks
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
“Retrieving SQL table data” on page 205
Related reference
SQLRecord stereotype
#sql directive

Setting preferences for SQL database connections


In the workbench, you use database connections in two ways:
v When you are developing your programs. For example, you need this
connection when you use the EGL SQL retrieve feature; see “Setting preferences
for SQL retrieve” on page 220.
v When you are running or debugging your programs.

To create a new connection using the New Connection wizard, see “Creating an
SQL database connection” on page 197, or use the following steps to set up or edit
the connections:
1. Click Window → Preferences.
2. When a list of preferences is displayed, expand EGL, then click SQL Database
Connections.
3. The currently selected connection in the Connection list is the default database
for EGL in the workbench. You can switch between database connections, edit
or delete the connections, and test the connections from this window.
4. To create a new connection, click New. For an explanation of the preference
fields, see “Fields in the New Connection wizard” on page 198.
5. If you are using DB2 you might need to set the Secondary Authentication ID
field. See ″Secondary Authentication ID″ in this topic.

You can clear or apply preference settings:


v To restore default values, click Restore Defaults.
v To apply preference settings without exiting the preferences dialog, click Apply.

Accessing data with EGL code 219


v If you are finished setting preferences, click OK.

Secondary Authentication ID
The secondary authentication ID is more commonly known as the secondary
authorization ID. The meaning and use of the secondary authorization ID depends
on the following conditions:
v The DB2 platform you are using.
v In some cases, the way that platform is configured.
To fully understand how a secondary authorization ID can be used for your
environment, refer to your DB2 documentation.

Here are common examples of the secondary authorization ID:


v For DB2 UDB, if you specify a secondary authorization ID, that ID is used as the
default schema name for all SQL statements.
v For DB2 on zOS, a secondary authorization ID is often mapped to a RACF®
group. Access rights to DB2 objects are granted to the RACF group and
individual user IDs are added to the RACF group. This technique minimizes
work when your authorization requirements change. For example, if a new DB2
table is created, the system administrator can grant access to a RACF group; all
individuals belonging to that group then get read access, as long as they are
using the secondary authorization ID.
Related tasks
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related reference
dbms
sqlJNDIName

Setting preferences for SQL retrieve


At EGL declaration time, you can use the SQL retrieve feature to create an SQL
record from the columns of an SQL table.

To set preferences for the SQL retrieve feature, do as follows:


1. Click Window → Preferences, expand EGL and then click SQL
2. Specify rules for creating each structure field that the SQL retrieve feature
creates:
a. To specify the EGL type to use when creating a structure field from an SQL
character data type, click one of the following radio buttons:
v Use EGL type string (the default) maps SQL char data types to EGL
string data types.
v Use EGL type limited-length string maps SQL char data types to EGL
limited-length string data types.
v Use EGL type char maps SQL char data types to EGL char data types.
v Use EGL type mbChar maps SQL char data types to EGL mbChar data
types.
v Use EGL type Unicode maps SQL char data types to EGL Unicode data
types.
b. To specify the EGL type to use when creating a structure field from an SQL
national character data type, click one of the following radio buttons:

220 EGL Programmer’s Guide


v Use EGL type dbChar (the default) maps the SQL type to EGL dbChar
data types.
v Use EGL type Unicode maps the SQL type to EGL Unicode data types.
v Use EGL type string maps the SQL type to EGL string data types.
v Use EGL type limited-length string maps the SQL type to EGL
limited-length string data types.
c. To specify the case of the structure field name, click one of the following
radio buttons:
v Do not change case (the default) means that the case of the structure field
name is the same as the case of the related table column name.
v Change to lower case means that the structure field name is a lower-case
version of the table column name.
v Change to lower case and capitalize first letter after underscore also
means that the structure field name is a lower-case version of the table
column name, except that a letter in the structure field name is rendered
in uppercase if, in the table column name, the letter immediately follows
an underscore.
d. To specify how the underscores in the table column name are reflected in
the structure field name, click one of the following radio buttons:
v Do not change underscores (the default) means that underscores in the
table column name are included in the structure field name.
v Remove underscores means that underscores in the table column name
are not included in the structure field name.
3. If you want new SQL records to be compatible with COBOL programs (that is,
to have fixed records with level numbers for structure items, and to use CHAR
instead of STRING primitive types), select the Add level numbers to record
definition check box.
4. If you want new SQL records to have the key field property set, select the
Retrieve primary key information from the system catalog check box.
5. If you want to be prompted for a database password if you did not supply one
for the connection on the SQL Database Connections page, select the Prompt
for SQL user ID and password when needed check box.
6. Click Apply to save the changes and remain in the Preferences window. Click
OK to save the changes and exit the window.
Related concepts
“Accessing data with EGL code” on page 183
Related tasks
“Retrieving SQL table data” on page 205
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
“Setting preferences for SQL database connections” on page 219
“Secondary Authentication ID” on page 220

Working with DL/I data


IBM developed DL/I (Data Language/One) in the 1960s as a hierarchical database
management system. DL/I remains a widely used database system in COBOL
programs today.

The following terms and concepts are essential in developing a DL/I database
program:

Accessing data with EGL code 221


Segments
The primary unit of data in a DL/I database is the segment. A segment is
similar to a record. It is a single block of data divided into data fields.
Database Hierarchy
A single database can contain many types of segments. These segments are
arranged in a hierarchical (top down) relationship. The segment at the top of
the hierarchy is called a root segment. Each segment can have one or more
dependent segments related to it at a lower level in the hierarchy. A segment
with a dependent segment is called the parent of the dependent segment. The
dependent segment is called a child segment. Each segment in the database,
except for a root segment, has one and only one parent. The root segment has
no parent.
Sequence Field
Each segment type in a database can have one of its fields designated as a
sequence field. The value of the sequence field determines the order in which
the segments are stored and retrieved from the database. When a parent
segment has multiple occurrences of the same child segment type and a
sequence field is defined for the child segment, DL/I stores those child
segments in sequence field order under that parent.
Program Specification Block (PSB)
A PSB is a formal DL/I description of the hierarchical database structures that
a program can access. The EGL record part of type PSBRecord contains the
information that your program needs to interact with the DL/I PSB. The PSB
shows the hierarchical relationships that exist between types of segments. For
more information, see Data access using PSBs and PCBs in the EGL Language
Reference.
Program Communication Block (PCB)
A PCB is an entry in a PSB. Each database PCB describes one hierarchical data
structure that a program can use. The data structure might correspond directly
to the structure of a physical or logical DL/I database or might invert the
database structure through access by a secondary index.
DL/I call
A DL/I call is an invocation of DL/I by a program. The parameter list passed
for a database call provides DL/I with the following information:
Function code
Indicates if DL/I is to get, insert, replace, or delete segments from the
database.
Database identifier
For DL/I calls using CBLTDLI, points to the program communication block
(PCB) that identifies the database that DL/I is to access on the call. For
DL/I calls using AIBTDLI, provides the name of the PCB in the PSB.
I/O area address
Identifies the address of the buffer that contains the segment after it is read
from the database or before it is written to the database.
Segment search argument (SSA) list
Lists a set of search criteria that enables DL/I to select the segments that it
retrieves from the database or specify the position of segments it inserts
into the database.

When you code a DL/I program in a language like COBOL or PL/I, you either
code the DL/I parameter list directly or use the command level interface of

222 EGL Programmer’s Guide


CICS to create the DL/I parameter list. EGL creates DL/I parameter lists for
you based on the I/O statement and the position of the DL/I segment in the
PCB.. You can view the DL/I call created for the function. You can also modify
the DL/I call to use additional DL/I functions.
Database position
When a program is running, DL/I maintains a position pointer for each PCB in
the program PSB. The pointer indicates the place in the database where a get
next statement begins searching for the segment to retrieve.
The position pointer is set on any successful DL/I call to point to the segment
following the last segment accessed on the call. If no calls are issued, the
current position indicates the start of the database. If the end of database
condition is encountered, the current position becomes the start of the
database.
As DL/I continues searching a database for a segment that satisfies the SSA list
criteria, DL/I accesses each root segment in the order it appears in the
database. When DL/I finds a root segment, it accesses all the dependents of
the root before scanning the next root. As DL/I scans the dependent segments,
it first tries to read the next segment at the next lower level. If there is not a
lower level, it reads the next segment at the same level. If there are no more
segments at the current level, it returns to the previous level to search for the
next segment. This process is called the “top to bottom, left to right” search
order.

You can write EGL programs that access DL/I databases by using many of the
same EGL statements you would use to access a relational database: add, delete,
get, and replace. When your EGL statement specifies a record variable based on
the DLISegment stereotype, EGL knows to generate code that works with a DL/I
database.

As with SQL, you can write DL/I programs entirely in EGL, or you can specify
explicit DL/I code to get more control of the details. In this case you write DL/I
pseudocode, and EGL translates it into actual DL/I commands.

For a diagram of an example DL/I database layout, see “Example DL/I database.”
For sample solutions to common DL/I coding problems, see “DL/I examples” on
page 227.
Related concepts:
Data access using PSBs and PCBs
Use program specification blocks (PSBs) and program communication blocks
(PCBs) to describe the logical structures in a program you generate for COBOL.
DL/I database support
EGL supports DL/I (Data Language/I), a hierarchical data base manager for
COBOL environments.
DLISegment stereotype
The DLISegment stereotype specializes a Record part for use with a hierarchical
database.
“Example DL/I database”
“DL/I examples” on page 227

Example DL/I database


To provide a consistent experience and to let each example build on others, this
documentation uses the same example DL/I database wherever possible. This

Accessing data with EGL code 223


customer database has basic customer information at the root level. For each
customer there are segments for credit status, history, and individual locations.
Each location has order segments, and each order has item segments.

Database layout
The following database is named CUSTOMER:

CUSTOMER
NAME/
ADDRESS
(STSCCST)

CUSTOMER CREDIT CUSTOMER


LOCATION STATUS HISTORY
(STSCLOC) (STSCSTA) (STSCHIS)

CUSTOMER
ORDER
(STPCORD)

ITEM
(STLCITM)

The following details refer to the example database:


v The location number in the location segment is unique for each customer.
v The order segment is a concatenated segment containing data from two
segments that are connected by a logical relationship. The item description,
quantity on hand, quantity on order, quantity reserved, unit price, and unit of
issue are all physically stored in a separate inventory database. From the
program’s point of view, due to the logical relationship between the two
segments, this information is presented as if it was part of the order item
segment.

224 EGL Programmer’s Guide


v There is only one credit segment per customer so no key field is necessary.
v The history segment is a variable length segment.

EGL DLISegment Records


EGL represents each of these segments in your program as records of type
DLISegment. The following code sample shows how you can define this database
structure in EGL. From time to time we will also show examples of DL/I calls
using DL/I versions of segment and field names (8 characters maximum). Those
DL/I names are also shown in the example.
//define records to match segments in DL/I db
Record CustomerRecordPart type DLISegment
{ segmentName="STSCCST", keyItem="customerNo" }
10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field
10 customerName char(25) { dliFieldName = "STUCCNM" };
10 customerAddr1 char(25) { dliFieldName = "STQCCA1" };
10 customerAddr2 char(25) { dliFieldName = "STQCCA2" };
10 customerAddr3 char(25) { dliFieldName = "STQCCA3" };
end

Record LocationRecordPart type DLISegment


{ segmentName="STSCLOC", keyItem="locationNo" }
10 locationNo char(6) { dliFieldName = "STQCLNO" }; //key field
10 locationName char(25) { dliFieldName = "STFCLNM" };
10 locationAddr1 char(25) { dliFieldName = "STFCLA1" };
10 locationAddr2 char(25) { dliFieldName = "STFCLA2" };
10 locationAddr3 char(25) { dliFieldName = "STFCLA3" };
end

Record OrderRecordPart type DLISegment


{ segmentName="STPCORD", keyItem="orderDateNo" }
10 orderDateNo char(12) { dliFieldName = "STQCODN" }; //key field
10 orderReference char(25) { dliFieldName = "STFCORF" };
10 orderItemCount num(6) { dliFieldName = "STFCOIC" };
10 orderAmount decimal(12,2) { dliFieldName = "STFCOAM" };
end

Record ItemRecordPart type DLISegment


{ segmentName="STLCITM", keyItem="itemKey" }
10 itemKey char(8); { dliFieldName = "STKCCKEY" }; //key field
15 itemInventoryNo char(6) { dliFieldName = "STKCIIN" };
15 itemLineNo smallint { dliFieldName = "STQCILI" };
10 itemQtyOrdered num(6) { dliFieldName = "STFCIQO" };
10 itemQtyShipped num(6) { dliFieldName = "STFCIQS" };
10 itemQtyBackOrdered num(6) { dliFieldName = "STFCIQB" };
10 itemAmount decimal(12,2) { dliFieldName = "STFCIAM" };
10 itemNumber char(6) { dliFieldName = "STQIINO" };
10 itemDescription char(25) { dliFieldName = "STFIIDS" };
10 itemQtyOnHand num(6) { dliFieldName = "STFIIQH" };
10 itemQtyOnOrder num(6) { dliFieldName = "STFIIOH" };
10 itemQtyReserved num(6) { dliFieldName = "STFIIQR" };
10 itemUnitPrice char(6) { dliFieldName = "STFIIPR" };
10 itemUnitOfIssue char(1) { dliFieldName = "STFIIUN" };
end

Record CreditRecordPart type DLISegment


{ segmentName="STSCSTA" }
10 creditLimit decimal(12,2) { dliFieldName = "STFCSCL" };
10 creditBalance decimal(12,2) { dliFieldName = "STFCSBL" };
end

Record HistoryRecordPart type DLISegment


{ segmentName="STSCHIS", lengthItem="historySegmentLength",
keyItem="historyDateNo" }
10 historySegmentLength smallint { dliFieldName = "STGCSL" };
10 historyDateNo char(12) { dliFieldName = "STQCHDN" };

Accessing data with EGL code 225


10 historyReference char(25) { dliFieldName = "STFCHRF" };
10 historyItemCount smallint { dliFieldName = "STFCHIC" };
10 historyAmount decimal(12,2) { dliFieldName = "STQCHAM" };
10 historyStatus char(77) { dliFieldName = "STQCLOS" };
end

IMS PSB
In the following PSB definition on the host, the DBDNAME is set to CUSTOMER,
the name of the database. A PCB is defined with the name STDCDBL; the
customerPCB in the next section sets the pcbName property to this name.
TITLE 'PSB FOR PROCESSING SAMPLE DATA BASES'
ELAALT PCB TYPE=TP,MODIFY=YES
ELAEXP PCB TYPE=TP,MODIFY=YES,EXPRESS=YES
STDCDBL PCB TYPE=DB,DBDNAME=CUSTOMER,PROCOPT=AP,KEYLEN=50,POS=S
SENSEG NAME=STSCCST,PARENT=0
SENSEG NAME=STSCLOC,PARENT=STSCCST
SENSEG NAME=STPCORD,PARENT=STSCLOC
SENSEG NAME=STLCITM,PARENT=STPCORD
SENSEG NAME=STSCSTA,PARENT=STSCCST
SENSEG NAME=STSCHIS,PARENT=STSCCST
PSBGEN LANG=ASSEM,CMPAT=YES,PSBNAME=STBICLG
END

EGL PSBRecord
The following code represents the IMS PSB in the EGL program:
//define overall db layout in PSB
Record CustomerPSBRecordPart type PSBRecord { defaultPSBName="STBICLG" }
// three PCBs required for CBLTDLI on IMS
iopcb IO_PCBRecord { @PCB { pcbType = PCBKind.TP } };
elaalt ALT_PCBRecord { @PCB { pcbType = PCBKind.TP } };
elaexp ALT_PCBRecord { @PCB { pcbType = PCBKind.TP } };

// database PCB
customerPCB DB_PCBRecord { @PCB {
pcbType = DB,
pcbName = "STDCDBL",
hierarchy = [
@relationship { segmentRecord = "CustomerRecordPart" },
@relationship {
segmentRecord = "LocationRecordPart", parentRecord = "CustomerRecordPart" },
@relationship {
segmentRecord = "OrderRecordPart", parentRecord = "LocationRecordPart" },
@relationship {
segmentRecord = "ItemRecordPart", parentRecord = "OrderRecordPart" },
@relationship {
segmentRecord = "CreditRecordPart", parentRecord = "CustomerRecordPart" },
@relationship {
segmentRecord = "HistoryRecordPart", parentRecord = "CustomerRecordPart" }]}};
end

Sample EGL program


The following program outline is set up to use the CUSTOMER database:
program PrintCatalog type basicProgram { alias="PRINT",
@DLI{
psb = "myPSB",
callInterface = CBLTDLI } }

//create variables for the records


myCustomer CustomerRecordPart;
myLocation LocationRecordPart;
myOrder OrderRecordPart;
myItem ItemRecordPart;
myCrStatus CreditRecordPart
myHistory HistoryRecordPart

226 EGL Programmer’s Guide


myPSB CustomerPSBRecordPart;

function main()
...
end
end
Related concepts:
“Working with DL/I data” on page 221
Related reference:
DL/I database support
EGL supports DL/I (Data Language/I), a hierarchical data base manager for
COBOL environments.

DL/I examples
These DL/I examples use the same example DL/I database as described in
Example DL/I database. Following are some examples of typical techniques for DL/I
database I/O:
v “Searching within a parent segment”
v “Searching with another non-key field”
v “Searching based on information in another record” on page 228
v “Searching for a non-root segment” on page 229
v “Searching with a secondary index” on page 230
v “Using path calls to access multiple segments” on page 232
v “Reading all segments with a single I/O statement” on page 232
v “Using dynamic arrays” on page 233

Searching within a parent segment


The default get next statement starts at the current position in the database and
searches through the entire database for the next occurrence of the target segment
under any parent. To limit the scope of the search to the currently established
dependent chain, use the get next inParent statement.

Consider the situation in which you want to retrieve the items for a particular
order. You can use the following to retrieve the order:
get myOrder with #dli {
GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
STSOCORD (STQCODN = :myOrder.orderDateno) };

Then you can use the following to retrieve the line segments within the order:
get next inParent myItem;
while (myItem not noRecordFound)
// process the current item
get next inParent myItem;
end

EGL creates the following pseudo-DL/I code for the get next inParent statement:
GNP STLCITM

Searching with another non-key field


You can use any field in a segment as a search argument on a DL/I call by
modifying the search arguments (SSAs) for the call. For example, if you wanted to
read through the customer database and retrieve the customer segment and credit

Accessing data with EGL code 227


segment for each customer with a credit balance greater than a specified amount,
you would define the DL/I call search arguments as follows:
1. You want to search on the creditBalance field (STFCSBL) in the credit segment
(STSCSTA). To do this, define a variable of type decimal(12,2) (for example,
″targetBalance″) that contains the specified amount that you want to search for.
The definition for targetBalance should match the definition for the
creditBalance field in the credit segment.
2. Write a get next statement for the myCrStatus record.
3. Add a #dli directive to the line, modifying the default code. Add a qualified
SSA that looks for a segment where the amount in the creditBalance field is
greater than targetBalance.
4. Include a path command code (*D) to retrieve the customer segment
(STSCCST) that corresponds to the credit segment.
The following sample code illustrates this process:
targetBalance decimal(12,2);
targetBalance = 10,000.00;

get next myCustomer,myCrStatus with #dli{


GU STSCCST*D STSCSTA (STFCSBL >= :targetBalance) };

Searching based on information in another record


You might want to search based on information in another record. Consider the
situation in which the customer number is passed to the program in a parameter
record as follows:
Record CustomerData type basicRecord
10 customerNo char(6)
...
end

Program myProgram
(customerParm CustomerData)
{ @DLI{ psb = "myCustomerPSB" }}
//declare variables
myCustomerPSB CustomerPSBRecordPart;
myCustomer CustomerRecordPart;

You want to retrieve the customer segment based on the value in


customerParm.customerNo. There are three ways to code this as follows:
v Assign the value of customerParm.customerNo to myCustomer.customerNo and
then use implicit DL/I I/O as follows:
myCustomer.customerNo = CustomerParm.customerNo;
get myCustomer;
In this case, EGL creates the normal default SSAs, resulting in the following
pseudo-DL/I code:
GU STSCCST (STQCCNO = :myCustomer.customerNo)

The advantage of this technique is that it is very simple. The disadvantage is the
very slight performance overhead of moving the customer number to the
segment record.
v Use the #dli directive and explicit DL/I I/O so that you can use the
customerParm.customerNo field as the host variable as follows:
get myCustomer with #dli {
GU STSCCST (STQCCNO = :customerParm.customerNo) } ;

228 EGL Programmer’s Guide


This technique avoids the performance overhead of moving the customer
number. However, it does take slightly longer to paste in the default #dli
directive and then modify the code to use the correct record variable name for
the parameter record.
v Add the hostVarQualifier property in the DLISegment record to specify the
qualifier for the host variable as follows:
Record CustomerRecordPart type DLISegment
{segmentName="STSCCST", keyItem="customerNo",
hostVarQualifier="customerParm" }
10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field
...
end
Then you can use implicit DL/I I/O without having to first assign
customerParm.customerNo to myCustomer.customerNo as follows:
get myCustomer;
The pseudo-DL/I code that EGL creates in this case is:
GU STSCCST (STQCCNO = :customerParm.customerNo)
The advantage of this technique is that it results in the same pseudo-DL/I code
that you coded for the #dli directive, without you actually having to code the
#dli directive. The disadvantage is that EGL now uses customerParm as the
qualifier for every implicit DL/I database I/O statement that uses the
CustomerRecordPart.

Searching for a non-root segment


You can use implicit DL/I database I/O to retrieve a non-root segment. EGL
creates the entire chain of SSAs for you based on the hierarchical position of the
target segment in the PCB. However, for the higher level segments in the hierarchy,
EGL cannot automatically determine the name of the program variable to use as
the qualifier for the segment.

Consider the situation where the customer segment STSCCST is the parent of the
location segment STSCLOC and you want to retrieve only the data for the location
segment. You have defined the following record variables in your program:
myCustomer CustomerRecordPart;
myLocation LocationRecordPart;

If you use the following get statement:


get myLocation;

EGL will create the following pseudo-DL/I code:


GU STSCCST (STQCCNO = :CustomerRecordPart.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)

Notice that while EGL correctly associated the variable myLocation with the
segment STSCLOC, EGL was unable to find the variable myCustomer that is based
on the CustomerRecordPart. EGL only knows that myLocation is of type
LocationRecordPart, whose parent segment is CustomerRecordPart, and that the
keyItem for CustomerRecordPart is customerNo.

You can solve this problem in several ways:


v You can name your record variables with the same name as the record parts on
which they are based. For example, change the variable declaration for
myCustomer to CustomerRecordPart.
CustomerRecordPart CustomerRecordPart;

Accessing data with EGL code 229


EGL creates the same pseudo-DL/I code:
GU STSCCST (STQCCNO = :CustomerRecordPart.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
Because EGL creates the default SSAs from the PCB hierarchy information, this
is an easy way of ensuring that the variable names EGL uses match your
program’s record variable declarations. The disadvantage is that this technique
does not follow the general practice of using different names for parts and
variables.
v Use the #dli directive and explicit DL/I database I/O as follows:
get myLocation with #dli {
GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
The advantage of this technique is that it is very clear which host variables are
being used. It is an easy technique to use if the host variable qualifier or field
name is different from the record variable that is based on the DL/I segment
record. The disadvantage is the same as for any explicit I/O -- if the hierarchy or
the key fields change, the explicit DL/I database I/O statement does not change
automatically.
v Modify your definition for CustomerRecordPart to include the hostVarQualifier
property as follows:
Record CustomerRecordPart type DLISegment
{ segmentName="STSCCST", keyItem="customerNo",
hostVarQualifier = "myCustomer" }
10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field
...
end

Now if you use the following get statement:


get myLocation;

EGL will produce the correct pseudo-DL/I code:


GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
The advantage of this technique is that you can use implicit DL/I database I/O
and have different names for the record variables and the DL/I segment records.
The disadvantage is that EGL now uses myCustomer as the qualifier for every
implicit DL/I database I/O statement that uses the CustomerRecordPart.

Searching with a secondary index


Sometimes the DL/I PSB indicates that a database structure is to be accessed with
a secondary index. When this situation occurs, your database administrator enters
an index key name next to the root segment in the runtime PCB definition. You
notify EGL about the use of a secondary index by including the secondaryIndex
property in the PCB record within the PSBRecord. For example, if you have
another view of the customer database in which customerName is the secondary
index, then you can add an additional PCB record to the PSB Record part as
follows:
// database PCB for customer by Name
customerNamePCB DB_PCBRecord
{ @PCB { pcbType = DB, pcbName = "STDCNAM",
secondaryIndex = "STUCCNM",
hierarchy = [ @relationship { segmentRecord = "CustomerRecordPart" },
... ] }
}

230 EGL Programmer’s Guide


The pcbName property must match an actual DL/I database PCB in the runtime
PSB. The secondaryIndex property must provide the same field name as your
database administrator specifies in the XDFLD statement of the runtime PCB.
There are now two PCB records in the PSB record that include the
CustomerRecordPart in their hierarchy.

If you issue a get statement to locate a customer, as in the following example:


myCustomer CustomerRecordPart;
get myCustomer;

EGL will create the pseudo-DL/I code based on the first PCB record in the PSB
record that includes the CustomerRecord part.

If the secondary index database is the second PCB record in the PSB record, you
must include the usingPCB keyword, as in the following example so that EGL will
use the correct PCB:
get myCustomer usingPCB customerNamePCB;

EGL will create the following pseudo-DL/I code:


GU STSCCST (STUCCNM = :myCustomer.customerName)

Notice that EGL used the record variable name from the get statement
(myCustomer) and the PCB specified by the usingPCB keyword
(customerNamePCB) to find the following information:
v The DL/I name of the segment (property segmentName = "STSCCST").
v The DL/I name of the secondary index field (property secondaryIndex =
"STUCCNM").
v The EGL field name for the comparison value (property dliFieldName =
"STUCCNM" and then the corresponding field name customerName).

In some cases, there might be a secondary index on a lower level segment in the
physical database. In this case, the database structure is inverted. For example, if
there is a secondary index on the orderReference field in the order segment, the
database hierarchy as viewed by your program needs to be reflected in the
corresponding PCB record is as follows:
// orders view of customer database
ordersByReferencePCB DB_PCBRecord
{ @PCB { pcbType = DB, pcbName = "STDCDBL",
secondaryIndex = "STFCORF", //use DL/I name
hierarchy = [
@relationship { segmentRecord = "OrderRecordPart" },
@relationship { segmentRecord = "LocationRecordPart",
parentRecord = "OrderRecordPart" },
@relationship { segmentRecord = "CustomerRecordPart",
parentRecord = "LocationRecordPart" },
@relationship { segmentRecord = "ItemRecordPart",
parentRecord = "OrderRecordPart" }
]}
};
end

Assuming the order reference number is unique to each customer and order, the
you do not need to use keys for the location and customer segments. Assuming the
ordersByReferencePCB is now your default PCB, you can retrieve both the order
and the customer by modifying the SSA to delete the comparison for the location
and customer segments as follows:

Accessing data with EGL code 231


get myOrder, myCustomer with #dli{
GU STPCORD*D (STQCODN = :myOrder.orderReference)
STSCLOC
STSCCST };

Using path calls to access multiple segments


If you invoke an EGL I/O statement with a dependent segment record object, you
can read in any of the segments on the path from the root to the object at the same
time. You can do this simply by adding the records for the path call to the
statement. For example, when retrieving an order segment from our example
customer database, you can read in the customer, location, and order segments on
the same call:
get myCustomer, myLocation, myOrder;

This statement generates the following DL/I pseudocode:


GU STSCCST*D (STQCCNO = :myCustomer.customerNo)
STSCLOC*D (STQCLNO = :myLocation.locationNo)
STPCORD (STQCDDN = :myOrder.orderDateNo)

If you use the D command code on a get...forUpdate statement, the subsequent


replace statement affects every segment retrieved. You can prevent replacement of
a selected segment by specifying an explicit N command code in the SSA for the
replace keyword, as in the following example, which replaces only the location
and order segments:
get myCustomer, myLocation, myOrder forUpdate;
replace myOrder with #dli{
REPL STSCCST*N
STSCLOC*N
STPCORD };

The default DL/I call EGL builds for a delete function that follows a get
forUpdate statement with D command codes does not delete each segment
retrieved. It deletes only the target segment specified on the delete statement.

Reading all segments with a single I/O statement


You can use a single I/O statement to read all segments in a database. If you issue
a DL/I get next statement with no SSAs, DL/I returns the next segment in the
database regardless of its type. Follow these steps to use this technique:
1. Write a get next statement for the record that represents the largest segment in
the database. This ensures that any segment you read will not exceed allocated
memory.
2. Add the default DL/I call to your code. Edit the #dli directive to delete the
single SSA.
3. Create records matching the other segments in the database. Declare the records
in the program and specify that each of the records redefines the record used in
step 1 above so that all the records occupy the same area of memory.
4. Check dliVar.segmentName after the get next statement to determine the type
of segment that was retrieved.
5. Access the retrieved segment from the corresponding record structure.
Here is an example of code that will print everything in the customer database. In
this example, HistoryRecordPart is the largest DLISegment record:
myHistory HistoryRecordPart
redefCustomer CustomerRecordPart {redefines=myHistory};
redefLocation LocationRecordPart {redefines=myHistory};
...

232 EGL Programmer’s Guide


//read next segment, whatever type it is, into history record
while (myHistory not EOF)
get next myHistory with #dli{
GN };

//so what type was it?


case (dliVar.segmentName)
when "STSCCST" // it was a customer
printCustomer();
when "STSCLOC" // it was a location
printLocation();
...
end
end

Using dynamic arrays


You can use the get and get next statements to retrieve DL/I segments to a
dynamic array. Because there is no key field for the array itself (only for members
of the array), you must use some special techniques so that EGL will create the
correct code.

Consider the situation in which you have defined record variables and a dynamic
array as follows:
myCustomer CustomerRecordPart;
myLocation LocationRecordPart;
myOrder OrderRecordPart;
myOrderArray OrderRecordPart [] {maxsize = 20}; // array of orders

You can use a get statement to fill the array the first time and a get next statement
to retrieve a second group of 20 orders as follows:
myCustomer.customerNo = "123456";
myLocation.locationNo = "ABCDEF";
myOrderDateNo = "20050730A003";
get myOrderArray; // fill the array the first time
... do some processing
get next myOrderArray; // get the next batch of 20 orders

EGL creates the following pseudo-DL/I code for the get statement:
get myOrderArray with #dli{
GU STSCCST (STQCCNO = :CustomerRecordPart.customerNo)
STSCLOC (STQCLNO = :LocationRecordPart.locationNo)
STPCORD (STQCODN = :OrderRecordPart.orderDateNo)
GN STPCORD };

EGL creates the following pseudo-DLI code for the get next statement:
get next myOrderArray with #dli{
GN STPCORD };

Filling the dynamic array for the first batch of 20 orders with a get statement
requires an initial GU call followed by a loop of GN calls until the array is full or
DL/I runs out of segment occurrences. In the pseudo-DL/I code that EGL creates,
the GU call retrieves the first order segment. EGL treats the GN call as a loop and
provides the logic to loop until the array is full or DL/I runs out of segment
occurrences. Similarly, EGL treats the get next statement as a loop and provides the
loop control logic for you.

The get next statement provides the correct pseudo-DL/I code to retrieve the
second batch of orders. However, the pseudo-DL/I code for the get statement is

Accessing data with EGL code 233


not exactly correct -- the names of the qualifiers for the host variables are not the
names of the record variables in your program. You can solve this problem in
several ways:
v Name your DL/I segment records with the same name as the segments in the
DL/I database. Also change your record variable names to be the same name as
the segments in the DL/I database. For example, change the customer record
part definition from the following:
Record CustomerRecordPart type DLISegment
{ segmentName="STSCCST", keyItem="customerNo" }
10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field
...
end

to the following:
Record STSCCST type DLISegment
{ segmentName="STSCCST", keyItem="customerNo" }
10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field
...
end
Make similar changes for the location segment (STSCLOC) and the order
segment (STPCORD). Then change your PSB record to use the new names as
follows:
Record CustomerPSBRecordPart type PSBRecord { defaultPSBName="STBICLG" }
// database PCB
customerPCB DB_PCBRecord { @PCB { pcbType = DB, pcbName = "STDCDBL",
hierarchy = [ @relationship { segmentRecord = "STSCCST" },
@relationship {segmentRecord="STSCLOC",
parentRecord="STSCCST"},
@relationship {segmentRecord="STPCORD",
parentRecord="STSCLOC"}
]}};

end
Change the declaration of your record variables and myOrderArray so that they
reference the new DL/I segment record parts as follows:
STSCCST CustomerRecordPart;
STSCLOC LocationRecordPart;
STPCORD OrderRecordPart;
myOrderArray STPCORD [] {maxsize = 20}; // array of orders
Now when you issue the following get statement:
get myOrderArray; // fill the array the first time

EGL creates the following pseudo-DL/I code for the get statement and the host
variable qualifiers use the correct record variable names:
get myOrderArray with #dli{
GU STSCCST (STQCCNO = :STSCCST.customerNo)
STSCLOC (STQCLNO = :STSCLOC.locationNo)
STPCORD (STQCODN = :STPCORD.orderDateNo)
GN STPCORD };
Because EGL creates the default SSAs from the PCB hierarchy information, this
is an easy way of ensuring that the variable names EGL uses match your
program’s record variable declarations. The disadvantage is that this technique
does not follow the general practice of using different names for parts and
variables.
v Use the #dli directive and explicit DL/I database I/O as follows:

234 EGL Programmer’s Guide


get myOrderArray with #dli{
GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
STPCORD (STQCODN = :myOrder.orderDateNo)
GN STPCORD };
The advantage of this technique is that it is very clear which host variables are
being used. This technique is particularly useful if you must change the default
DL/I code -- for example if you do not know the first order number for the
customer and want to use the following DL/I code:
myOrder.orderDateNo = "";
get myOrderArray with #dli{
GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
STPCORD (STQCODN >= :myOrder.orderDateNo) // using >= instead of =
GN STPCORD };
The disadvantage of this technique is the same as for any explicit I/O -- if the
hierarchy or the key fields change, the explicit DL/I database I/O statement
does not change automatically.
v Modify the definition for each of your DL/I segment records to include the
hostVarQualifier property with the name of your program record variable. For
example, change the CustomerRecordPart to the following:
Record CustomerRecordPart type DLISegment
{ segmentName="STSCCST", keyItem="customerNo",
hostVarQualifier = "myCustomer" }
10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field
...
end
Now if you use the following record declarations and get statement:
myCustomer CustomerRecodPart;
myLocation LocationRecordPart;
myOrder OrderRecordPart;
myOrderArray OrderRecordPart [] {maxsize = 20}; // array of orders
get myOrderArray; // fill the array the first time
EGL will produce the correct pseudo-DL/I code:
get myOrderArray with #dli{
GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
STPCORD (STQCODN = :myOrder.orderDateNo)
GN STPCORD };
The advantage of this technique is that you can use implicit DL/I database I/O
and have different names for the record variables and the DL/I segment records.
The disadvantage is that EGL now uses myCustomer as the qualifier for every
implicit DL/I database I/O statement that uses the CustomerRecordPart,
LocationRecordPart, and OrderRecordPart.
Related concepts
“Working with DL/I data” on page 221
Related reference
#dli directive
dliVar system variable
“Example DL/I database” on page 223

Working with MQ message queues


Message queueing provides an alternative to calling a remote program. With
message queueing, programs communicate by writing to and reading messages
from queues.

Accessing data with EGL code 235


The Message Queue Interface (MQI) is an IBM specification of an application
programming interface (API) for accessing the MQ (formerly MQSeries®) message
and queuing services that support data transfer between programs running on a
wide variety of IBM and non-IBM platforms. The services allow programs to
communicate without knowledge of the lower levels of the communication
network and without knowledge of the location of the other programs.

A message queue can be on the same system as a program (local) or on another


system (remote). Queue managers manage access to queues and transmission of
data between queues.

An MQI message is a string of data sent from one program to another. An MQI
message consists of program information and routing information used by the
message queue manager (control information). The structure and content of the
program information is determined by the communicating programs, not by the
queue manager.

Programs that use message queueing techniques have the following features:
v There is no physical connection between programs.
v Communication network access functions are built into the queue managers, not
into the programs.
v Communicating programs can run in parallel.
v Communicating programs do not need to be running concurrently.
v Intermittent communication link failures do not prevent messages from being
delivered.
v Work is carried out by small, self-contained programs.
v Communication can be driven by events.
v Messages can be assigned priorities.
v Messages can be recoverable resources, committed or rolled back along with
database or file updates.
v Workloads can be balanced by starting multiple servers for processing a single
queue.
v Availability can be increased by assigning multiple alternative processors to
service a queue.

EGL supports calls to MQ message queues in two ways:


v You can use EGL-specific keywords like add and get next. In this case EGL
handles all the details of generating MQ API calls.
v You can write MQ API calls directly, to support older programs.

New code should use EGL keywords to communicate with message queues.

EGL uses resource associations to determine the queue to which the record is
assigned. For more information, see “Defining resource associations for message
queues” on page 237.

Subsequent sections provide the details of creating MQ programs in EGL.

Defining messages in EGL


EGL uses a record with the MQRecord stereotype to create the internal
representation of a message.

236 EGL Programmer’s Guide


MQRecords follow the same general rules as other EGL records. They consists of
message data as well as a number of properties. One set of properties tells EGL
how to create the API commands it generates to communicate with MQ. Another
set provides the physical name of the message queue to use (fileName), the logical
queue name (queueName), the size of the variable length record (lengthItem), and
other basic information.

For more information about these properties, see MQRecord properties.


Related tasks
“Defining resource associations for message queues”
You can define resource associations to specify default values for EGL programs
that access message queues.
“Reading from and writing to message queues” on page 238
Write to message queues with the EGL add statement; read with get next.
“Using direct MQ API calls” on page 240
The MQ API is a set of program interfaces used to request services from the
message queue manager.
Related reference
MQRecord properties

Defining resource associations for message queues


You can define resource associations to specify default values for EGL programs
that access message queues.

Use resource associations to:


v Define the queue manager name and queue name
v Define the system
v Convert message formats

To define a resource associations part for message queues, perform the following
steps:
1. Open an EGL build file by right-clicking the file name in the Project Explorer
and selecting Open With → EGL Build Parts Editor.
2. Create a resource association part by right-clicking the build file in the Outline
view and selecting Add Part.... Select Resource Association from the wizard
dialog and click Next.
3. Specify a name for the Resource Association part and an optional free-form
description. Click Finish.
4. EGL displays the Resource Association part. Click Add Association to add a
new element. Specify a file name (fileName property) to identify the element.
The entry will apply to any message queue record whose fileName property
matches the name you enter here.
5. Enter a file type (fileType property) of MQ for the element.
6. Specify the platform on which the message queue is located (system property).
7. If you want to specify different properties for different systems, click Add
System and specify additional systems.
8. For each file name and system on the left side of the editor, you can specify
properties on the right side. The system and file type carry over from the left
side. Specify the system resource name (systemName property) in the
following form:
[queueManagerName:]queueName

Accessing data with EGL code 237


Specify only the queueName if you want to use the default queue manager. The
system resource name for message queue records defines the queue manager
name and queue name. The system resource name is used as the initial value
for the fileName property for the MQRecord and identifies the default queue
associated with the record.
EGL uses the system resource name in add and get next statements for the
message queue record. The queueName identifies the queue that is accessed by
the operation. The queueManagerName identifies the queue manager on which
the queue is defined. The default queue manager is the queue manager to
which the program is connected. If there is not already an active connection,
EGL uses the queue manager name to connect to the queue manager before
accessing the queue. If no queue manager name is specified, EGL connects to
the default queue manager for the system. If the system resource name is not
specified in a resource association file, a default system resource name is
defined by the fileName property of the message queue record.
9. You can optionally specify a conversion table if you want data format
conversion to be performed on the message. If you specify a conversion table,
EGL converts the message from local format to remote format when the
message is added to the queue, and from remote format to local format when
the message is read from the queue. EGL performs conversion using the
message queue record structure to identify the data type of fields in the
message.

Reading from and writing to message queues


Write to message queues with the EGL add statement; read with get next.

The first time you use an EGL statement with an MQ record during a program,
EGL checks to see if there is an active connection to a queue manager. If not, it
creates one.

After you have read from or written to a message queue you may need to commit
or roll back your changes.

Connecting to queue managers


You can connect to only one queue manager at a time in an EGL program.

EGL automatically connects to the queue manager on the first add or get next
statement in a program, using the queue manager name specified in the system
resource name associated with the message queue record. If the queue manager
name is not specified, the queue manager is the default queue manager defined for
your system. EGL automatically disconnects from the queue manager when the
program ends, closing any open files and committing the current unit of work if it
is still open.

EGL provides sample functions named MQCONN and MQDISC that call the
MQCONN and MQDISC routines from the MQ API. Use these functions in the
following circumstances:
v If the connection queue manager and the queue manager to which the queue
belongs are different, use an MQCONN function call to connect before issuing
the add or get next statement in the program. Otherwise the add or the get next
statement will use the current open connection instead of attempting to connect
to the queue manager specified in the system resource name.

238 EGL Programmer’s Guide


v If you want a long running program to disconnect from the queue manager
before the program ends, use an MQCONN function call to do the initial
connection and an MQDISC function call to disconnect after all queue access is
complete.

For more information on MQCONN and MQDISC, see “Using direct MQ API
calls” on page 240. In workstation environments (Windows NT®, OS/2®, AIX,
Solaris, and HP), MQ provides different runtime libraries for MQ programs
depending on whether the program is running on the same system as the message
queue manager or whether the program is running as an MQ client
communicating with a manager on a server system. On AIX and HP systems,
different libraries are provided for threaded and non-threaded environments as
well.

Writing messages to queues


Write messages to queues using the add statement with the message queue record
as the I/O object. EGL performs the following actions:
1. Establishes the connection to the queue.
2. Opens the connection to the queue.
3. Puts the message on the queue.

You must use a local definition of the remote queue on the currently connected
queue manager if both of the following circumstances are true:
v You are writing messages to a queue on another Queue Manager using the add
statement.
v You previously wrote a message to a queue using the add statement.

EGL saves the connection handle for future add statements.

You must use the close statement after an add statement to close the connection to
the queue in any of the following circumstances:
v Before using the get next statement.
v To release the queue for access by another program.
v To release the queue if you have a long running program and have completed
work with the queue.

EGL automatically closes the connection to the queue on program termination.

Reading messages from queues


Read messages from queues using the get next statement with the message queue
record as the I/O object.When you use the get next statement, EGL performs the
following actions:
1. Connects to the queue manager, if the queue manager is not already connected.
2. Opens the queue, if the queue is not already open.
3. Gets the next message from the queue.

You must use a local definition of the remote queue on the currently connected
queue manager if both of the following circumstances are true:
v You are reading messages from a queue on another Queue Manager using the
get next statement.
v You previously read a message from a queue using the get next statement.

Accessing data with EGL code 239


You must use the close statement after a get next statement to close the connection
to the queue in any of the following circumstances:
v Before using the add statement.
v To release the queue for access by another program.
v To release the queue if you have a long running program and have completed
work with the queue.

EGL automatically closes the connection to the queue on program termination.

Committing or rolling back messages


When you combine messages in a transaction that defines a unit of work, the
messages can be committed or rolled back as a group. When a unit of work is
committed, everything included in the transaction is finalized. When a unit of
work is rolled back, everything included in the transaction is removed.

The methods used for commits and rollbacks depend on your environment. The
following environments handle commits and rollbacks independently of MQ:
v AS/400®
v CICS for MVS/ESA™
v CICS for VSE/ESA™
v IMS

In these transaction environments, message queue commits and rollbacks are


coordinated with commits and rollbacks for other recoverable resources, like DB2
databases, using a two-phase commit protocol.

In other environments, the resources for different managers are committed


independently from one another. EGL automatically issues the appropriate MQ
calls for commits and rollbacks when you use sysLib.commit() and
sysLib.rollback().
Related concepts
“Working with MQ message queues” on page 235
Message queueing provides an alternative to calling a remote program. With
message queueing, programs communicate by writing to and reading messages
from queues.
Related tasks
“Using direct MQ API calls”
The MQ API is a set of program interfaces used to request services from the
message queue manager.

Using direct MQ API calls


The MQ API is a set of program interfaces used to request services from the
message queue manager.

The MQ API (also known as the MQ Interface, or MQI) accesses the message
queue manager directly. Because of the complexity of the interface, the ease of
making mistakes, and the lack of flexibility, the MQI should only be used to
maintain existing code. New code should use the EGL add and get next statements
to access message queue information.

EGL supports the following MQI functions:


v Connecting and disconnecting from the queue manager (MQCONN or
MQCONNX, MQDISC)
240 EGL Programmer’s Guide
v Opening and closing a queue (MQOPEN, MQCLOSE)
v Reading a message from a queue (MQGET)
v Writing a message to a queue (MQPUT)
v Writing a single message to a queue with an implicit open and close of the
queue (MQPUT1)
v Requesting or setting attributes of a queue manager object such as a queue
(MQINQ, MQSET)
v Beginning a unit of work (MQBEGIN)
v Committing or backing out changes (MQCMIT, MQBACK)

To use direct MQ API calls, you must enable an EGL Project Feature:
1. Right-click the project name in the Project Explorer view.
2. Select Properties.
3. Click EGL Project Features in the left side of the Properties dialog.
4. Check the box next to EGL with low-level MQ API support.
5. Click OK.

MQ reusable parts
EGL provides a set of reusable parts, which are parameters, records, and functions
that you can use or modify to make direct calls to the MQ API. The source files for
these parts are located in the SDP70Shared\plugins\
com.ibm.etools.egl.resources_version\MqReusableParts directory.

MQI parameters are either data items or records. The MQSTATE and
MQATTRIBUTES sample records contain declarations for most data item
parameters.

The BUFFER parameter (message buffer parameter used with MQGET, MQPUT,
and MQPUT1 calls) and the CHARATTRS (character attributes buffer parameter
used with MQINQ and MQSET calls) are both defined with a length of 1024
characters. Increase the length of these items if you reuse MQSTATE in a program
that requires larger buffers.

Sample records are provided to define the format of record parameters and special
purpose messages and message headers. Record names are the same as the
COBOL structure names. The data items in the records have the same names as the
corresponding fields in the COBOL structures, except that the COBOL names use a
hyphen (-) as a token separator instead of an underscore.

The following table shows the names of the sample records for direct MQ calls.
Table 36. Sample records for MQ calls
Record Description Initializer function
MQBO Begin options MQBO_INIT
MQCNO Connect options MQCNO_INIT
MQDH Distribution header MQDH_INIT
MQDLH Dead-letter header MQDLH_INIT
MQGMO Get-message options parameter MQGMO_INIT
MQINTATTRS Integer attributes parameter MQINTATTRS_INIT
MQMD Message descriptor parameter MQMD_INIT

Accessing data with EGL code 241


Table 36. Sample records for MQ calls (continued)
Record Description Initializer function
MQMD1 Message descriptor (version 1) MQMD1_INIT
MQMDE Message descriptor extension MQMDE_INIT
MQOD Object descriptor parameter MQOD_INIT
MQOR Object record MQOR_INIT
MQPMO Put-message options structure MQPMO_INIT
MQRMH Message reference header MQRMH_INIT
MQRR Response record MQRR_INIT
MQSELECTORS Attribute selectors parameter MQSELECTORS_INIT
MQTM Trigger message structure MQTM_INIT
MQTMC2 Trigger message 2 (character MQTMC2_INIT
format)
MQXQH Transmission queue header MQXQH_INIT

The following table shows the sample EGL functions that call MQ API functions.
Table 37. EGL functions that call MQ API functions
Function Description
MQCONN Connect to message queue manager
MQCONNX Extended connect
MQDISC Disconnect from message queue manager
MQOPEN Open a message queue
MQCLOSE Close a message queue
MQGET Read a message from a queue
MQPUT Write a message to a queue
MQPUT1 Write a single message to a queue including queue open and close
MQINQ Inquire about queue attributes
MQSET Set queue attributes
MQBEGIN Begin a logical unit of work
MQCMIT Commit a logical unit of work
MQBACK Back out a logical unit of work

Related concepts
“Working with MQ message queues” on page 235
Message queueing provides an alternative to calling a remote program. With
message queueing, programs communicate by writing to and reading messages
from queues.
Related tasks
“Reading from and writing to message queues” on page 238
Write to message queues with the EGL add statement; read with get next.

Using linkage options for MQ run-time library selection


Use an EGL linkage options part to indicate which runtime library you want to
use.

242 EGL Programmer’s Guide


The MQ reusable parts shipped with EGL include sample linkage options parts for
all supported environments. The following table shows which linkage options part
to use in each environment. You can use the linkage options parts directly, or copy
the entries in the parts to your own linkage options, if you need to specify entries
for other program calls.
Table 38. Linkage options for MQ programs
MQ library Wrapper DLL
Environment description MQ library name Linkage options
Windows MQ manager mqm.lib csomqm32 mqm32.lkg
Windows MQ client mqic32.lib csomqc32 mqic32.lkg
AIX MQ manager libmqm.a csomqm libmqm.lkg
AIX MQ client libmqic.a csomqic libmqic.lkg
AIX MQ manager, libmqm_r.a csomqmr libmqm_r.lkg
threaded
environment
AIX MQ client, libmqic_r.a csomqicr libmqic_r.lkg
threaded
environment
HP-UX MQ manager libmqm.sl csomqm libmqm.lkg
HP-UX MQ client libmqic.sl csomqic libmqic.lkg
HP-UX MQ manager, libmqm_r.sl csomqicr libmqm_r.lkg
threaded
environment
HP-UX MQ client, libmqic_r.sl csomqmr libmqic_r.lkg
threaded
environment
Solaris MQ manager libmqm.so csomqm libmqm.lkg
Solaris MQ client libmqic.so csomqic libmqic.lkg

If you are testing or running with an MQ manager, non-threaded library, specify


the linkage options part as a test or generation option. If you are testing or
running with an MQ client or threaded library, you must also move the part to a
file and set the CSOLINKTBL environment variable to the file name.

Generated Java programs require a special format for the linkage options entry.
The entry should look like the following example:
:calllink applname=elaq* library=mqWrapperDllNname linktype=csocall
parmform=commptr remotecomtype=direct remoteapptype=nonvg
contable=javaConversionTableName
mqWrapperDllNname
The wrapper dll name for your run-time environment from the table.
javaConversionTableName
The java conversion table for your language and the system on which the
program is running.

Refer to the EGL Generation Guide for help in determining which conversion table
to choose.
Related concepts

Accessing data with EGL code 243


“Working with MQ message queues” on page 235
Message queueing provides an alternative to calling a remote program. With
message queueing, programs communicate by writing to and reading messages
from queues.
Related tasks
“Defining resource associations for message queues” on page 237
You can define resource associations to specify default values for EGL programs
that access message queues.

Working with iSeries objects


EGL provides a library and Record definitions to communicate with data queues
and data areas on the iSeries.

The iSeries operating system has its own API to handle program-to-program
communication. The communication can take place through one of two objects:
v A data area is a fixed-size object that any job running on the system can read
from or write to. Think of it as a virtual whiteboard. You can set it up to contain
one of the following kinds of data:
– A character string of up to 2000 bytes
– A decimal number
– A Boolean value (TRUE or FALSE)
v A data queue is a variable-length object that can hold any number of messages
from any number of jobs. Data queues are similar to MQ message queues.

A data area has lower overhead than a data queue, so your choice of which object
to use generally depends on the complexity of your task. You might use a data
area, for example, to hold a flag that lets one program tell another to perform
garbage collection. A data queue scenario is typically more complex, as in the
following example:
v One application listens for a specific type of request. For each request, it creates
a record and adds that new record to the queue.
v Other applications listen for new records created by the first application. One
uses the record to update a database. Another uses the same record to generate
an invoice.

EGL supports these iSeries objects in two ways:


v EGL Record parts that correspond to various iSystem objects, including data
areas and data queues, among others. The Record parts are located in the
CommonDataParts.egl file in the SDP70Shared\plugins\
com.ibm.etools.egl.resources_version\iSeriesObjects directory.
v A library of EGL functions that wrap iSystem API calls. This is not a system
library that you automatically have access to. This is an EGL source file located
in one of two subdirectories under the SDP70Shared\plugins\
com.ibm.etools.egl.resources_version\iSeriesObjects directory. Copy one of these
files into your current project:
– iCobolLib.egl for COBOL generation, for the cobol directory.
– iJavaLib.egl for Java generation, for the java directory.

For details of these Record parts and function calls, see the EGL Language Reference.
Related tasks

244 EGL Programmer’s Guide


“Working with MQ message queues” on page 235
Message queueing provides an alternative to calling a remote program. With
message queueing, programs communicate by writing to and reading messages
from queues.
Related reference
iSeries Record definitions
EGL provides Record definitions that correspond to objects in the iSeries
environment.
iSeries function calls
iSeries functions provide access to data queues and data areas.

Working with bidirectional data


Bidirectional (bidi) languages such as Arabic and Hebrew are languages in which
the text is presented to the user ordered from right to left, but numbers and Latin
alphabetic strings within the text are presented left to right. In addition, the order
in which characters appear within program variables can vary. In COBOL
environments, the text in program variables is usually in visual order, which is the
same order in which the text appears on the user interface. In Java environments,
the text is usually stored in logical order, the order in which the characters are
entered in the input field.

These differences in the ordering scheme, text orientation, and other bidirectional
format characteristics require the program to convert bidirectional text strings from
one format to another:
v To control the format of bidirectional text strings in FormGroup fields, use a
bidirectional runtime file.
v To control the format of bidirectional text strings between a server and client,
use a bidirectional conversion table.

Bidirectional runtime file

The bidiRuntime build descriptor option specifies a bidirectional runtime file. This
file, in XML format, contains a set of options that control the bidirectional behavior
for the fields in the form groups associated with an application. Several of these
options correspond to existing bidi properties:
v bidiInput
v orientation
v numericSwapping
v symmetricSwapping

Before the bidirectional runtime file was added to EGL (prior to version 7.5),
individual properties controlled this behavior. Those properties are still part of
EGL. If your code associates these individual properties with a FormGroup,
changing the runtime file will cause EGL to change the values of the individual
properties accordingly. If you change the individual properties, EGL will use the
new values to update the runtime file.

For information on how to set up the bidirectional runtime file, see “Creating a
bidirectional runtime file” on page 247.

Bidirectional conversion table

Accessing data with EGL code 245


EGL uses a bidirectional conversion table (BCT) to perform conversions between
″server″ and ″client″ formats. The file is in XML format and has a file extension of
.bct. You can create multiple BCTs to support different bidi format conversions,
using an EGL wizard. The program references the name of the conversion table to
indicate how attribute conversion should be performed.

In all cases, the bidi conversion table reference is specified as the 1- to 4-character
file name with the .bct extension. For example, if you have created a bidi
conversion table named hct1.bct, you can set the value of formConversionTable
in a program by adding the following statement at the beginning of the program:
sysVar.formConversionTable = "hct1.bct" ;

To use a bidi conversion table, you must do the following:


v Create bidi conversion tables that specify the transformations that should occur.
Note that different tables are needed for converting data being passed between a
Java client and a COBOL host and for converting data to be displayed in a text
or print form in a Java environment. You build the bidi conversion table file
using the bidi conversion table wizard. For more information, see “Creating a
bidirectional conversion table” on page 249.
v Specify the bidi conversion table for use in generation. The way in which you
specify the bidi conversion table differs depending on the code you are
generating:
– When you generate for a COBOL environment, do the following:
1. Set the bidiConversionTable build descriptor option to the name of the
bidi conversion table you created for COBOL generation. The bidi
conversion table controls the transformation of literal text from logical to
visual order for the COBOL environment, along with any other formatting
transformation requested in the table.
2. Set the clientCodeSet and serverCodeSet build descriptor options to
control the conversion of the code page from ASCII to EBCDIC as shown
in the next table.
Table 39. clientCodeSet and serverCodeSet build descriptor option values
Language clientCodeSet serverCodeSet
Arabic IBM-864 IBM-420
Hebrew IBM-1255 IBM-424

– When you generate a Java program that calls a remote COBOL program,
customize the linkage options part so that the conversionTable property is in
the callLink element for the called program, using one of the following
options:
- Specify a bidi conversion table as the value of that property (for example,
conversionTable="hct.bct")
- Set the property to PROGRAMCONTROLLED, which means that the
calling program specifies the bidi conversion table before calling the other
program. The caller specifies the table by assigning the bidi conversion
table name to the sysVar.callConversionTable system variable. You can
find more information about the sysVar.callConversionTable system
variable in the topic ″callConversionTable″ in the EGL Language Reference.
– When specifying EGL bindings for a service in an EGL deployment descriptor
(.egldd) file, specify the .bct file name for the conversionTable property (for
example, conversionTable="hct1.bct") in any protocol other than local.

246 EGL Programmer’s Guide


– When developing a program that you plan to generate to Java and that
program uses text or print forms with bidi language text, add a statement to
the program that assigns the conversion table name to the
sysVar.formConversionTable system function before showing the form.
Related tasks
“Creating a bidirectional runtime file”
You can use an EGL wizard to create a bidirectional runtime file.
“Creating a bidirectional conversion table” on page 249
You can use an EGL wizard to create a bidirectional conversion table (BCT).

Creating a bidirectional runtime file


You can use an EGL wizard to create a bidirectional runtime file.

To use the wizard, follow these steps:


1. Click File → New → Other. The New window opens.
2. Click to expand EGL, then click Bidi Format Configuration.
3. Click Next. The Bidi Format Configuration window opens.
4. Under Enter or select the parent folder, enter the name folder where you want
to create the file. The directory must be in the classpath for the application that
uses it.
5. For File name, enter a name for the bidirectional runtime file. The name must
have the .xml extension.
6. Click Next. The Runtime Bidi settings page opens.
7. To provide bidi settings for code generation, set the following fields under
Runtime Text attributes:
Ordering Scheme
Equivalent to the bidiInput property (see bidiInput). Select one of the
following values:
Implicit (default)
If you want to store bidi characters in the order in which they
are typed. ″Implicit″ has the same meaning as ″logical,″ and is
used here for consistency with the bidirectional conversion
table (see “Working with bidirectional data” on page 245).
Visual If you want to store bidi characters in the order in which they
appear on the screen (this option is provided for historical
reasons).
Text Orientation
Equivalent to the orientation property (see orientation). Select one of
the following values:
LTR (default)
If you want the fields to display in left-to-right orientation.
RTL If you want the fields to display in right-to-left orientation.
Symmetric Swapping
Equivalent to the symmetricSwapping property (see
symmetricSwapping). Select one of the following values:
Yes (default)
If you want to enable symmetric swapping.
No If symmetric characters are already swapped.

Accessing data with EGL code 247


Note: The default value here is the opposite of the default value of the
symmetricSwapping property.
Numerals
Determines the way that digits display inside forms. Select one of the
following values:
Nominal (default)
All digits display in nominal form (known as Arabic numerals
in English).
National
All digits display in national form (known as Hindi numerals
in Arabic).
Contextual
Digits display according to the preceding data. If the preceding
data is Arabic, digits display in national form. Otherwise, digits
display in nominal form.
Any Digits display as stored, with no modifications.
Encoding
Select the appropriate encoding from the following list:
v UnicodeBig (default)
v UnicodeBigUnmarked
v UnicodeLittle
v UnicodeLittleUnmarked
v UTF-8
8. To provide bidi settings for the Java runtime environment, set the following
fields under Java Emulator Configuration:
Symmetric Swapping
Equivalent to the symmetricSwapping property (see
symmetricSwapping). Select one of the following values:
Yes (default)
If you want to enable symmetric swapping.
No If symmetric characters are already swapped.

Note: The default value here is the opposite of the default value of the
symmetricSwapping property.
Numeric Swapping
Equivalent to the numericSwapping property (see numericSwapping).
Select one of the following values:
Yes (default)
If you want to enable numeric swapping.
No If numeric characters are already swapped.

Note: The default value here is the opposite of the default value of the
numericSwapping property.
9. Click Finish. The table is displayed for editing. Save and close the window
when you have finished.
Related concepts
“Working with bidirectional data” on page 245

248 EGL Programmer’s Guide


Creating a bidirectional conversion table
You can use an EGL wizard to create a bidirectional conversion table (BCT).

To use the wizard, follow these steps:


1. Click File → New → Other. The New window opens.
2. Click to expand Bidi Conversion Table Wizard, then click Bidi Conversion
Table.
3. Click Next. The New Bidi Conversion Table window opens.
4. Under Enter or select the parent folder, enter the name folder where you
want to create the table. The directory must be in the classpath for the
application that uses it.
5. For File name, enter a name for the Bidi Conversion table. The name of a bidi
conversion table used with EGL programs must have four characters or less,
and must have the .bct extension.
6. Click Next. The Client System settings page opens.
7. In the Code page list, select the encoding for the type of application you are
generating. You can specify any valid code page for client and server,
including UTF-8. The following table shows some examples:
Table 40. Encoding for bidi conversion tables
Use Language Client encoding for Server encoding for
bidi conversion table bidi conversion table
COBOL generation Arabic Cp1256 Cp864
COBOL generation Hebrew Cp1255 Cp1255
Java program that Arabic Cp1256 Cp420
calls a remote
COBOL program or
EGL service
Java program that Hebrew Cp1255 Cp424
calls a remote
COBOL program or
EGL service
Java program that Arabic Cp1256 Cp1256
uses text or print
forms
Java program that Hebrew Cp1255 Cp1255
uses text or print
forms

8. Change any Client System properties necessary. Note that for Java
generation, the conversion table client code page must be the same as the
java.lang.System.file.encoding set for the Java Virtual Machine when the
program runs.
9. Change any or Client Text attributes necessary. For the Ordering Scheme of
server attributes, the following considerations apply:
v For Java generation, the ordering scheme should be set to Implicit, while
encoding should be the same as your local system encoding.
v For COBOL generation, you should usually set the ordering scheme to
Visual and set the server code page to Cp420 for Arabic or Cp424 for
Hebrew. The client format will depend on the client that you use.
10. Click Next. The Server System settings page opens.

Accessing data with EGL code 249


11. Change the Server System properties and Server Text attributes if necessary.
12. Click Next. The Conversion Options page opens.
13. Change the Arabic Conversion Options and General Conversion Options if
necessary.
14. Click Finish.
Related concepts
“Working with bidirectional data” on page 245

250 EGL Programmer’s Guide


Transfer of control across programs
EGL provides several ways to switch control from one program to another:
v The call statement gives control to another program and optionally passes a
series of values. Control returns to the caller when the called program ends. If
the called program changes any data that was passed as a variable, the content
of the variable is changed in the caller.
The call statement does not commit databases or other recoverable resources,
although an automatic server-side commit may occur.
You may specify characteristics of the call by setting a callLink element of the
linkage options part. For more information, see call and Using linkage options
parts in a call or transfer.
v Two types of transfer statements give control from one main program to another,
end the transferring program, and optionally pass a record whose data is
accepted into the receiving program’s input record. You cannot use one of these
transfer statements in a called program.
– A transfer to transaction statement does the following:
- In a main program that runs under CICS or IMS/VS, this statement
commits recoverable resources, closes files, closes cursors, and starts a new
transaction.
- In a program that runs as a z/OS or IMS BMP main batch program or as a
Java main text or main batch program, the behavior depends on the setting
of build descriptor option synchOnTrxTransfer:
v If the value of synchOnTrxTransfer is YES, the transfer statement
commits recoverable resources, closes files, closes cursors, and starts a
program in the same run unit.
v If the value of synchOnTrxTransfer is NO (the default), the transfer
statement also starts a program in the same run unit, but does not close
or commit resources, which are available to the invoked program.
– A transfer to program statement does not commit or rollback recoverable
resources, but closes files, releases locks, and starts a program in the same run
unit.
For more information about restrictions and other issues, see transfer and Using
linkage options parts in a call or transfer.
v The vgLib.startTransaction() system function starts a run unit asynchronously.
The operation does not end the transferring program and does not affect the
databases, files, and locks in the transferring program. You have the option to
pass data into the input record, which is an area in the receiving program.
If your program invokes vgLib.startTransaction(), you might need to generate
the program with a linkage options part, asynchLink element to provide
additional information (such as a package name for Java, or information for a
remote transaction for CICS). For more information, see startTransaction() and
Using linkage options parts in a call or transfer.
v The EGL show statement ends a main textUI program or a main
VGWebTransaction program and shows data to the user. After the user submits
the form or Web page, the show statement optionally forwards control to a
second main program, which receives data received from the user as well as
data that was passed without change from the originating program.

© Copyright IBM Corp. 1996, 2008 251


In relation to textUI programs, the show statement is affected by the settings in
the linkage options part, transferToTransaction element.
For more information, see show.
v Finally, the forward statement is invoked from a JSF Handler or from a program
that runs in a Java environment. The statement performs the following actions:
1. Commits recoverable resources, closes files, and releases locks..
2. Forwards control.
3. Ends the code.
The target in this case is another program or a Web page. For more information,
see forward.
The target in this case is another program or a Web page. For more information,
see ″forward″ in the EGL Language Reference.
Related tasks
“Calling programs in CICS environments” on page 254
“Transferring control in CICS environments” on page 261
“Calling programs in IMS and z/OS batch environments” on page 267
“Transferring control in the IMS/VS environment” on page 275
“Transferring control in IMS BMP and z/OS batch environments” on page 270
Related reference
“Reference information for special parameters on call or transfer statement”

Reference information for special parameters on call or transfer


statement
You can use the following special parameters on a call or transfer statement:
v A text or print form passed on a call statement
v The dliLib.psbData structure
v A PCBRecord

The following sections provide more information.

Format of a text or print form passed on a call


Text or print forms that you pass on a call are defined with 8 bytes of adjunct
fields preceding each field data content area. The first 6 bytes of the adjunct field
are set to blanks. The last 2 bytes of the adjunct field contain the length of the
data. The field length is set to the length of the field defined in the map. It does
not include the 8-byte prefix. If the receiving structure in the called program is not
a form, the structure should have space for the 8 bytes before each data item. A
called program can only change the data in the variable fields in the passed form.
For example, a called program cannot change the attributes of form variable.

8 bytes

6 bytes 2-byte length data for form field

Figure 1. Format of the form area passed using the call statement

252 EGL Programmer’s Guide


When passing a form as a parameter from an AIX system to a non-AIX system and
vice versa, the 2-byte binary fields must be aligned on a 2-byte boundary, which
starts at the third byte of the 8-byte field.

Format of the dliLib.psbData structure


EGL-generated COBOL programs use the dliLib.psbData structure for passing PSB
information between programs. Refer to the online help system for additional
information about dliLib.psbData. dliLib.psbData is a 12-byte structure consisting
of an 8-byte PSB name followed by a 4-byte address.

On CICS, the address points to the user interface block (UIB). The UIB is 6 bytes
long. The first 4 bytes contain the address of the PCB address list for the PSB. The
last 2 bytes contain status information (for example, an indication of whether the
PSB contains status information).

On non-CICS systems, the address points to a simulated UIB. The simulated UIB is
6 bytes long. The first 4 bytes contain the address of the PCB address list for the
PSB. The last 2 bytes must contain binary zeros. The PCB address list must be the
list pointed to by register 1 when the IMS or the DL/I region controller invoked
the first program in the DL/I run unit.

The figure below shows the format of dliLib.psbData.

Pointer to PSB Name


dliLib.psbData
Pointer to UIB

Pointer to PCB List PCB Number 0 (I/O)

PCB Number 1
Status information
PCB Number 2
.
.
.
High order byte PCB Number n
must have
bit 0 = 1
Figure 2. Format of dliLib.psbData

Format of a PCBRecord
There are special considerations for the dliLib.psbData structure and PCB record
parameters. If you pass the dliLib.psbData structure as a parameter, it is
implemented as a 12-byte field consisting of an 8-byte PSB name followed by a
4-byte address. The address points to the CICS user interface block (UIB).

Transfer of control across programs 253


A PCB record parameter is always passed using a 4-byte pointer because the called
program must point to the actual DL/I PCB in DL/I calls. The called program
cannot use a copy of the PCB. When COMMDATA is specified, the 4-byte pointer
is moved into the COMMAREA at the position to be occupied by the PCB record
argument.

The above considerations are true for both AIBTDLI and CBLTDLI interfaces. If
you specified the AIBTDLI interface (the default) in the callInterface field
corresponding to the @DLI program property, EGL uses the AIB control block to
look up the PCB address of the AIB PCB name, then issues a CBLTDLI call against
that address.
Related concepts
“Transfer of control across programs” on page 251
Related tasks
“Calling programs in CICS environments”
“Calling programs in IMS and z/OS batch environments” on page 267
“Transferring control in IMS BMP and z/OS batch environments” on page 270

Calling programs in CICS environments


Use the linkage options part to specify how you want EGL to generate the call
statement. In the CICS environments, you can specify one of the following values
for the type property for a callLink element in the linkage options part:
localCall
A call that is to be made in the same CICS region.
remoteCall
A call that is to be made from one CICS region to another or from a generated
Java program to a generated COBOL program that runs in CICS.

For a localCall, you can also specify the linkType property that determines the
actual call statement as follows:
DYNAMIC
Standard dynamic COBOL call.
STATIC
Standard static COBOL call. The called program must be link edited with the
calling program.
CICSLINK
CICS LINK command (default for CICS programs). CICSLINK is only
supported in the following situations:
v The callLink element for the called program specifies a remoteCall.
v The callLink element for the called program specifies parmForm =
CHANNEL.
v The call statement specifies isExternal = YES or the callLink element for the
called program specifies pgmType = EXTERNALLYDEFINED.
In all other cases, including where CICSLINK is the default, EGL does not
generate a CICS LINK command for linkType = CICSLINK. Instead EGL
generates a standard dynamic COBOL call, the same call as if you specified
linkType = DYNAMIC for the callLink element for the called program.

You must create a CICS RDO PROGRAM entry for any called program that is
called with the following linkage options:

254 EGL Programmer’s Guide


v localCall with the linkType property set to DYNAMIC or CICSLINK.
Alternatively, for a localCall, you can use the CICS autoinstall function for
programs.
v remoteCall

You can also specify how the parameters on the call statement are to be passed to
the called program:
COMMPTR
Pointers to the parameters are passed in the COMMAREA (default for CICS
programs if the property type is localCall).
COMMDATA
Parameter data is passed in the COMMAREA (default for CICS programs if the
property type is remoteCall).
OSLINK
Parameters are passed using a standard COBOL parameter list. The called
program cannot contain any CICS statements or be an EGL program.
CICSOSLINK
A standard COBOL parameter list is used. The first two parameters are the
EXEC interface block (EIB) and COMMAREA followed by the call statement
parameters.
CHANNEL
Parameters are passed in containers in a channel. The containers are named
EGL-PARM-1 through EGL-PARM-n, where the maximum value of n is 30. No
COMMAREA is passed in the CHANNEL parameter format.
Table 41. Valid parameter format and linkage combinations for CICS
COMMPTR COMMDATA OSLINK CICSOSLINK CHANNEL
DYNAMICValid Valid Valid Valid No
STATIC Valid Valid Valid Valid No
CICSLINK Valid Valid No No Valid
REMOTE Valid if calling from an Valid No No Valid
EGL-generated Java
program; Not valid if
calling from a CICS
program.

For more information, see Linkage options part.

All calls described here are local calls between programs running on the same
CICS system. Called programs can also run on a different system than the calling
program as follows:
v If both programs run in CICS, set the type property to remoteCall and the
linkType property to COMMDATA. The call statement is generated as a CICS
LINK command with data passed in the COMMAREA control block
(COMMDATA).
v If the calling program is a generated Java program and the called program runs
on CICS, set the type property to remoteCall and the linkType property to
either COMMPTR or COMMDATA depending on how the called program
expects to receive its parameters.
If either the calling or called program is a PL/I program, you must set the
linkType property to CICSLINK. In addition, if the called program is a PL/I

Transfer of control across programs 255


program, you must either specify isExternal = YES on the call statement or specify
pgmType = EXTERNALLYDEFINED in the callLink element for the called
program. If the calling program is a PL/I program, you must specify linkType =
CICSLINK in the callLink element for the called EGL program.

The following sections give the specifics for using parameters with the call
statement.

Format of call statement parameters for CICS


The following sections provide a more detailed description of the parameter
formats used for call statement in the CICS environment.

Note: Special considerations apply if you pass dliLib.psbData or a PCBRecord as


a parameter. For more information, see “Format of the dliLib.psbData
structure” on page 253 and “Format of a PCBRecord” on page 253.

COMMAREA pointer (COMMPTR) parameter format


For the COMMPTR parameter format, pointers are passed in the CICS
COMMAREA. The COMMAREA is generated in the calling program’s COBOL
working storage area. The high-order bit is set on for the last parameter address in
the COMMAREA for the parameter format COMMPTR.

The figure below illustrates the COMMPTR parameter format. Register 1 points to
a list of pointers. The first is the address of the EXEC interface block (EIB),
followed by the address of the COMMAREA. Pointers to the parameters are
passed in the COMMAREA.

Register 1
Address of EIB

Address of COMMAREA

4 Byte Parm Pointer


. 1 to 30

High Order
. Parameter

Byte, . pointers

Bit 0 = 1 4 Byte Parm Pointer

X’FFFFFFFF’ List End


(optional - see
note)

When you set the endCommarea build descriptor option to YES for the calling
program, the calling program adds the x’FFFFFFFF’ fullword at the end of the
parameter list. You should set endCommarea to YES only when the called program
requires this terminal fullword, as in a program that was previously called from a
CSP/AE (Cross System Product/Application Execution) program. The length of the

256 EGL Programmer’s Guide


COMMAREA does not include the 4 bytes for this fullword unless endCommarea
is set to YES. Under certain conditions, CICS passes a copy of the COMMAREA to
the called program.

COMMAREA data (COMMDATA) parameter format


For the COMMDATA parameter format, the actual data is passed in a single buffer
in the CICS COMMAREA. The COMMAREA is generated in the calling program’s
working storage area. Each parameter value is moved to the COMMAREA, where
the values adjoin one another without regard for boundary alignment. If variable
length records are passed, space is reserved for the maximum length record as
defined to EGL. If a variable length record is passed that has the lengthItem
property set, the required space must be defined within the fixed portion of the
record. The called program must return the parameter values in the COMMAREA
in the same order. The calling program moves the returned parameter values in the
COMMAREA back to the original parameters.

The figure below illustrates the COMMDATA parameter format. Register 1 points
to a list of pointers. The first is the address of the EIB, followed by the address of
the COMMAREA. Actual parameter data is passed in the COMMAREA.

Register 1 Address of EIB

Address of COMMAREA

Parameter Data

OSLINK parameter format


For the OSLINK parameter format, the EIB and COMMAREA are not passed. Only
the parameters specified on the call statement are passed. The high-order bit is set
for the last address in the parameter list for parameter format OSLINK. OSLINK is
valid only for DYNAMIC and STATIC linkage types. The called program must be
one of the following:
v A non-EGL program that does not contain any EXEC CICS commands
v An EGL program that is generated for the ZOSBATCH environment. In this case,
the called EGL program must not do any I/O. In addition, you must specify
linkType = DYNAMIC in the callLink entry for the called EGL program.

The figure below illustrates the OSLINK parameter format. Register 1 points to a
list of pointers that are the addresses of buffers of parameter data (one for each
parameter).

Transfer of control across programs 257


Register 1 4 Byte Parm Pointer

.
. 1 to 30 parameter
. pointers
High Order Byte,
Bit 0 = 1
4 Byte Parm Pointer

CICSOSLINK parameter format


For the CICSOSLINK parameter format, the EIB and COMMAREA are always
passed as the first two parameters followed by the parameters specified on the call
statement. CICSOSLINK is valid only for STATIC and DYNAMIC linkage types.

The figure below illustrates the CICSOSLINK parameter format. Register 1 points
to a list of pointers. The first is the address of the EIB, followed by the address of
the COMMAREA, followed by the addresses of buffers of parameter data (one for
each parameter).

Register 1 Address of EIB

Address of COMMAREA

4 Byte Parm Pointer


High Order Byte,
Bit 0 = 1 .
. 1 to 30 parameter
. pointers

4 Byte Parm Pointer

CHANNEL parameter format


For the CHANNEL parameter format, containers are passed in a channel. A
channel is a set of containers that function like parameters for passing data
between CICS programs. No COMMAREA is passed in the CHANNEL parameter
format.

When an EGL generated program passes a channel to a called program, the


channel has the same name as the called program. However, when an EGL called
program receives a channel, the program uses a CICS API call to retrieve the name
of the channel that was passed.

The containers are named EGL-PARM-1 through EGL-PARM-n, where the


maximum value of n is 30.

258 EGL Programmer’s Guide


For example, if you pass three parameters of type INT, Record (33,000 bytes), and
EGL STRING, the channel will include three containers, as shown in the following
table:
Table 42. Example containers and parameters
Container name Value in container
EGL-PARM-1 4 bytes representing the INT
EGL-PARM-2 33,000 bytes representing the record
EGL-PARM-3 4 bytes representing the pointer to the STRING (the called
program must be EGL)

Calls from an EGL program to an EGL program


The called program runs and returns control to the calling program when the
program ends or an exit program statement is encountered. Up to 30 parameters
can be passed on the call statement. No CICS SYNCPOINT occurs as a result of a
call statement. The type, linkType, and parmForm properties for a called program
must be identical when generating both the calling and called program. If the
linkage type or parameter format is changed, the called program and all programs
that call it must be generated again. For a description of the parameter formats
used for calls, see ″Format of call statement parameters″ above.

Calls from an EGL program to a non-EGL program


The call statement that calls a non-EGL program is implemented in the same way
as when calling an EGL program. If the non-EGL program is written in assembler
or COBOL, you can set the linkType option in the callLink entry for the called
program to DYNAMIC, STATIC, or CICSLINK. However, if the non-EGL program
is written in a language other than assembler or COBOL, or if it is called using
EXEC CICS LINK, you must also specify one of the following options:
v Set the isExternal property to YES on the EGL call statement.
v Specify pgmType = EXTERNALLYDEFINED on the callLink entry for the called
program.
If the non-EGL program uses a linkage convention other than the default
(linkType = CICSLINK and parmForm = COMMPTR), you must include a
callLink entry for the non-EGL program in the linkage option part with the correct
values for the type, linkType, and parmForm properties. For a description of the
parameter formats used for calls, see “Format of call statement parameters for
CICS” on page 256.

The user program name must be defined to CICS and the program must exist in
the operating system load library, or a NOT FOUND condition results. The
program must also be link-edited according to CICS command level programming
rules. Refer to the CICS application programmer’s reference for more details.

Handling abends on calls from EGL programs to non-EGL


programs
In CICS there are abend handling considerations when an EGL program uses a
COBOL CALL instead of a CICS LINK to call a non-EGL COBOL program. In this
situation, the COBOL runtime environment disables the CICS abend handling
requested by the calling program on entry to the called program. The called
program should reinstate the abend handler for the EGL program by issuing a
CICS POP HANDLE statement on entry to the called program and a CICS PUSH
HANDLE statement on exit from the called program.

Transfer of control across programs 259


If the abend handler is not reinstated and an abnormal termination occurs in the
called program, normal error cleanup for the EGL program is not performed. The
shared table use count is not updated when the program ends unsuccessfully. This
might lead to an unnecessary copy of a shared table remaining in storage. No
Rational COBOL Runtime for zSeries error messages are issued by the abend
handler.

Refer to the application programming guide for your CICS environment for more
information on using COBOL calls in a CICS environment.

Examples of COMMPTR definitions in programs


When an EGL program uses CICSLINK and COMMPTR to pass parameters to a
non-EGL program, pointers to the parameters are passed in the CICS
COMMAREA. The following sections show examples of how non-EGL programs
can receive parameters passed using CICSLINK and COMMPTR.

Assembler language receiving parameters from CICSLINK with COMMPTR:


L PARMPTR,DFHEICAP Address parameter list
USING PARMAREA,PARMPTR
L PARM1PTR,PARM1A Address parameter 1
USING PARM1,PARM1PTR
L PARM2PTR,PARM2A Address parameter 2
USING PARM2,PARM2PTR
L PARM3PTR,PARM3A Address parameter 3
USING PARM3,PARM3PTR
.
. And so on
.
PARMAREA DSECT Define storage layout of parmlist
PARM1A DS F Passed pointer to parameter 1
PARM2A DS F Passed pointer to parameter 2
PARM3A DS F Passed pointer to parameter 3
PARM1 DSECT Define storage layout of passed parm
RECORD EQU * Parameter is a record
FLD1 DS L10 Fields in record structure
FLD2 DS L20 " "
FLD3 DS L200 " "
.
. And so on
.
PARM2 DSECT Define storage layout of passed parm
L7701 DS L5 Parameter is single data item level-77
PARM3 DSECT Define storage layout of passed parm
WORKSTOR EQU * Parameter is working storage
FLD5 DS L5 Fields in working storage
FLD6 DS L5 " "
.
. And so on
.

COBOL receiving parameters from CICSLINK with COMMPTR:


LINKAGE SECTION.
01 DFHCOMMAREA.
02 PARM1A USAGE IS POINTER.
02 PARM2A USAGE IS POINTER.
02 PARM3A USAGE IS POINTER.
01 PARM1.
02 RECORD.
03 FLD1 PIC X(10).
03 FLD2 PIC X(20).
03 FLD3 PIC X(200).
.
. And so on

260 EGL Programmer’s Guide


.
01 PARM2.
02 L7701 PIC X(5).
01 PARM3.
02 WORKSTOR.
03 FLD5 PIC X(5).
03 FLD6 PIC X(5).
.
. And so on
.
PROCEDURE DIVISION.
SET ADDRESS OF PARM1 TO PARM1A
SET ADDRESS OF PARM2 TO PARM2A
SET ADDRESS OF PARM3 TO PARM3A
.
. And so on
.

Calls from a non-EGL program to an EGL program


The EGL program must be defined as a called program. The calling non-EGL
program is responsible for setting the parameters as specified in the linkage option
part for the called program when it was generated. See “Format of call statement
parameters for CICS” on page 256 for diagrams of the linkage generated for
different parameter formats as specified in the linkage option part.

The format of variables in the parameter list must match the definition specified
for the parameters received by the called program. If they are not the same the
results are not predictable.

The following example shows the format of CICS LINK for a program call to a
program generated with the COMMPTR parameter format:
EXEC CICS LINK
PROGRAM('MYAPPL') COMMAREA(record of pointers)
LENGTH(length of COMMAREA)

If the linkType is DYNAMIC or STATIC, at exit the called EGL program sets the
COBOL special register RETURN-CODE to the value of the EGL variable
sysVar.returnCode. This return code, which is stored in register 15, can be tested
by the calling non-EGL programs.
Related concepts
“Transfer of control across programs” on page 251
Related tasks
“Transferring control in CICS environments”

Transferring control in CICS environments


Transfers in the CICS environment are supported in the following ways:
v A transfer to program statement is implemented as a CICS XCTL command.
v A transfer to transaction statement is implemented as one of the following
commands:
– a CICS START command if the genReturnImmediate build descriptor option
is set to NO
– a CICS RETURN IMMEDIATE command if the genReturnImmediate build
descriptor option is set to YES
Setting genReturnImmediate to YES is supported only for CICS for z/OS
systems

Transfer of control across programs 261


v A show statement with an associated form and a returning clause is
implemented as a CICS RETURN TRANSID command.

Transfer to program
A transfer to program statement can specify an optional record. A transfer to
program statement continues the same CICS transaction. The following sections
provide a more detailed description of how a transfer to program statement works
in the CICS environment.

Transfer from an EGL program to an EGL program using transfer


to program
The EGL program immediately transfers control to the target program using a
CICS XCTL command. A record, if specified, is passed in the COMMAREA. A
CICS SYNCPOINT occurs on a transfer to program statement if either of the
following situations occurs:
v You set the synchOnPgmTransfer build descriptor option to YES and a PSB is
scheduled.
v You set the synchOnPgmTransfer build descriptor option to NO for the
originating program and the originating program had scheduled a PSB and
different default PSB names were specified for the PSB records for the two
programs.
Otherwise, no CICS SYNCPOINT occurs. The following example shows the
command that EGL generates to transfer program control:
EXEC CICS XCTL('applnam') COMMAREA(record)
LENGTH(length of record)

Transfer from an EGL program to a non-EGL program using


transfer to program
The EGL program immediately transfers control to the target non-EGL program by
issuing a CICS XCTL to the program name specified in the transfer to program
statement. A record, if specified, is passed in the COMMAREA. A CICS
SYNCPOINT occurs on a transfer to program statement if a PSB is scheduled.

A transfer to program from an EGL program to a non-EGL program is


implemented in the same way as a transfer from one EGL program to another. You
must either specify isExternal = YES on the transfer to program statement or
specify fromPgm, toPgm, and linkType = EXTERNALLYDEFINED in the
transferToProgram element in the linkage options part used during generation.
The isExternal property or the EXTERNALLYDEFINED link type indicate that all
resources allocated by Rational COBOL Runtime for zSeries are released. The
non-EGL program receives data in the COMMAREA.

Transfer from a non-EGL program to an EGL program using


CICS XCTL
The originating program issues a CICS XCTL command to transfer to the target
EGL program. A record can be passed and will be used to initialize the record
identified by the inputRecord property of the EGL program.

The originating program must be defined as a main program, and the target
program name is the only required parameter. That parameter must point to a
valid EGL program name.
EXEC CICS XCTL ('applnam') COMMAREA(record)
LENGTH (length of record)

262 EGL Programmer’s Guide


If the target program is segmented, be sure that before the target program issues a
converse statement, it sets sysVar.transactionID to a transaction code associated
with the target program in a CICS TRANSACTION entry. Otherwise, when the
input from the terminal is received, the default value in sysVar.transactionID (the
current transaction code) causes the non-EGL program to be restarted instead of
the target EGL program.

You can set sysVar.transactionID to the proper transaction code by doing one of
the following:
v Specifying the transaction code as the restartTransactionID build descriptor
option.
v Moving the transaction code to sysVar.transactionID within the program before
the first converse statement.

Transfer to transaction
A transfer to transaction statement can specify an optional record. This transfer to
transaction statement causes a new CICS transaction to be invoked. Recoverable
resources are committed as part of the transfer process. The new transaction is
scheduled as soon as the first transaction ends. The following sections provide a
more detailed description of how a transfer to transaction statement works in the
CICS environment.

Transfer from an EGL program to an EGL program using transfer


to transaction
The following sections describe the differences in the transfer to transaction
statement depending on the value you specify for the genReturnImmediate build
descriptor option.

transfer to transaction with genReturnImmediate=″NO″: If you set the


genReturnImmediate build descriptor option to NO, the originating program
issues an EXEC CICS START command for the target transaction. If a record is
specified in the transfer to transaction statement, the record is passed as FROM
data on the EXEC CICS START command; otherwise, the FROM and LENGTH
parameters are not used.

The following example shows the format of the START command that EGL
generates if a record is specified in the transfer to transaction statement:
EXEC CICS START TRANSID('transid') FROM(record)
LENGTH(length of record)
TERMID(current-terminal)

EGL always includes the TERMID option of the CICS START command if the
transfer to transaction is issued from a main text UI program. The transaction is
not invoked unless the terminal is in TRANSCEIVE status in the CICS TCT.

A START command refers to a CICS transaction ID that is 4 characters or less.


CICS starts the new CICS transaction on the same terminal as the originating
program if the terminal is not currently in TRANSACTION status.

The started transaction can start a non-EGL program or an EGL program defined
as a main text UI program. After starting the new transaction, the program issuing
the transfer to transaction statement ends.

transfer to transaction with genReturnImmediate=″YES″: If you set the


genReturnImmediate build descriptor option to YES, the originating program

Transfer of control across programs 263


issues an EXEC CICS RETURN IMMEDIATE command for the target program. If a
record is specified, the record is passed in the 11th through nth bytes of the
COMMAREA. The first 10 bytes are binary zeros indicating that this is a transfer
to transaction statement passing a record. The following example shows the EXEC
CICS RETURN IMMEDIATE command that EGL generates if a record is specified
on the transfer to transaction statement.
EXEC CICS RETURN TRANSID('transid') COMMAREA(name of COMMAREA)
LENGTH(length of COMMAREA)
IMMEDIATE

Transfer from an EGL program to a non-EGL program using


transfer to transaction
A transfer to transaction statement from an EGL program to a non-EGL program
is implemented in different ways depending on the genReturnImmediate build
descriptor option. You must either specify isExternal = YES on the transfer to
transaction statement or specify the toPgm and externallyDefined = YES in the
transferToTransaction element in the linkage options part used during generation.
You can use the isExternal or the externallyDefined option to provide
documentation that this is a transfer to a non-EGL program. Because transfer to
transaction starts a new CICS transaction, a CICS SYNCPOINT occurs as a result
of the transfer statement.

If the genReturnImmediate build descriptor option is set to NO, the transfer to


transaction statement is implemented as an EXEC CICS START command. The
record passed when using a transfer to transaction statement is put into CICS
temporary storage. The non-EGL target program must retrieve the record into its
own data area. CICS also passes the length of the retrieved data to the program.
This length is zero if no record is passed. The following CICS command retrieves
the passed record:
EXEC CICS RETRIEVE INTO(myWorkingStorageArea)
LENGTH(workLength)

Be sure to put the length of myWorkingStorageArea into workLength before executing


the RETRIEVE command.

If the genReturnImmediate build descriptor option is set to YES, then the transfer
to transaction statement is implemented as an EXEC CICS RETURN IMMEDIATE.
The first 10 bytes of the COMMAREA received by the target program is binary
zeros. If a record is specified in the transfer to transaction statement, that record is
found in the COMMAREA starting at the 11th byte.

Transfer from a non-EGL program to an EGL program using


CICS START
The program can issue a CICS START command for the CICS transaction ID
associated with an EGL program. The terminal must be specified in the TERMID
option of the CICS START command if a main text UI program is being started.
The transaction is not invoked unless the terminal is in TRANSCEIVE status in the
CICS TCT. A record can be passed in the FROM area of the START command. If a
record is passed, it is used to initialize the record identified by the inputRecord
property for the EGL program. The target EGL program can specify a form in its
inputForm property that will be displayed automatically when the program loads.

The example below shows the format of the START command that can be used
when passing a record to the EGL program:

264 EGL Programmer’s Guide


EXEC CICS START TRANSID('transid') FROM(record)
LENGTH(length of record)
TERMID(current-terminal)

If the originating program uses the EXEC CICS START command, you can set the
genReturnImmediate build descriptor option to either YES or NO when you
generate the target program.

Transfer from a non-EGL program to an EGL program using


CICS RETURN IMMEDIATE
If the EGL program was generated with the genReturnImmediate build descriptor
option set to YES, the originating (non-EGL) program can issue a CICS RETURN
IMMEDIATE command for the CICS transaction. A record can be passed in the
COMMAREA and must start in the 11th byte. The first 10 bytes must be binary
zeros. If a record is passed, it is used to initialize the record identified by the
inputRecord property for the EGL program. The target EGL program can specify a
form in its inputForm property that will be displayed automatically when the
program loads.

The following example shows the format of the CICS RETURN IMMEDIATE when
you pass a record to the EGL program:
EXEC CICS RETURN TRANSID('transid')
COMMAREA(10 bytes of low-values + record)
LENGTH(10 + length of record)
IMMEDIATE

If you use CICS RETURN IMMEDIATE to transfer to an EGL program, you must
set the genReturnImmediate build descriptor option to YES when generating the
EGL program to be started.

Transfer using show


If you want to specify a form name in a transfer of control, you must use the show
statement. When you specify a form name with a show statement that includes a
returning clause, the originating program displays the form and returns to CICS.
The CICS RETURN command specifies the target transaction ID from the show
statement as the next transaction to be scheduled when the program user responds
to the screen. The target transaction must be associated with an EGL program. The
target program must have a form specified in its inputForm property, and this
form must be identical to the form specified in the show statement. The target
transaction receives control after the user presses an event key.

If a record is specified in the show statement, the record is received in the


COMMAREA by the target transaction and is used to initialize the record specified
by the inputRecord property of the target program.

You cannot transfer to a non-EGL program using a show statement.

Using asynchronous tasks


You can use the EGL system function vgLib.startTransaction() to start an
asynchronous transaction. You can write the program that is started for the
asynchronous transaction in either EGL or non-EGL. You can also write a non-EGL
program to start an EGL program asynchronously. The following sections describe
the techniques.

Transfer of control across programs 265


Starting asynchronous tasks from an EGL program
An EGL program starts an asynchronous task with a vgLib.startTransaction()
statement that generates a CICS START command. For example, the
vgLib.startTransaction() function might look like:
vgLib.startTransaction(requestRecord, prID, termID

The default behavior is to start a program that resides in the same CICS region;
however, you can specify a different region by defining the asynchLink element in
the linkage options part that is used when you generate the program that calls the
vgLib.startTransaction() system function. The prID and termID parameters are
ignored if the target transaction is started on a remote system.

The requestRecord must be in the following format:


v Bytes 1-2 of the record must be a SMALLINT field that is set to the length of the
data portion of the record plus 10.
v Bytes 3-6 must contain the CICS transaction ID.
v Bytes 7-10 must be blank.
v The data portion of the requestRecord starts in byte 11. Only the actual data
portion of the record is passed in the FROM option of the CICS START
command. If the started transaction is associated with an EGL program, that
EGL program receives the data portion of the requestRecord into the record
specified by the inputRecord property.

Depending on the value of the termID parameter, EGL issues the CICS START
command with or without an associated device:
v If termID is not specified, EGL associates the current terminal with the target
transaction; specifically, EGL assigns the current terminal identifier to the
TERMID option in the CICS START command.
v If termID is specified and its value is not binary zeros, EGL associates the
specified device (terminal or printer) with the target transaction; specifically,
EGL assigns the value of termID to the TERMID option in the CICS START
command but does not include the RTERMID option. Results are not predictable
if the value in termID is the CICS terminal ID that is associated with the current
transaction. To end the current transaction and start a new transaction at the
current terminal, use the transfer to transaction or show statement rather than
the vgLib.startTransaction() system function.
v If the value of the termID parameter is binary zeros, EGL associates no terminal
with the target transaction; specifically, EGL assigns the value of the prID
parameter to the RTERMID option in the CICS START command but does not
include the TERMID option. In addition, if you set the build descriptor option
printDestination to TERMINALID when you generate the started EGL program,
the prID parameter is the printer ID that is used to initialize the
converseVar.printerAssociation system variable in the target transaction. To set
the termID CHAR field to binary zeros, use an assignment statement containing
a hex literal for 4 bytes of binary zeros, as in the following example:
myCHAR = x"00000000";
v The target transaction must have a CICS TRANSACTION entry.
v If the first program in the started transaction is a non-EGL program, it must
issue a CICS RETRIEVE to get the passed work area and terminal information.
For more information, see “Retrieving data for a started task in a non-EGL
program” on page 267.

266 EGL Programmer’s Guide


Starting an EGL program asynchronously from a non-EGL
program
To start an asynchronous transaction that is associated with an EGL program from
a non-EGL program, issue a CICS START command like the following:
EXEC CICS START ('transid') FROM(workRecord) LENGTH(length of workRecord)
TERMID(destTermid)
RTERMID(asyncPrintDest)

The started EGL program must be a main basic program. It uses the workRecord to
initialize the record specified by the inputRecord property of the EGL program.

The RTERMID and TERMID options have the following meanings when starting
asynchronous tasks:
v If you want to start an asynchronous task without an associated CICS terminal
ID, then omit the TERMID keyword from the START command.
v If you want to start a task with an associated terminal ID, then the value you
specify in the TERMID option should be a valid CICS terminal ID. The results
are not predictable if you specify the terminal ID that is associated with the
current transaction.
v The value in the RTERMID option should be the print destination for the started
EGL program. if you set the build descriptor option printDestination to
TERMINALID when you generate the started EGL program, the RTERMID value
is used to initialize converseVar.printerAssociation in the started EGL program.

Retrieving data for a started task in a non-EGL program


Non-EGL programs started with the vgLib.startTransaction() system function must
always include the RTERMID option on the CICS RETRIEVE command that is
used to retrieve the passed record, even though the value might be all zeros.

The program can receive the data that was passed by doing the following:
EXEC CICS RETRIEVE INTO (workRecord) LENGTH(length of workRecord)
RTERMID(userRtermid)

The options for the CICS RETRIEVE command have the following meanings when
the non-EGL program is started as a result of vgLib.startTransaction():
v workRecord must be defined to match the data portion of the requestRecord that
you used in the vgLib.startTransaction() system function (from byte 11 through
the end of the requestRecord).
v Be sure to put the length of workRecord into LENGTH.
v If the RTERMID option contains 4 bytes of binary zeros, it should be ignored. If
the RTERMID option is not 4 bytes of binary zeros, it contains the printer (prID
parameter) specified for the vgLib.startTransaction() function.
Related concepts
“Transfer of control across programs” on page 251
Related tasks
“Calling programs in CICS environments” on page 254

Calling programs in IMS and z/OS batch environments


In non-CICS environments, standard OS linkage conventions are used. Up to 30
parameters can be passed on a call statement. The called program runs and returns
to the calling program when the program ends.

Transfer of control across programs 267


Use the linkage options part to specify the type of linkage generated for a call
statement. For non-CICS environments, you can specify that the call statement be
generated either as a DYNAMIC or a STATIC COBOL call with parameters passed
using a standard COBOL parameter list (OSLINK), with all parameters passed by
reference.

Calls from an EGL program to an EGL program


EGL call statements are generated as standard COBOL CALLs. The parameters on
the EGL call statement are the parameters on the COBOL CALL. All parameters
are passed by reference, not by content. Use the linkage options to specify whether
the COBOL CALL is a dynamic or static call.

The compiled COBOL CALL passes parameters using standard linkage


conventions. Register 1 points to a list of parameter addresses. The high order byte
of the last parameter address is set to 1, as in the following illustration.

Register 1 4 Byte Parm Pointer

.
. 1 to 30 parameter
. pointers

High Order Byte,


Bit 0 = 1 4 Byte Parm Pointer

Special considerations apply if you pass dliLib.psbData or a PCBRecord as a


parameter. For more information, see “Format of the dliLib.psbData structure” on
page 253 and “Format of a PCBRecord” on page 253.

Sharing called programs between environments


Programs generated for IMS/VS, IMS BMP, and z/OS Batch can call subprograms
generated for the z/OS Batch environment. You must ensure that the z/OS Batch
program does not do anything that is not supported in all the runtime
environments. You can do this by generating the z/OS Batch program (with the
build descriptor option prep set to NO) for all potential runtime environments
before generating it for z/OS Batch (with the build descriptor option prep set to
YES).

Calls from an EGL program to a non-EGL program


A call to a non-EGL program is generated in the same way as a call to an EGL
program. Calls to programs written in PL/I must be made as static calls. If the
non-EGL program is not written in COBOL, follow the rules for interfacing to
other languages described in the application programming guide for your release
of COBOL.

Calls from a non-EGL program to an EGL program


The non-EGL program uses a standard COBOL CALL statement to call the EGL
program. All parameters are passed by reference, not by content. Calls from
programs written in PL/I must be made as static calls. If the non-EGL program is
not written in COBOL, follow the rules for interfacing to other languages described
in the application programming guide for your release of COBOL.

268 EGL Programmer’s Guide


Avoiding multiple calls to runtime services initialization
If the first program invoked in the run unit is a non-EGL program, and the
program calls EGL programs repeatedly, then Rational COBOL Runtime for zSeries
performs initialization and termination functions on each call. The overhead for
these calls can be significant if the number of calls is large. To avoid the overhead
and perform initialization and termination once, EGL provides a wrapper program
for each environment. You must link edit the appropriate wrapper program with
your EGL program. To do this automatically, create a link edit part with the same
name as your EGL program. If your EGL program does not need to be link edited
with any programs other than the wrapper program, use the link edit commands
as shown below, substituting your program name for the name YOURPROG.
SELALMD represents the runtime services load library.

z/OS Batch control statements:


CHANGE NONVGRTN(YOURPROG)
CHANGE ELAAPPL(ELAWBAT)
INCLUDE SELALMD(ELAWBAT)
ENTRY ELARMAIN
NAME YOURPROG(R)

IMS BMP control statements:


CHANGE NONVGRTN(YOURPROG)
CHANGE ELAAPPL(ELAWBMP)
INCLUDE SELALMD(ELAWBMP)
ENTRY ELARMAIN
NAME YOURPROG(R)

IMS/VS control statements:


CHANGE NONVGRTN(YOURPROG)
CHANGE ELAAPPL(ELAWIMS)
INCLUDE SELALMD(ELAWIMS)
ENTRY ELARMAIN
NAME YOURPROG(R)

If you need to link your program with other modules (such as a PL/I program, for
example), see Link edit part examples.

Calling a CICS program from an EGL z/OS batch program


z/OS uses the External CICS Interface (EXCI) to call programs in a CICS region.
The called CICS program can be EGL developed or externally developed.

Use the linkage options part to specify how you want EGL to generate the call
statement:
v The type must be remoteCall.
v The remoteComType must be CICSEXCI.
v To pass parameters to the called program, set the parmForm property of the
callLink element to COMMDATA.

When processing the call statement, EGL generates the necessary COBOL code to
call via EXCI. For more information on these linkage options, see “Calling
programs in CICS environments” on page 254.

Calling a CICS program from the z/OS batch environment has the following
limitations:
v Client unit of work is not supported.

Transfer of control across programs 269


v Channels and containers are not supported for the EXCI call from the z/OS
batch environment.
v You cannot pass EGL variable length parameters (such as STRING type
variables) to the called program.
v DL/I is not supported.

Example
In the following example, a program named calledExci is called from z/OS batch.
The call uses the following linkage options:
v remoteComType = CICSEXCI (required)
v alias = CALLED
v location = NQA17C03 (required)
v luwControl = SERVER
v parmForm = COMMDATA
v pgmName = calledExci
v remotePgmType = EGL | EXTERNALLYDEFINED (has no effect)
v serverID = ABCD (default is CSMI)
v type = REMOTE
v conversiontable (has no effect)

The calling program includes the following EGL statement:


call "calledExci"(d, j);
Related concepts
“Transfer of control across programs” on page 251
Related reference
“Format of the dliLib.psbData structure” on page 253
“Format of a PCBRecord” on page 253
Related tasks
“Transferring control in the IMS/VS environment” on page 275
“Transferring control in IMS BMP and z/OS batch environments”
“Calling programs in CICS environments” on page 254

Transferring control in IMS BMP and z/OS batch environments


Transfers in the IMS BMP and z/OS batch environments are implemented in the
following ways:
v An EGL program initiates the transfer with either of the following statements:
– transfer to program, implemented as either a static or dynamic call when
transferring to another EGL program, or as an OS XCTL macro when
transferring to a non-EGL program.
– transfer to transaction, implemented as an OS XCTL macro.
v A non-EGL program initiates a transfer to an EGL program with the OS XCTL
command.

The next table outlines the different ways of implementing the transfers.

270 EGL Programmer’s Guide


EGL Statement From Program To Program How Implemented
transfer to program EGL EGL COBOL CALL
Non-EGL OS XCTL
Non-EGL EGL
transfer to EGL EGL
transaction
Non-EGL
Non-EGL EGL

The EGL build server statically links an EGL COBOL runtime stub program with
each generated main program. This EGL COBOL runtime stub activates the EGL
runtime environment and starts the first program in the run unit. The stub also
fulfills the transfer request in response to a transfer statement issued by any
program in the run unit.

Transfer from an EGL program to an EGL program using


transfer to program
When an EGL program uses a transfer to program statement to transfer control to
another EGL program, the transferring EGL program ends and returns control to
the EGL COBOL runtime stub linked with the EGL program. The stub issues a
static or dynamic call in accordance with the linkage options part specified at
generation time, for the EGL transfer-from program. The EGL COBOL runtime stub
program remains in control, and the EGL runtime environment remains active.

If the EGL transfer-to program in turn uses a transfer to program statement,


control again returns to the EGL COBOL runtime stub program, which handles the
requested transfer.

In each case, the EGL transfer-to program starts at its main function.

Transfer from an EGL program to an EGL program using


transfer to transaction
When an EGL program uses a transfer to transaction statement to transfer control
to another EGL program, the transferring EGL program ends and returns to a
COBOL runtime stub program linked with the EGL program. The stub issues an
OS XCTL macro to transfer to the target program. Both COBOL and Rational
COBOL Runtime for zSeries clean up and reestablish the runtime environment
each time an OS XCTL macro is used. Both COBOL and Rational COBOL Runtime
for zSeries use termination and initialization logic for the OS XCTL. You can set
the synchOnTrxTransfer build descriptor option to YES to control commit points.

Transfer to a non-EGL program using either transfer to


program or transfer to transaction
When an EGL program uses a transfer to program or transfer to transaction
statement to transfer control to a non-EGL program, the transferring EGL program
ends and returns to the EGL COBOL runtime stub program linked with the EGL
program. The stub issues an OS XCTL macro to transfer to the non-EGL program.
Both COBOL and Rational COBOL Runtime for zSeries clean up the runtime
environment each time an OS XCTL macro is used. Both COBOL and Rational
COBOL Runtime for zSeries use termination logic for the OS XCTL. The non-EGL
program establishes it own runtime environment and does any initialization logic

Transfer of control across programs 271


required by the OS XCTL. You can set the build descriptor option
synchOnTrxTransfer to YES to control commit points.

If the EGL program was started with a PSB, both the record specified on the
transfer and the dliLib.psbData structure are passed as OS XCTL parameters.
Otherwise, only the record specified on the transfer is passed. Register 1 is 0 if no
parameters are passed. See “Standard linkage conventions.”

Special considerations apply if you pass dliLib.psbData. For more information, see
“Format of the dliLib.psbData structure” on page 253.

The target program can issue a FREEMAIN for the parameters passed from the
EGL program. The FREEMAIN address is the address in register 1. The
FREEMAIN length is the value in the length field plus 100.

When a transfer to program or transfer to transaction statement is used, you must


indicate that you are transferring to a non-EGL program, in one of the following
ways:
v Set the property isExternal to yes on the transfer statement.
v Specify the externallyDefined option in the linkage options part, in the linkage
information for the transferToProgram or transferToTransaction element.

Transfer from a non-EGL program to an EGL program using


OS XCTL
Transfers from a non-EGL program to an EGL program in the IMS BMP and z/OS
batch environments can be implemented by using an OS XCTL to the EGL
program. Two ways of passing parameters with the OS XCTL command are
described in the following sections.

Reference information for transfers


The following sections describe the two ways of passing parameters to an EGL
program using an OS XCTL command.

Standard linkage conventions


One or two parameters are passed to the receiving program on the OS XCTL. The
first parameter is the working storage buffer consisting of a 2-byte binary length
field containing the buffer length (working storage data length plus 10), an 8-byte
filler field, and the working storage data. The second parameter, used only if the
EGL program is a DL/I program, is the dliLib.psbData structure. The following
diagram shows the format of the parameter list that the transferring program
should pass.

272 EGL Programmer’s Guide


Register 1 Pointer to Length (2 bytes)
Working Storage
Filler (8 bytes)
High order byte Pointer to
must have dliLib.psbData Working Storage Data
bit 0 = 1

dliLib.psbData

Figure 3. Passing parameters on OS XCTL: Example 1

See “Format of the dliLib.psbData structure” on page 253 for the format of the
dliLib.psbData structure. Register 1 can be set to 0 if there is nothing to pass.

Standard linkage conventions that support FREEMAIN in the


EGL program
If you want Rational COBOL Runtime for zSeries to issue a FREEMAIN for the
areas passed to the EGL program, obtain a single area for all passed data with a
length equal to the length of the working storage data you want to pass plus 110
bytes (see the figure below). Set up the parameter list pointers at the top of the
area, put the length and filler fields starting at offset 100 in the area, and move the
working storage data to be passed into the area at offset 110. Issue the OS XCTL
macro with register 1 pointing to the start of the area.

Transfer of control across programs 273


Register 1 000 Pointer to working storage

004 Pointer to dliLib.psbData

008 PSB name

016 Simulated UIB pointer

PCB
020 Simulated UIB Address
List

026 Reserved for Host Services

100 Length of working storage

102 Reserved for Host Services

110 Working storage data

Figure 4. Passing parameters on OS XCTL: Example 2

Note: The high-order bit must be turned on for one of the following pointers:
v The pointer to working storage if dliLib.psbData is not passed
v The pointer to dliLib.psbData if dliLib.psbData is passed.

PCB list linkage


If the EGL program is a DL/I program, the non-EGL program can also transfer to
the EGL program, passing a list of PCBs as parameters on the OS XCTL. The EGL
program receives control in this way if it is started as a DL/I z/OS batch job. The
PCBs must map to the PSB definition expected by the EGL program.

The input record for the EGL program is initialized according to data type if the
EGL program is started with this interface.
Related concepts
“Transfer of control across programs” on page 251
Related reference
“Format of the dliLib.psbData structure” on page 253
Related tasks
“Calling programs in IMS and z/OS batch environments” on page 267
“Transferring control in the IMS/VS environment” on page 275

274 EGL Programmer’s Guide


Transferring control in the IMS/VS environment
Different considerations apply for transferring when IMSADF II programs are
involved. For more information, see “Transferring to and from IMSADF II
programs” on page 293.

EGL main Text UI programs that are generated for the IMS/VS target environment
run as IMS message processing programs (MPPs).

Transferring program control with a transfer to transaction statement is not


supported for IMS/VS main basic programs. A non-EGL program can invoke EGL
MPP programs using an IMS program-to-program message switch. The following
types of message switches are supported:
Immediate message switch
Program A passes control directly to a transaction that is associated with
program B without first responding to the originating terminal. For a
conversational MPP, the program does this by inserting the scratch pad area
(SPA) using an alternate PCB that has its destination set to the new transaction
name. For a nonconversational MPP, the program inserts a message using an
alternate PCB that has its destination set to the new transaction name.
Deferred message switch
Program A responds to the terminal and informs IMS to start a transaction that
is associated with program B on the next input from the terminal. For a
conversational MPP, the message switch is achieved by modifying the SPA to
specify the new transaction name before sending it back to IMS (using the I/O
PCB). For a nonconversational MPP, the message switch is achieved by
including the next transaction name on the map in such a way that it becomes
the first 8 bytes of the input message.

The definition and generation options of the target non-EGL program or EGL
program control the type of switch that is possible and the way the data is passed.
Transferring from conversational to nonconversational or from nonconversational
to conversational is not supported for EGL programs.

If the target transaction is an EGL program, the use of the property inputForm
determines which type of message switch is valid:
v If inputForm is not specified, an immediate message switch is required.
v If inputForm is specified, either a deferred program-to-program message switch
(EGL show statement) or an immediate program-to-program message switch
(EGL transfer to transaction statement) can be used. If the immediate switch is
used, the input form (identified in the inputForm property) is automatically
displayed by the target program. However, this is less efficient than a deferred
switch because the target program must be processed twice: once to display the
input form and once to read the data entered by the program user.
If a non-EGL program does a deferred program-to-program message switch to an
EGL program, the non-EGL program should turn on the modified data tag (MDT)
attribute for all fields on the form and should set all other field properties to the
values that were defined during form definition. If the program user requests help
or if edit errors occur, the program displays default data in any fields that did not
have the MDT attribute set and were not modified by the program user. The EGL
program uses the defined properties for all other field properties.

If the target transaction is a non-EGL program that needs form input from the
message queue at the start of processing, the EGL program should use a deferred

Transfer of control across programs 275


program-to-program message switch (EGL show statement). Otherwise, the EGL
program should use an immediate program-to-program message switch (EGL
transfer to transaction statement).

The way data is passed is controlled by the following factors:


v Whether the program is conversational or nonconversational.
v Whether the switch is immediate or deferred.

Transferring between conversational programs


The following table shows the methods used to pass data between conversational
programs (generated with spaSize > 0 build descriptor option).
Table 43. Program switching in conversational EGL programs (non-IMSADF interface)
Immediate switch (optional input
Action form) Deferred switch (with input form)
Coding and Define both programs as Define both programs as
generating segmented = YES. Generate both segmented = YES. Generate both
programs as conversational programs as conversational
(spaSize > 0). (spaSize > 0).
Performing the The transferring program cannot The transferring program must
transfer send a form. If it is an EGL write the form to a message queue
program, it uses a transfer to associated with the terminal after
transaction statement to send a first writing the SPA. If it is an
record. EGL program, it does this using a
show with a form and an optional
record.
Using an input The target program can optionally The target program must have an
form have an input form. input form.
Passing a record The record is transferred in the The record, if any, is transferred in
SPA. the SPA.
Specifying If spaStatusBytePosition is If spaStatusBytePosition=n is
segmentation specified, the segmentation status specified, the segmentation status
status byte byte is always placed in the last byte is placed in either position 15
byte of the SPA. The target or the last byte of the SPA, based
program always ignores the value on the value of n. The target
of the segmentation status byte. program uses the value of the
segmentation status byte when
there is an input form integrity
problem caused by the program
user pressing PA1 or PA2.
Note: The segmentation status byte specified by spaStatusBytePosition is used only for
program-to-program transfers for conversational programs. The byte is present for transfers
between conversational programs and other programs. However, a transferring non-EGL
program should always set the byte to blank. A target non-EGL program should always
ignore the value of the segmentation status byte.

Depending on whether you use a transfer to transaction or a show statement to


accomplish the transfer, the following can be passed between two programs:
v A scratch pad area (SPA) can be passed on either a transfer to transaction or a
show statement.
v An MFS map (EGL form) can be passed on a show statement only.

276 EGL Programmer’s Guide


For more information and layouts, see “Format of the IMS SPA for message
switching” on page 286 and “Format of the IMS MFS message input descriptor
(MID)” on page 289.

A conversational program always uses an SPA. The SPA is passed on both


immediate and deferred message switches. When you generate an EGL main Text
UI program with spaSize > 0, EGL uses the SPA as follows
v When the transaction first starts for a user, EGL initializes the input record for
that program from the data portion of the SPA.
v When you use a transfer to transaction or a show statement to pass a record to
another transaction, EGL sets the data portion of the SPA to the data in the
specified record.
In addition, on a deferred switch, you can pass an MFS map to a terminal. EGL
does this as follows:
v When the transaction first starts for a user, EGL will check for a passed form. If
such a form exists, EGL uses that data to initialize the input form for the
program.
v On a show statement, EGL sends the form to the terminal.

Conversational immediate program-to-program message switch


Conversational immediate program-to-program message switches are supported in
the following situations:
v Between two EGL programs.
v From a non-EGL program to an EGL program.
v From an EGL program to a non-EGL program.

Immediate switch between two EGL programs: With this technique, two
segmented conversational EGL programs can change both the transaction name
and the PSB name without presenting a form to the program user. Different
FormGroups can be used by the two programs. The example below shows a
skeleton definition of the two programs.
program ProgramA type textUIProgram
{segmented=yes, inputRecord="basicRecord1",
@DLI { psb="psb" } }

// Declarations
basicRecord1 TRANSFER_RECORD;
psb PSB1A;

// FormGroup
use FORMGX;

function main()
...
sysVar.transferName = 'trx1b';
transfer to transaction sysVar.transferName passing basicRecord1;
...
end // end main
end // end ProgramA

program ProgramB type textUIProgram // inputForm is optional


{segmented=yes, inputRecord="basicRecord1", inputForm="form2",
@DLI { psb="psb" } }

// Declarations
basicRecord1 TRANSFER_RECORD;
psb PSB1B;

Transfer of control across programs 277


// FormGroup
use FORMGY;

function main()
// generated EGL logic does the following:
// initializes basicRecord1
// if inputForm is specified:
// converses form2
// performs edits for form2
// converses form2 until form2 passes all edits
// gives control to the first statement in the main function
...
end // end main
end // end ProgramB

The EGL-generated program control logic automatically handles the SPA and the
record (basicRecord1) that is passed from Program A to Program B. The data area
of the SPAs for programs A and B must be at least large enough to hold the larger
of the records involved.

Immediate switch from non-EGL program to EGL program: The non-EGL


program must be an IMS conversational program. The EGL program must be
defined similarly to program B in ″Immediate switch between two EGL programs″
above. The spaSize build descriptor option must specify the SPA size that is being
used by the non-EGL program.

The non-EGL program must do the following:


1. Create the SPA in the format defined in “Format of the IMS SPA for message
switching” on page 286. The data area in the SPA must match the definition of
the input record expected by the EGL program. The EGL-generated program
control logic removes the header information (length, SPA ID, transaction
name), so the EGL program receives only the data.
If you specified spaSize=n and spaStatusBytePosition=p as build descriptor
options, the segmentation status byte is at the end of the SPA, regardless of the
value of spaStatusBytePosition. The non-EGL program should initialize the
segmentation status byte to blank before inserting the SPA.
2. Insert the SPA into an alternate PCB. The alternate PCB must have its
destination set to the transaction name for the EGL program.

Immediate switch from EGL program to non-EGL program: The non-EGL


program must be an IMS conversational program. The EGL program must be
defined similarly to program A in ″Immediate switch between two EGL programs″
above. The spaSize build descriptor option must specify the SPA size that is being
used by the non-EGL program.

The non-EGL program must issue a get unique to the I/O PCB to read the SPA.
For the required layout of the SPA, see “Format of the IMS SPA for message
switching” on page 286. The SPA is created by the EGL program control logic. The
data area of the SPA contains the record that the EGL program passed on the
transfer to transaction statement.

If you specified spaSize=n and spaStatusBytePosition=p as build descriptor


options, the segmentation status byte is at the end of the SPA, regardless of the
value of spaStatusBytePosition. The non-EGL program should ignore the last byte
of the SPA.

278 EGL Programmer’s Guide


Conversational deferred program-to-program message switch
Conversational deferred program-to-program message switches are supported in
the following situations:
v Between two EGL programs.
v From a non-EGL program to an EGL program.
v From an EGL program to a non-EGL program.

Deferred switch between two EGL programs: With this technique, two
segmented conversational EGL programs can change both the transaction name
and the PSB name when a form is presented to the program user. You must use
the same formGroup for both programs. You do not have to transfer a record, but
a form is required. The example below shows a skeleton definition of the two
programs.
program ProgramA type textUIProgram
{segmented=yes, inputRecord="basicRecord2",
@DLI { psb="psb" } }

// Declarations
basicRecord2 TRANSFER_RECORD;
psb PSB2A;

// FormGroup
use FORMG2;

function main()
...
sysVar.transferName = 'trx2b';
show form2 returning to sysVar.transferName passing basicRecord2;
...
end // end main
end // end ProgramA

program ProgramB type textUIProgram // inputForm is required


{segmented=yes, inputRecord="basicRecord2", inputForm="map2",
@DLI { psb="psb" } }

// Declarations
basicRecord2 TRANSFER_RECORD;
psb PSB2B;

// FormGroup
use FORMG2;

function main()
// generated EGL logic does the following:
// initializes basicRecord2
// performs edits for map2
// converses map2 until map2 passes all edits
// gives control to the first statement in the main function
...
end // end main
end // end ProgramB

Deferred switch from non-EGL program to EGL program: The non-EGL program
must be an IMS conversational program. The EGL program must be defined
similarly to program B in ″Deferred switch between two EGL programs″ above.
The spaSize build descriptor option must specify the SPA size that is being used
by the non-EGL program.

The non-EGL program must do the following:

Transfer of control across programs 279


1. Create the SPA in the format defined in “Format of the IMS SPA for message
switching” on page 286. The data area in the SPA must match the definition of
the input record expected by the EGL program. The EGL program control logic
removes the header information (length, SPA ID, transaction name), so the EGL
program receives only the data.
If you specified spaSize=n and spaStatusBytePosition=p as build descriptor
options, then you must initialize the segmentation status byte at the offset
within the SPA specified by spaStatusBytePosition=p. Initialize the
segmentation status byte to blank.
2. Insert the SPA into the I/O PCB.
3. Insert the MFS map (EGL form) into the I/O PCB using the message output
descriptor that corresponds to the message input descriptor in the EGL
program. The non-EGL program must set the modified data tag (MDT)
attribute for all variable data fields on the MFS map (EGL form) to be passed to
the EGL program on the deferred switch. All other attributes should be left at
their default values. For the required layout of the map, see “Format of the IMS
MFS message input descriptor (MID)” on page 289. EGL generates a COBOL
copybook for the MID/MOD record layout that should be used by the
non-EGL program to ensure that the record formats match.

Deferred switch from EGL program to non-EGL program: The non-EGL program
must be an IMS conversational program. The EGL program must be defined
similarly to program A in ″Deferred switch between two EGL programs″ above.
The EGL program must set the modified property to YES for all variable data
fields on the form that are required as input in the non-EGL program. The spaSize
build descriptor option must specify the SPA size that is being used by the
non-EGL program.

The non-EGL program must do the following:


1. Issue a get unique to the I/O PCB to read the SPA. For the required layout of
the SPA, see “Format of the IMS SPA for message switching” on page 286. The
SPA is created by the EGL program control logic. The data area of the SPA
contains the record that the EGL program passed on the show statement.
If you specified spaSize=n and spaStatusBytePosition=p as build descriptor
options, the segmentation status byte is either at position 15 or at the last byte
of the SPA. The non-EGL program should ignore the value of the segmentation
status byte.
2. Issue a get next to the I/O PCB to retrieve the message input descriptor that
corresponds to the message output descriptor used by the EGL program. For
the required layout of the map, see “Format of the IMS MFS message input
descriptor (MID)” on page 289. EGL generates a COBOL copybook for the
MID/MOD record layout that should be used by the non-EGL program to
ensure that the record formats match.
3. Use the value of the map MID field EZEMAP-SSM-STATUS to determine
whether there has been a MFS map (EGL form) integrity problem. If
EZEMAP-SSM-FILLCHAR is true and this is not an initial SPA (that is, not the
first transaction in the conversation), then an input map integrity problem has
occurred, possibly because the program user has pressed PA1 or PA2. Take
whatever action is appropriate for the program to recover the data that was lost
from the input map. This might involve issuing an error message to the
program user and restarting the transaction or taking other recovery actions
depending on the program design.

280 EGL Programmer’s Guide


Transferring between nonconversational programs
The following table shows the methods used to pass data between
nonconversational programs. A nonconversational program is a main textUI
program generated with the spaSize build descriptor option set to 0 (as is the
default).
Table 44. Program switching in nonconversational EGL programs (non-IMSADF interface)
Immediate switch (optional input
Action form) Deferred switch (with input form)
Coding and Define both programs as Define both programs as
generating segmented = YES. Generate both segmented = YES. Generate both
programs as nonconversational programs as nonconversational
(spaSize = 0). (spaSize = 0).
Performing the The transferring program cannot The transferring program must
transfer send a form. If it is an EGL write the form to a message queue
program, it uses a transfer to associated with the terminal. If it is
transaction with a record. an EGL program, it uses a show
statement with a form and an
optional record.
Using an input The target program can optionally The target program must have an
form have an input form. input form.
Passing a record The record is transferred in the The record, if any, is transferred in
message. the work database.

Depending on whether a transfer to transaction or a show statement used, the


following can be passed on a transfer between two nonconversational programs:
v An IMS message segment. See “Format of EGL input message segment for IMS
message switch” on page 288.
v An MFS map (EGL form). The same MID and MOD definitions are used for
conversational and nonconversational transfers. For the record layout and an
example of the COBOL definition for a map message input descriptor (MID) for
a deferred program-to-program message switch, see “Format of the IMS MFS
message input descriptor (MID)” on page 289.

Nonconversational immediate program-to-program message


switch
Nonconversational immediate program-to-program message switches are
supported in the following situations:
v Between two EGL programs.
v From a non-EGL program to an EGL program.
v From an EGL program to a non-EGL program.

Immediate switch between two EGL programs: When developing EGL programs,
this technique is the same as transferring with segmented conversational EGL
programs, except that the spaSize build descriptor option is set to 0
(nonconversational). With this technique two nonconversational EGL programs can
change both the transaction name and the PSB name without presenting a form to
the program user. Different form groups can be used by the two programs.

The outlines of the two programs are identical to those in a conversational


immediate switch between two EGL programs; the difference is in the value of the
spaSize build descriptor option at generation time. For better performance,
however, you may omit the inputForm for program B:

Transfer of control across programs 281


program ProgramA type textUIProgram
{segmented=yes, inputRecord="basicRecord1",
@DLI { psb="psb" } }

// Declarations
basicRecord1 TRANSFER_RECORD;
psb PSB1A;

// FormGroup
use FORMGX;

function main()
...
sysVar.transferName = 'trx1b';
transfer to transaction sysVar.transferName passing basicRecord1;
...
end // end main
end // end ProgramA

program ProgramB type textUIProgram


// omit inputForm for better performance
{segmented=yes, inputRecord="basicRecord1", inputForm="form2",
@DLI { psb="psb" } }

// Declarations
basicRecord1 TRANSFER_RECORD;
psb PSB1B;

// FormGroup
use FORMGY;

function main()
// generated EGL logic does the following:
// initializes basicRecord1
// if inputForm is specified:
// converses form2
// performs edits for form2
// converses form2 until form2 passes all edits
// gives control to the first statement in the main function
...
end // end main
end // end ProgramB

The EGL-generated program control logic automatically handles the IMS message
that is used to transfer control and the record that is passed from program A to B.

Immediate switch from non-EGL program to EGL program: The non-EGL


program must be an IMS nonconversational program. The EGL program must be
defined similarly to program B in the nonconversational ″Immediate switch
between two EGL programs.″

The non-EGL program must insert a message to an alternate PCB. The destination
must be set to the transaction name for the EGL program. The non-EGL program
must supply the header information (length, ZZ, and transaction name) in the
message. For the required layout of the message, see “Format of EGL input
message segment for IMS message switch” on page 288. The EGL-generated
program control logic automatically removes the header information, so the EGL
program receives only the data.

Immediate switch from EGL program to non-EGL program: The non-EGL


program must be an IMS nonconversational program. The EGL program must be
defined similarly to program A in the nonconversational ″Immediate switch
between two EGL programs.″

282 EGL Programmer’s Guide


The non-EGL program must issue a get unique to the I/O PCB to retrieve the
record that the EGL program passed on the transfer to transaction statement. For
the required layout of the message, see “Format of EGL input message segment for
IMS message switch” on page 288. The EGL-generated program control logic
automatically supplies the header information (length, ZZ, transaction name), so
the EGL program defines only the data. However, the non-EGL program must be
prepared to accept the header information.

Nonconversational deferred program-to-program message switch


Nonconversational deferred program-to-program message switches are supported
in the following situations:
v Between two EGL programs.
v From a non-EGL program to an EGL program.
v From an EGL program to a non-EGL program.

Deferred switch between two EGL programs: From an EGL developer’s


viewpoint, this technique is identical to transferring with segmented conversational
EGL programs, except that the spaSize build descriptor option is set to 0,
indicating nonconversational programs. With this technique two nonconversational
EGL programs can change both the transaction name and the PSB name when a
form is presented to the program user. You must use the same formGroup for both
programs. You do not have to transfer a record, but a form is required.

The outlines of the two programs are identical to those in the conversational
deferred switch between two EGL programs; the difference is in the value of the
spaSize build descriptor option at generation time:
program ProgramA type textUIProgram
{segmented=yes, inputRecord="basicRecord2",
@DLI { psb="psb" } }

// Declarations
basicRecord2 TRANSFER_RECORD;
psb PSB2A;

// FormGroup
use FORMG2;

function main()
...
sysVar.transferName = 'trx2b';
show form2 returning to sysVar.transferName passing basicRecord2;
...
end // end main
end // end ProgramA

program ProgramB type textUIProgram // inputForm is required


{segmented=yes, inputRecord="basicRecord2", inputForm="map2",
@DLI { psb="psb" } }

// Declarations
basicRecord2 TRANSFER_RECORD;
psb PSB2B;

// FormGroup
use FORMG2;

function main()
// generated EGL logic does the following:
// initializes basicRecord2
// performs edits for map2
// converses map2 until map2 passes all edits

Transfer of control across programs 283


// gives control to the first statement in the main function
...
end // end main
end // end ProgramB

Deferred switch from non-EGL program to EGL program: The non-EGL program
must be an IMS nonconversational program. The EGL program must be defined
similarly to program B in the nonconversational ″Deferred switch between two
EGL programs.″

The non-EGL program must do the following:


1. If a record is being transferred, call ELATSPUT to save the record in the work
database for the EGL program. For details on using ELATSPUT, see “Using the
EGL COBOL runtime work database for IMS/VS” on page 291.
2. Insert the MFS map (EGL form) to the I/O PCB using the message output
descriptor that corresponds to the message input descriptor used by the EGL
program. The non-EGL program must set the modified data tag (MDT)
attribute for all variable data fields on the map to be passed to the EGL
program on the deferred switch. All other attributes should be left at their
default values. For the required layout of the map, see “Format of the IMS MFS
message input descriptor (MID)” on page 289. EGL generates a COBOL
copybook for the MID/MOD record layout that should be used by the
non-EGL program to ensure that the record formats match.

Deferred switch from EGL program to non-EGL program: The non-EGL program
must be an IMS nonconversational program. The EGL program must be defined
similarly to program A in the nonconversational ″Deferred switch between two
EGL programs.″ The EGL program must set the modified property to YES for all
variable data fields on the form that are needed as input in the non-EGL program.

The non-EGL program must do the following:


1. Issue a get unique to the I/O PCB to retrieve the message input descriptor that
corresponds to the message output descriptor used by the EGL program. For
the required layout of the map, see “Format of the IMS MFS message input
descriptor (MID)” on page 289. EGL generates a COBOL copybook for the
MID/MOD record layout that should be used by the non-EGL program to
ensure that the record formats match.
2. If you are transferring a record, call ELATSGET to retrieve the record that the
EGL program passed on the show statement from the work database. For
details, see “Using the EGL COBOL runtime work database for IMS/VS” on
page 291.

Interfacing through serial files in IMS


EGL programs can communicate with non-EGL programs by performing add or
get next statements on records in serial files that are associated with the IMS
message queue.

The following types of programs can add records to serial files:


v Main textUI programs
v Main basic programs
v Called programs
Only main basic programs can retrieve records from serial files (using get next).

284 EGL Programmer’s Guide


Between EGL programs
An EGL program can add a series of serial records to the IMS message queue by
specifying the following information in a ResourceAssociations part at generation:
v Indication that the file is a message queue (fileType set to smsgq or mmsgq).
v The PCB name to be used. This must be the name of an alternate PCB.
The EGL program automatically handles the IMS header information (segment
length, ZZ, and transaction name). The transaction name is created from the
default systemName specified in the ResourceAssociations part at generation time,
or in the value of the resourceAssociation variable for the record (if it is used to
override the default). Do not include IMS header information in the EGL serial
record definition.

An EGL basic program, running as either an MPP or a transaction-driven batch


message processing program (BMP), can then use the file to read the messages
with get next statements. The EGL program automatically strips the header
information from the message and puts the data into the serial record.

From non-EGL program to EGL program


A non-EGL program can write a series of records to the IMS message queue for
later processing by an EGL basic program, running as either an MPP or a
transaction-driven BMP. The non-EGL program must insert a record in the format
shown in the following table to an alternate I/O PCB associated with the
transaction that processes the record.
Table 45. Format of the record inserted to the message queue
Length in
Field bytes Type of data Description
Segment length 2 Binary The length of the segment.
Reserved (ZZ) 2 Binary Reserved.
IMS transaction 8 Character The IMS transaction name for the EGL
name program.
Program- Variable Variable This area contains the data items defined in
defined fields the EGL serial record.

An EGL basic program uses get next to read a serial file associated with the I/O
PCB and then processes the message. The EGL program automatically removes the
IMS message header (segment length, ZZ, and transaction name), so the program
receives only the message data in the serial record.

From EGL program to non-EGL program


When an EGL program does an add to a serial file associated with a message
queue, the EGL program automatically adds the IMS message header in front of
the record data, and then inserts the message to the alternate PCB. The EGL
program is only concerned with the actual data in the message.

A non-EGL program running as either an MPP or a transaction-driven BMP can


process the message queue. The format of the message actually inserted to the
message queue and received by the non-EGL program is shown in the table in the
previous section, ″From non-EGL program to EGL program.″
Related concepts
“Transfer of control across programs” on page 251
Related reference

Transfer of control across programs 285


“Format of the IMS SPA for message switching”
“Format of the IMS MFS message input descriptor (MID)” on page 289
“Using the EGL COBOL runtime work database for IMS/VS” on page 291
“Format of EGL input message segment for IMS message switch” on page 288
Related tasks
“Transferring to and from IMSADF II programs” on page 293

Reference information for IMS/VS transfers


The following sections provide reference information for call and transfer
statements in the IMS/VS environment or when DL/I databases are being used.
v “Format of the IMS SPA for message switching”
v “Format of EGL input message segment for IMS message switch” on page 288
v “Format of the IMS MFS message input descriptor (MID)” on page 289
v “Using the EGL COBOL runtime work database for IMS/VS” on page 291

Format of the IMS SPA for message switching


EGL defines the format of the IMS scratch pad area based on the following build
descriptor options:
spaSize
Specifies the total length of the SPA, including the fields required by IMS (SPA
length, SPA ID, and IMS transaction name) as well as the EGL requirement for
a Segmentation Status Byte.
spaStatusBytePosition
This optional field is set either to 15 (if the status byte is to precede the data)
or to the same value as spaSize (if the status byte follows the data).
Table 46. Format of IMS scratch pad area
Length in
Field bytes Type of data Description
SPA length 2 Binary The length of the segment.
SPA ID 4 Binary A unique name used to identify the SPA to
IMS. This name must not be changed by
the MPP.
IMS transaction 8 Character The IMS transaction name for the EGL
name program.
Segmentation 1 Hexadecimal This optional byte is present if spaSize=n
Status Byte and spaStatusBytePosition=15 was
(Optional) specified and this is a deferred switch. It
indicates whether data was saved in the
work database.
Program data Variable Variable This area contains the record passed on the
transfer to transaction statement and
received by the target program in its input
record.

286 EGL Programmer’s Guide


Table 46. Format of IMS scratch pad area (continued)
Length in
Field bytes Type of data Description
Segmentation 1 Hexadecimal This optional byte is present if this is an
Status Byte immediate switch, and if spaSize=n and
(Optional) spaStatusBytePosition=n. (The status byte
position will always be either 15, if the
status byte is to precede the data, or equal
to the size of the SPA if the status byte
follows the data.) In this case the contents
of the byte are ignored. This optional byte
is also present if spaSize=n and
spaStatusBytePosition=n was specified and
this is a deferred switch. In this case, the
byte indicates whether data was saved in
the work database.

The following example shows the COBOL definition for a scratch pad area passed
in either a deferred or an immediate program-to-program message switch for
conversational processing. Keep in mind that PL/I requires a 4-byte length field
rather than the 2-byte length field used for COBOL. Refer to the IMS/VS
documentation for your system for additional information. The specific field names
are used for illustrative purposes only; the actual field names might vary in the
generated code.
* SPA IO area.
01 SPA.
05 SPA-LENGTH PIC S9(4) COMP.
05 SPA-ID PIC S9(9) COMP.
05 IMS-TRAN-NAME PIC X(8).
05 CSP-OPTIONAL-SSM-BYTE PIC X(1). See Note 1.
05 CSP-APPL-WS-DATA.
10 data-item-1 PIC ........................
10 data-item-2 PIC ........................
.
.
.
05 CSP-OPTIONAL-SSM-BYTE PIC X(1). See Note 2.

The following notes apply to this example:


1. This optional byte is present if spaSize=n and spaStatusBytePosition=15 was
specified and this is a deferred switch. It indicates whether data was saved in
the work database.
2. This optional byte is present if spaSize=n and spaStatusBytePosition=n was
specified and this is an immediate switch. In this case the contents of the byte
are ignored. This optional byte is also present if spaSize=n and
spaStatusBytePosition=n was specified and this is a deferred switch. In this
case, it indicates whether data was saved in the work database.

The data identified as ″Program data″ in the table above is treated as the input
record for the target program. This technique enables a non-EGL program to store
data in the SPA and switch to an EGL program (or a series of EGL programs) that
use or modify the SPA data. The EGL program can eventually switch back to a
non-EGL program with information from the EGL program contained in the SPA.
Follow the IMS restrictions regarding changes in the SPA size.

SPA size and transfer record size: The following table defines how the SPA, the
record specified on the transfer to transaction or show statement, and the input

Transfer of control across programs 287


record for the target program are related for conversational processing.
Table 47. Relationship of IMS SPA to transfer record
Data area size vs. transfer
Function record size Results
transfer to The size of the program data The program data area in the SPA is
transaction area in the SPA exceeds the created using the entire EGL record, and
size of the EGL record named the remaining bytes of SPA are initialized
in the transfer to transaction to blanks.
or show statement.
transfer to The size of the program data Extra bytes of the EGL record are
transaction area in the SPA is less than truncated.
that of the EGL record named
in the transfer to transaction.
Initialization of Size of the program data area Extra bytes of the program data area in
target in the SPA exceeds the size of the SPA are truncated when it is moved
program’s EGL record named as input into the input record.
input record record for the target program.
Initialization of Size of the program data area The input record is initialized from the
target in the SPA is less than that of program data area in the SPA, and the
program’s the EGL record named as remaining bytes of the input record are
input record input record for the target initialized based on the data type.
program.

Related concepts
“Transfer of control across programs” on page 251
Related tasks
“Transferring control in the IMS/VS environment” on page 275
Related reference
“Reference information for IMS/VS transfers” on page 286
The following sections provide reference information for call and transfer
statements in the IMS/VS environment or when DL/I databases are being used.

Format of EGL input message segment for IMS message switch


When you use the transfer to transaction statement in an IMS nonconversational
program, the optional record is passed as a message segment for an immediate
program-to-program message switch. The following table shows the record layout:
Table 48. Format for nonconversational immediate message switch
Length in
Field bytes Type of data Description
Segment length 2 Binary The length of the segment.
Reserved 2 Binary Reserved for IMS.
IMS transaction 8 Character The IMS transaction name for the EGL
name program.
Program data Variable Variable The fields defined for the EGL record.

The following example shows the COBOL definition for a working storage record
passed via the message queue for an immediate program-to-program message
switch. Keep in mind that PL/I requires a 4-byte length field rather than the 2-byte
length field used for COBOL. Refer to the IMS/VS documentation for your system
for additional information. The specific field names are used for illustrative
purposes only; the actual field names might vary in the generated code.

288 EGL Programmer’s Guide


01 CSP-APPL-WS-RECORD.
05 CSP-IMS-SEG-LENGTH PIC S9(4) COMP.
05 CSP-ZZ PIC S9(4) COMP.
05 CSP-IMS-TRANNAME PIC X(8).
05 CSP-APPL-WS-DATA.
10 data-item-1 PIC ........................
10 data-item-2 PIC ........................

Format of record for show statement

When you use the show statement in an IMS nonconversational program, the
optional record is passed via the work database for a deferred program-to-program
message switch. The following table shows the record layout:
01 CSP-APPL-WS-RECORD.
05 CSP-APPL-WS-DATA.
10 data-item-1 PIC ........................
10 data-item-2 PIC ........................
Related concepts
“Transfer of control across programs” on page 251
Related tasks
“Transferring control in the IMS/VS environment” on page 275
“Transferring to and from IMSADF II programs” on page 293
Related reference
“Reference information for IMS/VS transfers” on page 286
The following sections provide reference information for call and transfer
statements in the IMS/VS environment or when DL/I databases are being used.

Format of the IMS MFS message input descriptor (MID)


The IMS MFS message input descriptor (MID) and message output descriptor
(MOD) that are used to read and write forms to terminals for a deferred
program-to-program message switch share the same basic format. The table below
shows the record layout for a MID. For an MFS MOD, the IMS transaction name
and the value of the COND parameter (form name) are reversed. In addition, some
fields in the MOD are ignored.
Table 49. Format of the MFS message input descriptor (MID)
Length in
Field bytes Type of data Description
Segment length 2 Binary The length of the segment.
Reserved 2 Binary Reserved for IMS.
IMS transaction 8 Character The IMS transaction name for the EGL
name program.
Reserved 1 Character Reserved for Rational COBOL Runtime for
zSeries.
Form name 8 Character Value for MFS COND parameter from the
MID of a deferred program-to-program
message switch.
Additional 51 Variable A group of fields that Rational COBOL
Rational Runtime for zSeries uses to validate the
COBOL form. The total length of all fields prior to
Runtime for the start of the program form fields is 72
zSeries fields bytes.
Program form Variable Variable This area contains the fields defined for the
fields EGL form.

Transfer of control across programs 289


The following example shows the COBOL definition for a form message input
descriptor (MID) for a deferred program-to-program message switch. Keep in mind
that PL/I requires a 4-byte length field rather than the 2-byte length field used for
COBOL. Refer to the IMS/VS documentation for your system for additional
information. The specific field names are used for illustrative purposes only; the
actual field names might vary in the generated code.
* CopyMember ELAAHMMI
01 EZEMAP-IO-AREA.
05 EZEMAP-HEADER.
10 EZEMAP-LL PIC S9(4) COMP.
10 EZEMAP-ZZ
15 EZEMAP-Z1 PIC X(1).
15 EZEMAP-Z2 PIC X(1).
10 EZEMAP-ZZ-BIN REDEFINES EZEMAP-ZZ
PIC S9(4) COMP.
10 EZEMAP-MID-TRANCODE. Note 1
15 EZEMAP-MOD-MAP PIC X(8).
10 FILLER PIC X(1).
10 EZEMAP-MOD-TRANCODE.
15 EZEMAP-MID-MAP PIC X(8).
10 EZEMAP-STRUCTURE-TYPE PIC X(4).
88 EZEMAP-IS-A-MAP VALUE "MAP ".
10 EZEMAP-SCA PIC X(2). Note 2
10 EZEMAP-SCA-BIN REDEFINES EZEMAP-SCA
PIC S9(4) COMP.
10 EZEMAP-EZEAID PIC X(2). Note 3
10 EZEMAP-HELP-PF-KEY PIC X(2).
10 EZEMAP-BYPASS-PF-KEYS.
15 EZEMAP-BYPASS-PF-KEY PIC X(2)
OCCURS 5 TIMES.
10 EZEMAP-HELP-MAP-NAME PIC X(8).
10 EZEMAP-CURSOR.
15 EZEMAP-ROW PIC S9(4) COMP.
15 EZEMAP-COL PIC S9(4) COMP.
10 EZEMAP-GEN-DATE-TIME.
15 EZEMAP-DATE PIC X(8).
15 EZEMAP-TIME PIC X(8).
10 EZEMAP-SSM-STATUS-ATTR PIC X(2). Note 4
88 EZEMAP-SSM-PREMODIFIED VALUE X"0081".
10 EZEMAP-SSM-STATUS PIC X(1). Note 5
88 EZEMAP-SSM-INVALID VALUE X"40" X"FF" X"00".
88 EZEMAP-SSM-WSR-SAVED VALUE "C".
88 EZEMAP-SSM-WSR-MAP-SAVED VALUE "D".
88 EZEMAP-SSM-FILL-CHAR VALUE X"FF".
* Copymember for form group formGroup
01 EZEMFS-form REDEFINES EZEMAP-IO-AREA.
05 EZEMFS-form-HEADER PIC X(72). Note 6
05 EZEMAP-DATA.
10 formField. Note 7
15 EZEATTR PIC X(08).
15 EZEDATA PIC .... Note 8
.
.
.

The following notes apply to this example:


1. For a MOD, the transaction name and the map name are reversed. If a
conversational transaction is started by using an IMS /FORMAT command,
IMS removes the transaction name from the data stream.
2. In a MID, SCA is set to blanks. In a MOD, SCA must be initialized to binary
zeros by the program that inserts the MOD.

290 EGL Programmer’s Guide


3. In a MOD, the EZEAID fields through the EZEMAP-GEN-DATETIME fields
can be left blank. Any value placed in these fields is not returned on input.
4. The transferring program must set EZEMAP-SSM-PREMODIFIED to TRUE to
ensure that the value of EZEMAP-SSM-STATUS is transmitted to the target
program.
5. If the transferring program puts data in the work database for the target
nonconversational program to use in initializing its input record, it should use
the level 88 EZEMAP-SSM-WSR-SAVED to set this field. Otherwise, this field
should be initialized using the level 88 EZEMAP-SSM-INVALID.
The target program should test the value of EZEMAP-SSM-STATUS to
determine if there is data in the work database to restore. If either
EZEMAP-SSM-WSR-SAVED or EZEMAP-SSM-WSR-MAP-SAVED is true, there
is a record in the work database to restore.
6. Form is the actual name of the form defined in EGL, the name specified by the
alias property for the form, or the alias name if one had to be assigned at
generation time.
7. formField is the actual name of a field defined in the form or the alias name if
one had to be assigned at generation time. If the formField is an array, an
OCCURS clause is used.
8. The PIC representation varies based on the type and length of the form field.
EGL generates a COBOL copybook of the MID/MOD associated with a
FormGroup. The name of the copybook part is the FormGroup name, or the alias
for the FormGroup if one was specified. The non-EGL program can use this
copybook to correctly define the message format that the EGL program needs in
the input form and the message format received when an EGL program transfers
control to a non-EGL program.
Related concepts
“Transfer of control across programs” on page 251
Related tasks
“Transferring control in the IMS/VS environment” on page 275
“Transferring to and from IMSADF II programs” on page 293
Related reference
“Reference information for IMS/VS transfers” on page 286
The following sections provide reference information for call and transfer
statements in the IMS/VS environment or when DL/I databases are being used.

Using the EGL COBOL runtime work database for IMS/VS


EGL programs can pass both a form and a record for a deferred
program-to-program message switch. When the segmented program is generated
as nonconversational (without an SPA), the work database is used to save data
when a show statement specifies both a form and a record. Rational COBOL
Runtime for zSeries provides subroutines that can be used by a non-EGL program
to store or retrieve data from the work database. Both the originating and target
programs or transactions must use the same physical work database.

The two service routines that non-EGL programs can use to interface to the work
database are:
v ELATSGET to retrieve data from the work database.
v ELATSPUT to store data into the work database.

Transfer of control across programs 291


Reading from a work database (ELATSGET) in IMS: You can use ELATSGET to
read a record from the work database after a deferred program switch from an
EGL program. The logical terminal identifier is used as the work database key.

The ELATSGET module is dynamically loaded in the following invocation


sequence at run time. This method avoids having to link this module for each
program that uses it.
MOVE "ELATSGET" TO modname.
CALL modname USING parm1, parm2, parm3, parm4, parm5, parm6.

In the previous example, modname is an 8-byte character field, and parm1 through
parm6 are as follows:
v Record buffer
v Length of buffer (fullword binary)
v Target transaction code (8 bytes padded with blanks)
v I/O PCB
v ELAWORK PCB (or fullword of binary zeros if a DB2 work database is used)
v Return code (fullword binary).
ELATSGET provides the following return codes:
Table 50. ELATSGET return codes
Code Meaning
0 Read successful
4 Read successful, truncation occurred
8 Read failed, record not found
12 Read failed, other error

Truncation occurs when the calling program attempts to restore data into a buffer
that is smaller than the data that was previously saved. If the buffer is larger than
the data that was previously saved, the trailing portion of the buffer is initialized
to blanks.

ELATSGET does not issue any error messages. The calling program must take the
appropriate action when an error occurs. If a DL/I work database is used, the PCB
contains the status code that indicates the error. If a DB2 work database is used,
the full-word binary (5th parameter) contains the SQL code that indicates the error.

Writing to a work database (ELATSPUT) in IMS: You can use ELATSPUT to


write a record to the work database before you perform a deferred program switch
to an EGL program. The logical terminal identifier is used as the work database
key.

The ELATSPUT module is dynamically loaded in the following invocation


sequence at run time. This method avoids having to link this module to each
program that uses it.
MOVE "ELATSPUT" TO modname.
CALL modname USING parm1, parm2, parm3, parm4, parm5, parm6.

In the previous example, modname is an 8-byte character field, and parm1 through
parm6 are as follows:
v Record buffer

292 EGL Programmer’s Guide


v Length of record (fullword binary)
v Target transaction code (8 bytes padded with blanks)
v I/O PCB
v ELAWORK PCB (or fullword of binary zeros if a DB2 work database is used)
v Return code (fullword binary)
ELATSPUT provides the following return codes:
Table 51. ELATSPUT return codes
Code Meaning
0 Write successful, new record added
4 Write successful, existing record replaced
12 Write failed, other error

ELATSPUT does not issue any error messages. The calling program must take the
appropriate action when an error occurs. If a DL/I work database is used, the PCB
contains the status code that indicates the error. If a DB2 work database is used,
the fullword binary (5th parameter) contains the SQL code that indicates the error.
Related concepts
“Transfer of control across programs” on page 251
Related tasks
“Transferring control in the IMS/VS environment” on page 275
“Transferring to and from IMSADF II programs”
Related reference
“Reference information for IMS/VS transfers” on page 286
The following sections provide reference information for call and transfer
statements in the IMS/VS environment or when DL/I databases are being used.

Transferring to and from IMSADF II programs


Generated EGL programs can transfer to or from IMSADF programs. Immediate
program-to-program message switches can be performed between IMSADF II
conversational programs and EGL segmented conversational programs generated
with the spaADF build descriptor option set to YES. In addition, IMSADF II
secondary transactions can be processed by EGL batch programs.

Please note the following, however:


v Because of differences in the way EGL and IMSADF II programs pass the PCB
information, EGL cannot be used to write IMSADF II special processing routines.
Because of differences in map layout conventions, deferred program-to-program
message switches between IMSADF II and EGL programs are not supported.
v Different considerations apply for transferring between EGL programs when
IMSADF II programs are involved. All EGL programs involved in a transfer
where the possibility exists of a transfer to an IMSADF II program must set the
spaADF build descriptor option to YES. For example, if EGL program A can
transfer either to EGL program B or to IMSADF II program C, both EGL
programs must set spaADF to YES, even if program B never transfers to an
IMSADF II program.

Transfer of control across programs 293


IMSADF II conversational processing
EGL cannot be used to initiate IMSADF II, but can be used to receive control from
and return control to the IMSADF II transaction driver. This is supported only
when the IMSADF II program system uses the IMSADF II 28-byte SPA with a
work database.

The code example below shows an EGL DLISegment record definition for the
IMSADF II, Version 2, Release 2, work database. The fields in this definition are
limited to those you must modify if an EGL program is transferring directly to the
IMSADF II conversational transaction driver.
//*** RECORD=ADFWKDB ****
// The sample segment layout of the ADFWORK database default
// segment size is 6000 bytes. Use this DLISegment definition
// to retrieve data from and store data into the ADF work database.
// Refer to the IMSADF Application Development Guide
// Appendix E for details on which fields to update.
// ***********************
Record ADFWKDB type DLISegment {
keyItem = "LTERMNME"
}
3 LTERMNME char(8) ;
3 SPALEGTH smallint ;
3 * char(4) ;
3 SPATRANS char(8) ;
3 * char(397) ;
3 SPABITS hex(2) ;
3 * char(6) ;
3 SPAFIRST smallint ;
3 SPARTNCD int ;
3 SPASECTX smallint ;
3 * char(4) ;
3 SPAPGOPT smallint ;
3 SPASWITH char(2) ;
4 RDFSWITH smallint ;
3 SPATRX char(3) ;
3 SPACGTRX char(3) ;
3 * char(66) ;
3 SPASHOTR char(8) ;
3 * char(31) ;
3 SPAKEYID char(255) ;
3 SPAFLDSG char(5192) ;
end // end ADFWKDB

Rational COBOL Runtime for zSeries does not share its work database with
IMSADF II; the two databases have different formats. Changes to the IMSADF II
work database do not affect the Rational COBOL Runtime work database.
Similarly, changes made by an EGL program to the Rational COBOL Runtime work
database do not affect the IMSADF II work database.

Starting from the IMSADF II side, define the EGL program to IMSADF II in the
same way that you define a transaction that is written entirely in COBOL. Refer to
the IMSADF II documentation for your system for additional information. The
EGL generated program name (and therefore, the load module name) must obey
the following IMSADF II naming convention:
ssssTcc
ssss
The IMSADF II program system ID.
T A constant.

294 EGL Programmer’s Guide


cc The cluster code (SOMTX) operand used to generate the transaction that causes
the switch to the EGL program.

From IMSADF II transaction driver to EGL program


When the program user enters the IMSADF II transaction ID that corresponds to
the EGL program, IMSADF II does an immediate program-to-program message
switch to the requested transaction. IMSADF II writes its own 28-byte SPA to the
IMS message queue to perform the switch.

The EGL program must be generated with the spaADF build descriptor option set
to YES and spaSize set to 28 to match the IMSADF II SPA size. When IMS
schedules the new transaction, the EGL program control logic reads the IMSADF II
SPA from the I/O PCB. Because of these build descriptor options, the EGL
program control logic does not modify the SPA in any way. Therefore, the EGL
program can eventually do an immediate program-to-program message switch
back to the IMSADF II conversational transaction driver. Switching directly to the
IMSADF II sign-on transaction is not supported.

If multiple EGL programs run before transferring back to the IMSADF II


conversational transaction driver, all the EGL programs must be generated with
these same build descriptor options. The program control logic uses the Rational
COBOL Runtime work database or a second message segment following the SPA
to pass records between the EGL programs, thereby preserving the IMSADF
II-formatted SPA. Both deferred and immediate program-to-program message
switches can be used between the EGL programs.

You can also specify the spaStatusBytePosition=p build descriptor option, where p
specifies an available byte in the IMSADF II SPA that can be used for EGL’s
segmentation status byte. All EGL programs involved in a series of message
switches that started from the IMSADF II transaction driver must have the same
spaSize, spaADF, and spaStatusBytePosition build descriptor options. Refer to
your IMSADF II documentation for information on the positions in the SPA that
are available.

As in a COBOL program, the EGL program can access the IMSADF II work
database to use information or to modify information in the IMSADF II
communication area. If you access the IMSADF II work database, the EGL program
processes the IMSADF II work database the way it would any other program
database. Use the record definition above to access the IMSADF II work database.
If you use a DL/I IMSADF II work database, be sure to include a database PCB in
the EGL program’s PSB definition.

From EGL program to IMSADF II transaction driver


To switch back to the IMSADF II transaction driver, your EGL program should set
flags in the IMSADF II work database that tell the transaction driver what to do
when it receives control. Refer to the IMSADF II documentation for your system
for additional information. The EGL program transfers control using a transfer to
transaction statement that specifies no record. Set sysVar.transferName to the
name of the new transaction to be started; this variable must contain the same
value that was placed in the IMSADF II variable SPATRANS. The EGL program
control logic inserts the SPA to cause an immediate program-to-program message
switch back to IMSADF II.

Transferring with conversational programs in ADF mode


The techniques described in this section are used only when there is a transfer
from IMSADF II to a series of EGL programs and non-EGL programs prior to

Transfer of control across programs 295


transferring back to IMSADF II. If only a single EGL program runs and then
transfers back to IMSADF II, the program control logic automatically preserves the
IMSADF II SPA. For transfers when IMSADF II is not involved, see “Transferring
control in the IMS/VS environment” on page 275.

The following table shows the conventions used for transferring between EGL
programs when the spaADF build descriptor option is set to YES. These
conventions differ from the techniques used when IMSADF II is not involved in
that special techniques are used to pass a record so the SPA can remain intact. ADF
mode does not support transfers between segmented nonconversational programs.
Table 52. Transfers between EGL conversational programs
Immediate switch (optional
Action input form) Deferred switch (with input form)
Coding and Define both programs as Define both programs as segmented
generating segmented = YES. Generate both = YES. Generate both programs as
programs as conversational with conversational with the spaSize
the spaSize build descriptor set to build descriptor set to 28 and the
28 and the spaADF build spaADF build descriptor option set
descriptor option set to YES. to YES.
Performing the The originating program cannot The originating program must write
transfer send a form. If it is an EGL the form to a message queue
program, it does this using a associated with the terminal after
transfer to transaction statement first writing the SPA. If it is an EGL
with a record. program, it does this using a show
statement with a form and an
optional record.
Using an input The target program can optionally The target program must have an
form have an input form. input form.
Passing a record The record is transferred in a The record, if any, is transferred
message segment following the through the work database.
SPA.
Specifying If spaStatusBytePosition was If spaStatusBytePosition was
segmentation specified, the target program specified, the target program uses
status byte always ignores the value of the the value of the segmentation status
segmentation status byte that is byte at the offset specified when
located in the SPA at the offset there is an input form integrity
specified. problem caused by the program user
pressing PA1 or PA2.
The segmentation status byte specified by spaStatusBytePosition is used only for program
to program transfers for conversational programs. The byte is present for transfers between
conversational programs and other programs. However, a transferring non-EGL program
should always set the byte to blank. A target non-EGL program can ignore the value of the
segmentation status byte.

Conversational immediate program-to-program message switch


Conversational immediate program-to-program message switches are supported as
follows:
v Between two EGL programs.
v From a non-EGL program to an EGL program.
v From an EGL program to a non-EGL program.

Immediate switch between two EGL programs: With this technique two
segmented conversational EGL programs can change both the transaction name
and the PSB name without presenting a form to the program user. The two

296 EGL Programmer’s Guide


programs can use different form groups. For a skeleton definition of the two
programs, see ″Immediate switch between two EGL programs″ in “Transferring
control in the IMS/VS environment” on page 275; remember that you must set the
spaADF build descriptor option to YES when IMSADF II programs are involved.

The EGL program control logic automatically preserves the SPA and manages the
record that is passed as a message segment following the SPA for both programs A
and B. Specify the same spaSize build descriptor option (28 bytes) for both
programs A and B.

Immediate switch from non-EGL program to EGL program: The non-EGL


program must be an IMS conversational program. The EGL program must be
defined similarly to program B in ″Immediate switch between two EGL programs″
in “Transferring control in the IMS/VS environment” on page 275; remember that
you must set the spaADF build descriptor option to YES when IMSADF II
programs are involved.

The non-EGL program must do the following:


1. Preserve the IMSADF II SPA format.
2. Insert the SPA to an alternate PCB, with the destination set to the transaction
name for the EGL program. If you specified a spaStatusBytePosition build
descriptor option, the segmentation status byte is in the SPA at the offset
specified. Initialize the segmentation status byte to blank before inserting the
SPA.
3. Insert the input record as a message segment after the SPA into the same
alternate PCB. For the required layout of the message, see “Format of EGL
input message segment for IMS message switch” on page 288.

Immediate switch from EGL program to non-EGL program: The non-EGL


program must be an IMS conversational program. The EGL program must be
defined similarly to program A in ″Immediate switch between two EGL programs″
in “Transferring control in the IMS/VS environment” on page 275; remember that
you must set the spaADF build descriptor option to YES when IMSADF II
programs are involved.

The non-EGL program must do the following:


1. Issue a get unique to the I/O PCB to read the SPA. This SPA is in the original
IMSADF II format, unchanged by the EGL program. If you specified a
spaStatusBytePosition build descriptor option, the segmentation status byte is
in the SPA at the offset specified. The non-EGL program should ignore the
value of the segmentation status byte.
2. Issue a get next to the I/O PCB to read the message that contains the record
that was passed by the EGL program. For the required layout of the message,
see “Format of EGL input message segment for IMS message switch” on page
288.
3. Preserve the IMSADF II SPA format.

Conversational deferred program-to-program message switch


Conversational deferred program-to-program message switches are supported as
follows:
v Between two EGL programs.
v From a non-EGL program to an EGL program.
v From an EGL program to a non-EGL program.

Transfer of control across programs 297


Deferred switch between two EGL programs: With this technique two
segmented conversational EGL programs can change both the transaction name
and the PSB name when a form is presented to the program user. The two
programs must use the same FormGroup. You do not have to transfer a record, but
a form is required. For a skeleton definition of the two programs, see ″Deferred
switch between two EGL programs″ in “Transferring control in the IMS/VS
environment” on page 275; remember that you must set the spaADF build
descriptor option to YES when IMSADF II programs are involved.

Deferred switch from non-EGL program to EGL program: The non-EGL program
must be an IMS conversational program. Define the EGL program similarly to
program B in ″Deferred switch between two EGL programs″ in “Transferring
control in the IMS/VS environment” on page 275; remember that you must set the
spaADF build descriptor option to YES when IMSADF II programs are involved.

The non-EGL program must do the following:


1. Preserve the IMSADF II SPA format. If you specified a spaStatusBytePosition
build descriptor option, the segmentation status byte is in the SPA at the offset
specified. Initialize the segmentation status byte to blank before inserting the
SPA.
2. Call ELATSPUT to save the record that you want to pass to the EGL program
via the work database. For details see “Using the EGL COBOL runtime work
database for IMS/VS” on page 291.
3. Insert the SPA to the I/O PCB.
4. Insert the form to the I/O PCB using the message output descriptor that
corresponds to the message input descriptor in the EGL program. The non-EGL
program must set the modified data tag (MDT) attribute for all variable data
fields on the form to be passed to the EGL program on the deferred switch. All
other attributes should be left at their default values. For the required layout of
the form, see “Format of the IMS MFS message input descriptor (MID)” on
page 289. EGL creates a COBOL copybook for the MID/MOD record layout
that the non-EGL program should use to ensure that the record formats match.

Deferred switch from EGL program to non-EGL program: The non-EGL program
must be an IMS conversational program. Define the EGL program similarly to
program A in ″Deferred switch between two EGL programs″ in “Transferring
control in the IMS/VS environment” on page 275; remember that you must set the
spaADF build descriptor option to YES when IMSADF II programs are involved.
The EGL program must set the modified property to YES for all variable data
fields on the form that the non-EGL program needs as input.

The non-EGL program must do the following:


1. Issue a get unique to the I/O PCB to read the SPA. This SPA is in the original
IMSADF II format, unchanged by the EGL program.
2. Issue a get next to the I/O PCB to retrieve the message input descriptor that
corresponds to the message output descriptor used by the EGL program. For
the required layout of the map, see “Format of the IMS MFS message input
descriptor (MID)” on page 289. EGL creates a COBOL copybook for the
MID/MOD record layout that the non-EGL program should use to ensure that
the record formats match.
3. Use the value of the MID form field EZEMAP-SSM-STATUS to determine
whether a record was passed in the work database.

298 EGL Programmer’s Guide


v If either EZEMAP-SSM-WSR-SAVED or EZEMAP-SSM-WSR-MAP-SAVED is
true, then there is a record in the work database. Retrieve it as described in
step 4 below.
v If EZEMAP-SSM-FILL-CHAR is true and this is not an initial SPA, then an
input form integrity problem has occurred, probably because the program
user has pressed PA1 or PA2. Take whatever action is appropriate for the
program to recover the data that was lost from the input form. This might
involve issuing an error message to the program user and restarting the
transaction or other recovery actions depending on the program design. In
this situation, if you specified a spaStatusBytePosition build descriptor
option, the program can use the segmentation status byte to determine if a
record was saved in the work database prior to the transfer. If the
segmentation status byte has the value C, c, D, or d, then a record was saved
in the work database and you can retrieve it as described in step 4 below.
4. Call ELATSGET to retrieve the record saved by the EGL program in the work
database. For details see “Using the EGL COBOL runtime work database for
IMS/VS” on page 291.
5. Preserve the IMSADF II SPA format.
Related concepts
“Transfer of control across programs” on page 251
Related reference
“Format of EGL input message segment for IMS message switch” on page 288
“Format of the IMS MFS message input descriptor (MID)” on page 289
Related tasks
“Transferring control in the IMS/VS environment” on page 275
“Using the EGL COBOL runtime work database for IMS/VS” on page 291

Transferring control in the iSeries COBOL environment


In the iSeries environment, the following types of transfer of control are possible to
and from EGL programs:
v Using the call statement.
v Using the transfer to program statement.
v Using the transfer to transaction statement.
The iSeries environment does not support the show statement to transfer to a
non-EGL program.

If you are calling a non-EGL program from an EGL program, the call uses the
standard iSeries CALL interface. Parameters are passed using a standard system
argument list.

When you use the transfer to program or transfer to transaction statement, control
is passed directly to the target program using the iSeries XCTL interface. If a
record is specified, it is passed as a parameter using a standard system argument
list. The transferring program is removed from the program invocation stack and
does not resume control when the target program ends.
Related concepts
“Transfer of control across programs” on page 251

Transfer of control across programs 299


Transferring control in the iSeries RPG environment
In the iSeries environment, the following types of transfer of control are possible to
and from EGL programs:
v Using the call statement.
v Using the transfer to program statement.
v Using the transfer to transaction statement.
The iSeries environment does not support the show statement to transfer to a
non-EGL program.

If you are calling a non-EGL program from an EGL program, the call uses the
standard iSeries CALL interface. Parameters are passed using a standard system
argument list.

When you use the transfer to program or transfer to transaction statement, control
is passed directly to the target program using the iSeries XCTL interface. If a
record is specified, it is passed as a parameter using a standard system argument
list. The transferring program is removed from the program invocation stack and
does not resume control when the target program ends.
Related concepts
“Transfer of control across programs” on page 251

Calling to and from Java programs


The following types of transfer of control are possible in EGL:
v EGL-generated Java program to EGL-generated Java program
v Non-EGL Java program to EGL program
v EGL-generated Java program to non-EGL Java program
v EGL-generated Java program to DLL
v EGL-generated Java program to .EXE or .BAT file

EGL-generated Java program to EGL-generated Java program


Calling one EGL-generated program from another is as simple as invoking the Java
class for the target program using a call statement. Be aware, however, of package
dependencies. You must invoke a class that is one of the following:
v Within the same package as the calling program.
v Qualified with a package name using dot syntax.
v Identified with a linkage option part. For more information, see Linkage options
part.

Non-EGL Java program to EGL program


To invoke an EGL-generated program from a non-EGL Java program, you must do
one of the following:
v Define the EGL program as a service. For more information, see Generating EGL
and Web services.
v Create Java wrapper classes for the EGL program. For more information, see
Generating Java wrappers.

300 EGL Programmer’s Guide


EGL-generated Java program to non-EGL Java program
To invoke non-EGL Java code from Java code generated by EGL, you must create
an Interface part of type JavaObject. The Interface part contains function
descriptions for the Java methods you wish to call.

Invoke the Java method in one of two ways:


v If the function is marked static, invoke it using the name of the Interface part
and dot syntax (interfacePart.method()).
v Otherwise, create a variable based on that Interface part and use it in much the
same way you would a library, appending the interface variable name to the
name of the method using dot syntax (interface.method()).
Note that the Java class must provide a method to instantiate itself; EGL cannot
instantiate a Java class.

EGL-generated Java program to DLL


You can call functions in a single, non-EGL dynamic link library (DLL) (written in,
for example, C or COBOL) from an EGL Java program. The file extension for the
DLL depends on your environment (examples include .dll, .so, and .sl).

You create a Library part of type nativeLibrary to act as an interface between your
EGL program and the DLL. The Library part lists function names and parameters,
and can use the alias property of the functions where function names do not
match EGL conventions.

Access the functions by using dot syntax (library.function()) or by creating a use


declaration for the library to make its functions global to your program.

EGL-generated Java program to .EXE or .BAT file


EGL provides two functions that allow you to call a system command (such as a
.bat or a .exe executable file).
sysLib.callCmd()
This function transfers control to a specified executable; when the executable
terminates, control returns to the calling EGL program.
sysLib.startCmd()
This function transfers control to a specified executable, then keeps running;
both the EGL program and the executable run at the same time.
Related concepts
“Transfer of control across programs” on page 251
Linkage options part
Related tasks
Generating EGL and Web services
Generating Java wrappers

Calling an IMS program from EGL-generated Java code


You can call an IMS program remotely, from EGL-generated Java code. The called
program can be generated from EGL or VisualAge Generator or can be written in
another language.

The program accessed on IMS is not the called program itself, but is a catcher
program provided by Rational COBOL Runtime for zSeries. As shown later, the

Transfer of control across programs 301


system programmer must re-link that catcher program. The effect of that task is to
assign an alias for each runtime PSB associated with any transactions that are
invoked remotely by EGL-generated Java code.

The runtime process is as follows:


1. EGL runtime takes the name of the IMS transaction code from the linkage
options part used at generation time of the calling program.
2. EGL uses the connectors of IMS Connect to submit this transaction code, as
well as the called program name and parameters, to the IMS message queue.
3. The catcher program reads the called program name and parameters from the
message queue and uses a z/OS call to invoke the requested program. The
name of the catcher program depends on the version of EGL you use. For
version 7.0 and later of EGL, the catcher program is ELAISVN7. For earlier
versions of EGL, the catcher program is ELAISVN.
4. On regaining control, the catcher program submits the returned data to the IMS
queue.
5. IMS Connect reads the data from the queue and returns the data to the calling
program.

Here is an example:
1. On IMS, the systems programmer carries out the following tasks:
a. Creates a system definition that associates a transaction (for example,
TRAN1) with a PSB (for example, PSB1).
b. Links the catcher program (ELAISVN7 for EGL version 7 or later, or
ELAISVN for an earlier version) to assign it the alias PSB1. The linkage can
include up to 64 aliases of this kind, and you can give the module any
name you choose. If you want to add an alias after 64, create a second load
module.
2. You place a statement in your Java program to call PGMX and to supply
parameters for that program.
3. In the build descriptor used to generate the program, you set the linkage build
descriptor option to a linkage options part called pgmLinkage.
4. In that linkage options part for program PGMX, you set the callLink element,
serverID property to the appropriate transaction code (in this case, to TRAN1).
5. At run time, IMS Connect sends the transaction code (TRAN1), program name
(PGMX), and parameters to the IMS message queue.
6. Because TRAN1 has been invoked, IMS schedules PSB1, which starts the
catcher program.
7. The catcher program reads the message queue for the program name (PGMX)
and parameters, then calls PGMX.
8. When PGMX finishes, control returns to the catcher program, which places the
returned data on the IMS message queue.
9. IMS Connect returns the data to your Java code.

The transaction TRAN1 must be defined to IMS as a message processing program.


Use the following IMS system definition as a model:
APPLCTN PGMTYPE=TP,PSB=PSB1
TRANSACT CODE=TRAN1,MODE=SNGL,EDIT=ULC

Data will be folded to uppercase characters if the statement EDIT=ULC is omitted


from the transaction definition.

302 EGL Programmer’s Guide


Here is an example of the JCL the system programmer might use to re-link the
catcher program ELAISVN7, in this case to assign the aliases PSB1 and PSB2. If
you are using a version of EGL earlier than version 7, the catcher program is
named ELAISVN:
//L EXEC ELARLINK
//L.SYSLMOD DD DISP=SHR,DSN=loadLibraryName
//L.SYSIN DD *
INCLUDE SELALMD(ELAISVN7)
ENTRY ELAISVN7
ALIAS PSB1
ALIAS PSB2
NAME loadModuleName(R)
/*
loadLibraryName
Name of the load library
loadModuleName
Name of the load module; usually ELAISVN7 (or ELAISVN for versions of
EGL earlier than version 7).

IMS requires that the name of a runtime PSB be identical to the name (or, in this
case, the alias) of the first program in a transaction. If you want your called
program to be called, not only from remote code, but in another transaction on
IMS, you must do as follows:
1. Create a second PSB that is named for the first program in that transaction.
2. Structure that PSB like the PSB scheduled for the remote invocation.
Related concepts
“Transfer of control across programs” on page 251
“Developing EGL programs for the IMS environment” on page 307

Transfer of control across programs 303


304 EGL Programmer’s Guide
Developing EGL programs for the VSE environment
Rational Business Developer provides a Generation for VSE feature that you can
use to generate EGL as COBOL source for the z/VSE environment.

To use the Generation for VSE feature, you must do the following things:
v Install the feature and then enable the feature by purchasing and applying the
license for IBM Rational Business Developer Extension for VSE. The feature
provides the COBOL generation capability for the VSE environment.
v Install and customize IBM Rational COBOL Runtime for z/VSE, which provides
the runtime support for the VSE environment (similar to the runtime support for
z/OS that is provided by IBM Rational COBOL Runtime for zSeries).

The following highlights apply to developing for the VSE environment:


v You can develop traditional 3270 or batch applications. You can also develop
VGWebTransaction programs.
v Developing for VSE CICS is similar to developing for z/OS CICS; developing
for VSE Batch is similar to developing for z/OS Batch. Therefore, much (but not
all) of the information in the online help that describes these two z/OS
environments also applies to the VSE environment.
v Unlike the z/OS environment which uses a build server to prepare the output of
COBOL generation for runtime, VSE uses a preparation process that is similar to
that used by VisualAge Generator. The VSE preparation process uses the
following templates and procedures:
– Preparation JCL templates that are included with the Generation for VSE
feature
– Preparation JCL procedures that are included with IBM Rational COBOL
Runtime for z/VSE

For more information about developing and generating EGL programs in the VSE
environment, including compatibility considerations for VSE that differ from z/OS,
refer to the Rational Business Developer V7.5 Generation for z/VSE feature Reference
Manual (SC19-2539-00). You can find this manual in PDF form on the EGL Cafe
site:
http://www.ibm.com/software/rational/cafe/community/egl/documentation

For more information about installing and customizing the VSE runtime support,
refer to the Program Directory for Rational COBOL Runtime for z/VSE (GI10-8803-00).
Related reference
“Developing EGL programs for the IMS environment” on page 307

© Copyright IBM Corp. 1996, 2008 305


306 EGL Programmer’s Guide
Developing EGL programs for the IMS environment
EGL allows you to develop programs that run on IMS. Depending on program and
build-part characteristics, you can generate programs to run in any of the
following regions:
v a message processing program (MPP) region
v an IMS FastPath (IFP) region
v a batch message processing (BMP) region
Factors for each of these regions are discussed separately below.

In addition, the effect of build descriptors is also discussed in detail.

For more information on how to interact with IMS control blocks, see “EGL
support for runtime PSBs and PCBs” on page 310.

Generating for the MPP region


You can generate two types of programs for the MPP region:
v Text UI programs, which accept or display a text form.
v Basic programs, which neither accept nor display text forms.

The following considerations apply to both Text UI and basic programs:


v You can send output to another message queue; and for that purpose, you code
an add statement to write a serial record that is associated (at generation time)
with an alternate PCB or with an express alternate PCB. For output to a message
queue, the file type associated with the serial record may be SMSGQ or
MMSGQ. For details, see “Using serial and print files in IMS” on page 319.
v You can send output to a printer; and for that purpose, you code a print
statement to display a print form. You associate the printer (at generation time)
with an alternate PCB or an express alternate PCB, specify the file type as
SMSGQ, and also specify the IMS logical terminal name for the printer.
Alternatively, at run time you can use converseVar.printerAssociation to change
the IMS logical terminal name.
v You can start an asynchronous transaction using vgLib.startTransaction().
v You cannot access indexed or relative files.

The next two sections provide information particular to each of the two program
types.

Text UI programs
If you code a main program that accepts or displays a text form, EGL handles the
details of I/O PCB access. You must set the segmented program property to YES.

You can interact with the terminal by using the converse statement, which presents
a text form and responds to the user’s input by processing the statement that
follows the converse statement. For an overview of the runtime behavior, refer to
the EGL Language Reference.

© Copyright IBM Corp. 1996, 2008 307


Although use of a converse statement is relatively simple, you get better
performance by using a show statement. You can use the show statement to return
to the beginning of the same program or to another program. The show statement
must specify the same form that the receiving program specifies as its inputForm.
Use of the show statement limits the data that is saved to just the information in
the form and record that are specified on the show statement. However, you must
be sure to code your program so the form and record provide all the necessary
information to continue the interaction with the program user.

Your program can run as an IMS conversational or nonconversational program, can


transfer to or call another program, and can issue a show statement with a
returning clause. For restrictions that apply to a particular type of statement, see
the topic that describes the statement syntax.

On IMS, a called Text UI program is not supported. A main Text UI program can
transfer to or from a non-EGL IMS or IMSADF II program on the same IMS
system. For more information, see one of the following topics:
v “Transferring control in the IMS/VS environment” on page 275
v “Transferring to and from IMSADF II programs” on page 293
.

Basic programs
If you code a main program that neither accepts nor displays a text form, input is
available from the IMS message queue. To retrieve that input, you code a loop that
reads one message after another into a serial record that is associated with the I/O
PCB. For input from a message queue, the file type associated with the serial
record may be SMSGQ or MMSGQ. For details, see “Using serial and print files in
IMS” on page 319.

In most environments, when a main basic program is started, the program’s input
record is initialized from the record that was passed by the transferring program.
This is not true of a main basic program that is generated for the IMS BMP
environment. Instead the target program must read the transferred record from the
message queue.

An EGL-generated called basic program can be called from EGL-generated Java


code on another platform.

Your program can run as an IMS nonconversational program and can transfer to a
program or call another program in the same IMS/VS system. For restrictions that
apply to a particular type of statement, see the topic that describes the statement
syntax.

On IMS, an EGL-generated called program cannot read from a message queue. A


basic program cannot use the transfer to transaction statement.

Generating for the MPP IMS FastPath region


You can generate both Text UI and basic programs to run in an IMS FastPath (IFP)
region, in which case the situation is the same as described for an MPP region,
except that (in keeping with IMS requirements) the program must be
nonconversational. In addition, use of multi-segment input message queues
(including the use of converse statements) is not recommended for IMS fast path
programs for performance reasons.

308 EGL Programmer’s Guide


IMS imposes restrictions on fast path programs. These restrictions result in the
following limitations on the use of EGL functions with fast path programs:
v A transfer to transaction statement is supported only to a non-fast path
program. In this case, the transferred-to program is responsible for responding to
the terminal. A show statement is permitted.
v dliLib.AIBTDLI(), dliLib.EGLTDLI(), and vgLib.VGTDLI() must use only the
call types supported for fast path transactions.
v Multiple-segment input message queues are not supported.
v Only one of the following actions can be done for each get unique to the I/O
PCB:
– transfer to transaction or show statement
– add statement for serial file associated with an alternate response PCB
– dliLib.AIBTDLI(), dliLib.EGLTDLI(), and vgLib.VGTDLI() function calls
using the I/O PCB or an alternate response PCB
To indicate that you want a nonconversational program to run as an IMS fast path
program, set the imsFastPath build descriptor option to YES. This option causes
the generated program to limit its use of IMS functions to that permitted by IMS
fast path support. Use of fast path restricts the amount and type of diagnostic data
that is provided when an error occurs in the generated program.

When a batch program runs in the IMS BMP environment and updates IMS fast
path databases, the program must cause either a SYNC or CHKP call to commit
the updates. You can cause a CHKP call by:
v Using the sysLib.commit() service routine before the end of a batch-oriented
BMP
v Making sure that the get next statement for a serial file associated with an IMS
message queue receives an endOfFile (QC status code) before the end of a
transaction-oriented BMP.

Generating for the IMS BMP region


You can generate a basic program that runs in an IMS BMP region.

To create a transaction-oriented IMS BMP program, you must retrieve input from
the IMS message queue by coding a loop that reads one message after another into
a serial record that is associated with the I/O PCB. The use of single-segment and
multi-segment message queues is as described earlier for IMS MPP programs. To
create a batch-oriented IMS BMP program, do not read input from the IMS
message queue. For details, see “Using serial and print files in IMS” on page 319.

An IMS BMP program can also send output to another message queue or printer
as described for IMS MPP programs. An IMS BMP program can use any of the
EGL statements that a program generated for z/OS batch can use. In particular,
you can do the following in an IMS BMP or z/OS batch program:
v Receive input or send output to a GSAM file. For that purpose, you code an add
statement to write a serial record that is associated (at generation time) with a
GSAM PCB. You also specify the file type as GSAM and specify the name of the
GSAM data set. Alternatively, at run time you can use
recordName.resourceAssociation to change the name of the data set.
v Send print output to a GSAM data set; and for that purpose you code a print
statement. You associate the printer (at generation time) with a GSAM PCB,

Developing EGL programs for the IMS environment 309


specify the file type as GSAM and specify the name of the GSAM data set.
Alternatively, at run time you can use converseVar.printerAssociation to change
the name of the output GSAM data set.

Your code can transfer to or call another IMS BMP program. A called program
cannot read from a message queue.

Effect of build descriptor options


You enforce some decisions outside of your code, by setting options in the build
descriptor that is used at generation time.

To generate a program for an MPP or IFP region, set system to IMS/VS. The
following options also apply:
v To mandate the size of a SPA (as needed for a conversational program), set the
build descriptor option spaSize. To ensure that a program is nonconversational,
set that value to zero (as is the default).
v To indicate that a conversational program transfers to or from an IMSADF II
program, set the build descriptor option spaADF to YES.
v To generate a FastPath program (which runs in an IFP region), set the build
descriptor option imsFastPath to YES.
To generate a program for the IMS BMP region, set system to IMSBMP.

Additional build descriptor options apply only to the IMS/VS or IMS BMP
environments:
v imsLogID
v mfsExtendedAttr
v mfsIgnore
v mfsUseTestLibrary
v formServicePgmType
v spaStatusBytePosition
The mfsDevice must also be set before you generate your formGroup.
Related concepts
“Transfer of control across programs” on page 251
Related reference
“EGL support for runtime PSBs and PCBs”
Related tasks
“Using serial and print files in IMS” on page 319
“Transferring control in the IMS/VS environment” on page 275
“Transferring to and from IMSADF II programs” on page 293

EGL support for runtime PSBs and PCBs


This topic concerns tasks that are appropriate in the following cases:
v When the target for EGL generation is IMS BMP or IMS/VS; or
v When your code is accessing DL/I databases, as is possible when the target
system is CICS, IMS/VS, IMS BMP, or z/OS batch; or
v When your code is accessing GSAM files, as is possible when the target system
is IMS BMP or z/OS batch.

310 EGL Programmer’s Guide


You customize EGL program elements as needed to generate a COBOL program
that can access your organization’s program specification blocks (PSBs) and
program communication blocks (PCBs). Those blocks are called the runtime PSBs
and runtime PCBs.

First, define the DLISegment record parts that you will reference in database PCB
records (if any). Your next, primary tasks are as follows:
1. Define a PSB record part. That part includes the set of PCB records that will be
used when accessing IMS message queues, DL/I databases, or GSAM files.
2. In the program, make the PSB and PCB information available:
v Declare a record that is based on the PSB record part
v Set the program property @dli, property field psb to the name of the PSB
record; for more information on the syntax, see Set-value blocks.

Each PCB record is based on one of the following, predefined PCB record parts:
IO_ PCBRecord
Used to interact with an I/O PCB, which allows for input from a program or
terminal and (if the input came from a terminal) allows for output to the same
terminal. The I/O PCB also provides access to other IMS capabilities; for
example, checkpoint and restart of a batch program.
ALT_PCBRecord
Used to reference a teleprocessing PCB other than the I/O PCB. This type of
record allows your code to write output to a message queue that is associated
either with another transaction or with a device other than the terminal
associated with the I/O PCB. The runtime PCB may be either of the following
kinds:
v An alternate PCB, in which case the message is sent to its destination only if
a commit occurs; or
v An express alternate PCB, in which case the message is sent to its
destination regardless of whether a commit or rollback occurs.
DB_PCBRecord
Used to reference a database PCB, which represents a DL/I database accessible
from your program. The runtime database PCB specifies the data that can be
accessed and the type of access that is valid.
GSAM_PCBRecord
Used to reference a GSAM PCB, which is used when a z/OS batch or IMS
BMP program accesses a serial file that acts as a root-only DL/I database.

The next list provides details on the runtime PSB in each of the target systems.
CICS
The value of the PSB record property defaultPSBName is (by default) the
name of the runtime PSB. EGL places that name in the psbName field of the
system variable dliLib.psbData, but you can assign a different value to that
library field. When your program attempts an I/O operation against a DL/I
database, the value in psbName determines what runtime PSB is used.
The system variable dliLib.psbData has a second field, psbRef. The initial
value of the field is zero, which indicates that no PSB is scheduled. When the
first DL/I I/O occurs, EGL runtime issues a PSB schedule call, which acts as
follows:
v Uses the value in dliLib.psbData.psbName to schedule a runtime PSB.

Developing EGL programs for the IMS environment 311


v Sets dliLib.psbData.psbRef to an address with which that PSB can be
accessed.

Note: You must avoid writing logic that assigns any value to
dliLib.psbData.psbRef.
During a call, you can use the variable dliLib.psbData to ″pass the PSB″
(really, to pass a name and the related address).
During a transfer, details of runtime behavior depend on how the transfer
occurs:
v If the transfer is by a show statement with a returning clause or by a
transfer to transaction statement, the scheduled PSB ends because a commit
point occurs during the transfer, and a PSB is not passed to the target
program.
v If the transfer is by a transfer to program statement, the default behavior
depends on whether a PSB is scheduled:
– If a PSB is not scheduled, no commit point occurs.
– If a PSB is scheduled, that PSB ends because a commit point occurs
during the transfer, and a PSB is not passed to the target program. But in
this case an alternative outcome is possible, with the benefit that you can
minimize the difference in behavior when the transferring program is
generated for CICS as compared to when that program is generated for
IMS/VS. The alternative outcome occurs when four conditions are met:
- The target system is z/OS CICS;
- The target program is generated by EGL;
- The build descriptor option synchOnPgmTransfer is set to NO; and
- The default PSB referenced in the PSB record of the transferring
program is the same as the default PSB referenced in the PSB record of
the target program.
In this case, a commit point does not occur, and EGL passes the
scheduled PSB to the target program.

Note: The default PSB is the value of the defaultPSBName property,


which is set in the PSB record part that is the basis of a program’s
PSB record. The default value of that property is the name of the
record part. To see examples of PSB records, see DLISegment
stereotype.
DB PCBs are valid in the runtime PSB.
IMS BMP
The PSB parameter in the runtime JCL identifies the runtime PSB used
throughout the job step. Although you can customize the JCL at deployment
time, EGL generates the default PSB parameter value in the runtime JCL by
assigning the value of the PSB record property defaultPSBName.
For IMS BMP, EGL requires that the following PCBs be in the runtime PSB:
1. In the zero (first) position, the I/O PCB. Be sure that your IMS system
programmer sets CMPAT to YES when developing the PSBGEN job, even if
you are generating a batch-oriented BMP.
2. An alternate PCB, which is usually in the second position.
3. An express alternate PCB, which is usually in the third position.
DB and GSAM PCBs are also valid.

312 EGL Programmer’s Guide


IMS/VS
The rules of IMS system definition ensure that the name of the main program
is the name of the runtime PSB, which is available throughout the transaction.
For IMS/VS, EGL requires that the following PCBs be in the runtime PSB:
1. In the zero (first) position, the I/O PCB. Your IMS system programmer can
set CMPAT to YES when developing the PSBGEN job, though the action is
optional.
2. An alternate PCB, which is usually in the second position.
3. An express alternate PCB, which is usually in the third position.
DB PCBs are also valid.
If the value of build descriptor option workDBType is DLI (as is the default),
set one of your runtime DB PCBs for the EGL work database, which is
identified as ELAWORK either in the runtime PSB or as the name of the EGL
PCB record.

Note: It is recommended that you specify the last database PCB in your
runtime PSB as ELAWORK so that, if you decide to change to an SQL
work database, you can easily remove that PCB.
z/OS batch
The PSB parameter in the runtime JCL identifies the runtime PSB used
throughout the job step. Although you can customize the JCL at deployment
time, EGL generates the default PSB parameter value by assigning the value of
the PSB record property defaultPSBName.
For z/OS batch, EGL requires that the first runtime PCB be the I/O PCB. Be
sure that your IMS system programmer sets CMPAT to YES when developing
the PSBGEN job.
In addition, EGL requires two additional PCBs of any type be present in the
runtime PSB. DB and GSAM PCBs are valid, as are alternate PSBs. Your code
cannot use the alternate PSBs, however; their validity allows use of the same
runtime PSB for z/OS batch and IMS BMP.

EGL adjusts for an initial two or three I/O and teleprocessing PCBs if they are
declared in the PSB record but are not present in the runtime PSB. This adjustment
allows you to generate the same program across different environments. In relation
to CICS, for example, EGL runtime ignores the initial I/O and alternate PCB
records if they are present in your code.

Requirements for the PSB record part


The structure of your PSB record part is closely related to the structure of your
runtime PSB, and two other issues are in play:
v The target system affects which PCBs are required in the PSB record part, as
described earlier.
v The value of the program property @dli, property field callInterface (whether
AIBTDLI or CBLTDLI) also affects the requirements for your PSB record part.

When callInterface is AIBTDLI


When the callInterface field is set to AIBTDLI (as is the default), access to a given
runtime PCB is by PCB name, and the structure of the PSB record in your program
does not need to reflect the structure of a runtime PSB. However, you must make
the runtime PCBs available to EGL:

Developing EGL programs for the IMS environment 313


v For IMS/VS, IMS BMP, or z/OS batch, the first PCB in the runtime PSB must be
an I/O PCB. IMS always uses the name IOPCB as the name of the I/O PCB;
v For IMS/VS and IMS BMP, EGL uses the following names for the other required
PCBs:
– ELAALT for the alternate PCB.
– ELAEXP for the express alternate PCB.
– ELAWORK if you use a DL/I database as the EGL work database in the
IMS/VS environment, In this case, you do not need to include the database
hierarchy information in the EGL PCB record, and your IMS system
programmer should use the macro ELAPCB when defining the runtime PSB,
as shown later. (At generation time, you indicate that the work database is a
DL/I database by accepting the default value for the build descriptor option
workDBType.)
You can specify the names for those PCBs in one of the following ways:
– Ask your IMS system programmer to specify the EGL-required PCB name in
the PSBGEN job that creates the runtime PSB. The following example uses a
label to provide the name for the alternate PCB and includes the PCBNAME
parameter to provide the name for the express alternate PCB and work
database PCB:
ELAALT PCB TYPE=TP,MODIFY=YES
PCB TYPE=TP,MODIFY=YES,EXPRESS=YES,PCBNAME=ELAEXP
ELAPCB LABEL=ELAWORK
In this case, you do not need to include the PCB records in your PSB record
part.
– If your IMS programmer uses different names from those required by EGL,
you must include the required PCB records in your PSB record part and must
associate the EGL-required name with the name in your runtime PSB.
Assume, for example, that your runtime PSB includes the following PCBs:
PCB TYPE=TP,MODIFY=YES,PCBNAME=MYALTPCB
PCB TYPE=TP,MODIFY=YES,EXPRESS=YES,PCBNAME=MYEXPPCB
ELAPCB LABEL=MYWORKDB
In this case, your PSB record part includes the PCB records as follows:
Record MYPSB type PSBRecordPart
ELAALT ALT_PCBRecord {@PCB {pcbType = PCBKind.TP, PCBName = "MYALTPCB"}};
ELAEXP ALT_PCBRecord {@PCB {pcbType = PCBKind.TP, PCBName = "MYEXPPCB"}};
ELAWORK DB_PCBRecord {@PCB {pcbType = PCBKind.DB, PCBName = "MYWORKDB"}};
end

When the callInterface field is set to AIBTDLI, you need to declare only the PCB
records that are used in your program, as well as any of the required PCBs that
have a different runtime name from the EGL-required name. This rule applies to
main and called programs.

When callInterface is CBLTDLI


If you set the callInterface field to CBLTDLI, access to a given runtime PCB is by
address rather than by name.

With the exception of I/O and alternate PCB records that EGL ignores so you can
generate the same program across different environments, the structure of the PSB
record in a main program must reflect at least the initial PCBs in the runtime PSB:
v The PSB record cannot have more PCB records than the number of PCBs in the
runtime PSB but can have fewer
v The position of each PCB record must match the position of the related runtime
PCB and must be of the same type as that PCB

314 EGL Programmer’s Guide


If the target system is IMS/VS and you are using a DL/I database as the EGL
work database, you do not need to include the database hierarchy information in
the EGL PCB record, and your IMS system programmer should use the macro
ELAPCB when defining the runtime PSB. (At generation time, you indicate that the
work database is a DL/I database by accepting the default value for the build
descriptor option workDBType.)

The situation in called programs is as follows:


v If you pass a PSB record to the called program, you are passing an address used
to access the runtime PSB. You must set up at least the initial part of the PSB
record part as you did in the main program, including the PCB records for the
I/O, alternate, and alternate express PCBs (if used in a particular environment),
as well as other PCB records needed in the called program. You also must set
the program property @dli, property field psbParm.
v If you pass PCB records to the called program (as is preferred), you are passing
addresses used to access each runtime PCB. You still must set up at least the
I/O, alternate, and alternate express PCBs (if used in a particular environment);
but aside from those, you need to declare only the PCB records that are needed
in the called program. You also must set the program property @dli, property
field pcbParms.

If you specify properties pcbParms and psbParm in a called program, the


PCB-specific addresses in the former override the equivalent addresses in the
latter; the passed PSB record is ignored.

For main or called programs that are generated for IMS/VS or IMS BMP, the
default behavior is as follows:
v The second PCB record refers to the alternate PCB
v The third PCB record refers to the express alternate PCB

If you use ELAALT as the name of a record other than the second or if you use
ELAEXP as the name of a record other than the third, the name takes precedence;
EGL assumes that the named PCB record refers to the appropriate type of runtime
PCB.
Related concepts
“Developing EGL programs for the IMS environment” on page 307

Interacting with terminals in IMS


Typical IMS programs use a message-driven structure like that in the figure below:

Developing EGL programs for the IMS environment 315


Message Output
Queue

From To printer
Terminal 1 or other transaction

Input Transaction Message


Queue Program

From
Terminal 2
Queue

Message
Back to
Relational original terminal
or DL/I
Database
Message

In this example, the IMS controller starts the transaction program when the
message queue associated with the program contains a message. Another program
might have put the message on the queue, or the controller might have read input
from the terminal. The program takes the message off the queue, does any
required database I/O, and adds messages to output queues to continue
processing. The output queue can represent the input terminal, another terminal or
printer, or a queue associated with another transaction. The program then loops
back to the beginning and processes the next message on its input queue.

Typical PL/I or COBOL programs must continue the cycle until the message queue
is empty because multiple terminals run the same transaction concurrently.
However, EGL textUI programs automatically loop to read the next message in the
queue. You do not need to define message queue control functions directly. You
can define programs for IMS just as you define programs for CICS, that use a
synchronous logic structure instead of a message-driven structure. The following
figure shows an example of a synchronous program:

316 EGL Programmer’s Guide


Start Application End

Database
Terminal
or File

With the synchronous model, you only need to consider the processing that must
occur for a single user at a single terminal. This simplifies both the design and the
definition of the program.

IMS requires you to commit all database changes and to release all database locks
and positions when waiting for user input. In EGL, this means creating a
segmented program. When you define the program, remember that EGL performs
a commit with each converse I/O statement.

You must understand how segmentation works to develop programs for IMS; see
Segmentation in Text UI programs.
Related concepts
“Developing EGL programs for the IMS environment” on page 307

Defining forms for IMS programs


EGL generates your FormGroup parts into IMS Message Format Services (MFS)
maps. Each form that you define for use in the IMS environment must provide
space for the following:
v An 8-byte constant field that is used to store the IMS transaction name
v A 2-byte area that EGL uses to record the types of information stored in the
work database

You can define the 8-byte constant field with the protect and dark attributes. The
attribute byte on the form becomes the attribute byte in the EGL-generated MFS
control block. The 8-byte constant contains the name of the IMS transaction that is
started when the form is processed. Specifying the constant on the form enables
the user to specify the IMS /FORMAT command to display a formatted screen to
start a transaction. Do not use the /FORMAT command if variable fields on the
form have initial default values. If the /FORMAT command is used, the default
values do not appear.

If you do not define an 8-byte, protected, dark constant on the form, EGL searches
for any string of 9 blanks on the form and sets this area aside as a protected, dark
variable field (1 byte attribute, 8 bytes of data) in the generated MFS map. The
generated program uses this field to store the name for the next IMS transaction to

Developing EGL programs for the IMS environment 317


be run after a converse or show statement. The user cannot use the /FORMAT
command to start a transaction for these forms because IMS does not have a
default transaction name.

You do not need to explicitly define the 2-byte area on a form. EGL selects two
adjacent blank bytes on the map and treats it as a protected, dark variable field (1
byte attribute, 1 byte of data).

Estimating the size of MFS blocks for a formGroup


When EGL generates a formGroup, it generates the MFS control blocks for that
formGroup. There are three types of MFS control blocks:
Device input format (DIF) and device output format (DOF)
These control blocks describe the arrangement of data fields and literals in the
device presentation space (for example, the screen for 3270 devices).
For 3270-type devices, a single set of statements describes both the DIF and the
DOF. For printers, only a DOF is needed. Each device field is given a name
that statements can refer to in the message input and output descriptors.
For EGL FormGroup parts, the DOF is always larger than the DIF because the
DOF includes form constants.
Message output descriptor (MOD)
This control block describes the various fields of information in the output
message inserted by the program. It also identifies corresponding device fields
where the data for each message field is moved.
Message input descriptor (MID)
This control block describes the various fields of information in the input
message retrieved by the program. The MID identifies the corresponding
device field from which the data for each message field came.

MFS control blocks cannot exceed 32748 bytes. If you are using a large FormGroup
part, the following formulas offer a guideline for estimating an upper limit for the
size of the control blocks that will be generated. Using these formulas during your
design helps you determine whether your FormGroup parts should be split into
smaller ones. If a generated control block is too large, MFS generation issues a 3022
abnormal termination.

Calculating the DOF size for display devices


The following formula helps you estimate the size of the DOF:
DOF Size =
150
+ (388 * Number of printer forms in the formGroup)
+ (208 * Number of display forms in the formGroup)
+ (63 * Number of variable field occurrences on display
forms in the formGroup)
+ (62 * Number of constant fields on display forms in the
formGroup)
+(1.12 * Total length of all constant fields on display forms
in the formGroup)

Calculating the DOF size for printer devices


The following formula helps you estimate the size of the DOF:
DOF Size =
206
+ (68 * Number of printer forms in the formGroup)
+ (374 * Number of display forms in the formGroup)
+ (63 * Number of variable field occurrences on printer

318 EGL Programmer’s Guide


forms in the formGroup)
+ (62 * Number of constant fields on printer forms in the
formGroup)
+(1.12 * Total length of all constant fields on printer forms
in the formGroup)

Calculating the MOD size for all forms


The following formula helps you estimate the size of the MOD:
MOD Size =
36
+ (724 * Number of display forms in the formGroup)
+ (202 * Number of printer forms in the formGroup)
+ (52 * Number of variable field occurrences in the formGroup)

Calculating the MID size for terminal maps


The following formula helps you estimate the size of the MID for terminal maps:
MID Size =
36
+ (858 * Number of display forms in the formGroup)
+ (52 * Number of variable field occurrences for display
forms in the formGroup)
Related concepts
“Developing EGL programs for the IMS environment” on page 307

Using serial and print files in IMS


Serial files must be implemented as IMS message queues in IMS/VS. They can be
implemented as message queues, OS/VS files, VSAM files, or GSAM files for IMS
BMP. Serial files can be implemented as OS/VS files, VSAM files, or GSAM files
for z/OS batch. The following discussion deals with using serial files for GSAM
files or message queues.

Using serial files as GSAM files


EGL programs that run in the IMS BMP or z/OS batch environments can
implement serial files as GSAM files. You can use the add, get next, and close I/O
statements for serial files that you implement as GSAM files. Here is a list of
differences between GSAM and normal serial file processing:
v A GSAM file requires a DBD.
v A GSAM file requires a PCB in the IMS PSB. You must define this PCB in the
IMS runtime PSB and in the EGL PSB definition. In your program, you must
declare a record variable that is based on the PSB record part.
v A GSAM file is read or written through DL/I calls. The generated COBOL
program handles this automatically, based on the I/O statements that you
request.
v A GSAM file is checkpointed and restarted in the same way as a DL/I database.
However, to recover the GSAM file requires the use of symbolic checkpoint and
restart instead of basic checkpoint.
EGL does not support the record search argument for GSAM or undefined length
records.

You identify a serial file or print file as a GSAM file by using the resource
association part during generation to specify a file type of GSAM and a PCB name.

When you associate a serial file with a GSAM file, you must include the following
information:

Developing EGL programs for the IMS environment 319


Resource name
Indicates the 1- to 44-character data set name that is used in the sample
runtime JCL. The file name from the record definition is used as the DD name
in the sample runtime JCL.
File type
Specifies GSAM as the file type to associate the serial file or printer output
with a GSAM file.
PCB name
Specifies a PCB name for the serial file that is associated with the GSAM file. If
you do not specify one, the default is the first GSAM PCB in the EGL PSB.

Using serial files as message queues


Online programs that run in IMS/VS implement serial files as IMS message
queues. Programs that run as IMS BMP programs can also implement serial files as
message queues. You can use the add and get next I/O statements as well as close
for output files. If you select IMS/VS or IMS BMP as the target runtime
environment, you can define serial or print files as being associated with a
message queue. You must associate all serial files and print files with message
queues for IMS/VS. Only a single input file can be associated with the message
queue.

You can associate a serial file or print file with a message queue by using a
resource association part during generation and specifying the file type and a PCB
name. When you associate a serial file with a message queue, you must define the
following resource information:
Resource name
You must indicate the 1- to 8-character destination ID for printer or serial file
data. The name must match the ID of an IMS logical terminal or a transaction
code that is defined in the IMS system definition.
The file name is the default resource name for the message queue. You can
override this default in the resource association part.
If the PCB that you select is a modifiable alternate or express alternate PCB,
you can override the default message queue name at run time by setting a
value for record.resourceAssociation for a file or
converseVar.printerAssociation for a printer in the program.
record.resourceAssociation is treated as a local variable. Setting
record.resourceAssociation for a record in one program does not affect
record.resourceAssociation in another program. An add statement writes to the
message queue identified by the setting of record.resourceAssociation for that
program.
Message queue type
You can specify single-segment message queues or multiple-segment message
queues.
Single-segment message queues (SMSGQs)
For a single-segment message queue, each record that you add or that you
read (with a get next) from the serial file is a complete message. The
generated COBOL program issues an IMS PURG call between records that
are added to a single-segment message queue. The generated COBOL
program issues an IMS get unique for each get next statement.
Multiple-segment message queues (MMSGQs)

320 EGL Programmer’s Guide


For multiple-segment message queues, a series of adds to the serial file is
treated as though each add statement were for a segment of a single
message. The message is not ended until you issue a close statement or
reach a commit point. The generated COBOL program issues an IMS
PURG call for the close statement. You can then begin adding segments of
another message and close it. Multiple-segment message queues are not
valid for print files.
If you issue a get next statement for a MMSGQ serial file, the generated
program issues an IMS get unique call to get the first segment of the
message. Additional get next statements result in GN calls to get the
remaining segments of the message. At the end of all the segments in a
message, the generated COBOL program sets the noRecordFound record
state. If you continue scanning, the generated program starts another series
of get unique (GU) calls, followed by get next (GN) calls. When no more
messages are found, the generated program returns an endOfFile state.
PCB name
You must also specify a PCB name for the serial file that is associated with a
message queue. You must specify the name assigned to the I/O PCB as the
PCB name for a serial input file. The I/O PCB is the only message queue used
for input. If you use a serial input file, you must use a main batch or called
batch program. The generated program handles all I/O PCB logic for main
textUI programs.
You can specify the PCB name for a serial output file. The PCB name must be
the name assigned to an alternate PCB record. The default PCB name is the
name of the first alternate PCB in the PSB. You can only send output to the
I/O PCB by using one of the following system functions:
v vgLib.VGTDLI()
v dliLib.AIBTDLI()
v dliLib.EGLTDLI()

Defining records to use with message queues


When you define a serial record to associate with a message queue, you should
define only the program data. The generated COBOL program adds the IMS
message header (length, ZZ, and transaction code) for an add statement and
removes it for a get next statement.

Checking the results of serial file I/O statements


When a serial file is associated with a message queue or GSAM database, the
generated program issues a DL/I call to implement the I/O operation. When the
DL/I call completes, Rational COBOL Runtime for zSeries performs the following
functions:
v For get next statements, the record state is set based on the DL/I status code.
The sysVar.sessionID and sysVar.userID fields are updated from the user ID
field of the I/O PCB when the generated program issues a GU call for the I/O
PCB. This happens at the first get next statement for a serial file defined as a
multiple-segment message queue (MMSGQ), and at each get next statement for
a single-segment message queue (SMSGQ). The EGL sysVar.transactionID field
is updated from the transaction name in the IMS message header after each get
next statement that results in a GU call for the I/O PCB.
v For an add or close statement, the record state is updated based on the DL/I
status code.

Developing EGL programs for the IMS environment 321


After a DL/I call that involves either the message queue or GSAM, the dliVar
fields are not updated. These fields are updated only for functions that access DL/I
segment records. This allows a program written for a CICS transient data queue or
an OS/VS serial file to run consistently when the file is changed to a message
queue or GSAM database in an IMS environment. You should check the I/O error
values to determine if endOfFile, noRecordFound, or other error occurred on the
serial file. If you need more detailed information from the PCB, use the field
names in the IO_PCBRecord or the ALT_PCBRecord. Consider a situation in which
your PSB variable (named myPSB) declares an ALT_PCBRecord named myAltPCB,
and you used myAltPCB as the PCB name in your resource association. To
reference the DL/I status code after an add statement, use
myPSB.myAltPCB.statusCode.

EGL I/O error code IMS Messsage Queue status code Severity
endOfFile QC Soft
noRecordFound QD Soft
ioError any non-blank status code Hard or soft
hardIOError non-blank other than QC, QD, CE, CF, CG, Hard
CI, CJ, CK, CL
EGL I/O error code GSAM status code Severity
endOfFile GB Soft
ioError any non-blank status code Hard or soft
hardIOError non-blank other than GB Hard

Using print files as message queues


For IMS/VS you must associate print files with message queues. For IMS BMP,
you can associate print files with message queues. You associate print files with
message queues the same way you associate serial files with message queues, with
the exception that SMSGQ is the only valid file type for a resource association
whose file name is ″printer″. In your IMS system definition, you must define the
message queue name that you use in the runtime environment as a logical
terminal. You can use converseVar.printerAssociation to change the printer
destination at run time. For example, you could define a table of user IDs and the
printer ID that each user normally uses. By setting converseVar.printerAssociation,
you can route the printer output to a printer near the program user.
Related concepts
“Developing EGL programs for the IMS environment” on page 307

Example IMS program code


These excerpts from EGL programs show interaction with IMS terminals, message
queues, and serial files.

Example of output to a serial file associated with a message


queue
Here are some code excerpts from an EGL program that accesses message queues.
The program carries out the following tasks:
1. Requests input from a terminal using a form.
2. Reads the response.
3. Updates a serial record with information based on the user input.

322 EGL Programmer’s Guide


4. Outputs the serial record to another transaction for later batch processing.
The program assumes the following associations in your IMS environment:
v IMS transaction code MYTRXCD1 is associated with a PSB named MYTRXCD1.
v IMS transaction code NEXTTRX is associated with a PSB named MYTRXCD2.
//define PSB
Record addToQueue type PSBRecord { defaultPSBName="MYTRXCD1" }
// three PCBs required for CBLTDLI on IMS
iopcb IO_PCBRecord { @PCB { pcbType = TP } };
elaalt ALT_PCBRecord { @PCB { pcbType = TP } };
elaexp ALT_PCBRecord { @PCB { pcbType = TP } };
// other database PCBs
...
end

Record myTransactionPart type serialRecord


{ fileName="MYMSGQUE" }
...
end

program addtrans type textUIProgram


{ alias = "MYTRXCD1", // IMS requires pgm to match PSB name
segmented = yes,
@DLI { psb = "mypsb" }}

use MYFORMS; // MYFORMS is a formGroup containing FORM1

// declare variables
myTransaction myTransactionPart; // serial record for message queue
mypsb addToQueue; // psb

function main()
...
converse FORM1;
// do whatever processing is necessary
move FORM1 to myTransaction byName;
add myTransaction;
...
end
end

When you generate, you must specify a resource association part that associates
the serial file with a message queue and that provides the name of the transaction
to which it is to be sent, along with the name of the PCB to use. Consider the
following example, which also includes an association element that makes possible
the input of the message-queue data by a batch program, as described later:
<ResourceAssociations name="IMS_RESOURCE_ASSOCIATION">
<association fileName="MYMSGQUE">
<imsvs>
<smsgq systemName="NEXTTRX" pcbName="elaalt"/>
</imsvs>
</association>
<association fileName="MYINQUE">
<imsvs>
<smsgq systemName="NEXTTRX" pcbName="iopcb"/>
</imsvs>
</association>
</ResourceAssociations>

Because addtrans is a textUI program, EGL generates control logic to interface to


the IMS environment. IMS programs are expected to read the input message queue
until the queue is empty. Therefore, EGL generates logic into the program so that

Developing EGL programs for the IMS environment 323


once the program responds to the current user (using a converse or show
statement) or transfers the responsibility for responding (using a transfer to
transaction statement), the program loops to read the next input message from the
queue. For an overview, see “Interacting with terminals in IMS” on page 315; for
more information, see ″Multiple users and message queues″ in this topic.

Example of IMS batch processing


You can also create a program to process the messages that program addtrans
writes to the message queue. The program must be a basic program that gets
records from a serial file and associates the serial file with the I/O PCB.

The program can use the same serial record that addtrans used, but with a new file
name because a different PCB name is required. Key changes show in bold in the
example below:
//define PSB
Record getFromQueue type PSBRecord { defaultPSBName="MYTRXCD2" }
// three PCBs required for CBLTDLI on IMS
iopcb IO_PCBRecord { @PCB { pcbType = TP } }
elaalt ALT_PCBRecord { @PCB { pcbType = TP } };
elaexp ALT_PCBRecord { @PCB { pcbType = TP } };
// other database PCBs
end

program gettrans type basicProgram


{ alias = "MYTRXCD2"
@DLI { psb = "mypsb" }}

// declare variables
myTransaction myTransactionPart // serial record for message queue
{fileName="MYINQUE"};
mypsb getFromQueue; // psb

function main()
while (myTransaction not endOfFile)
get next myTransaction;
// do whatever processing is necessary
end
end
end

When you generate the program for either the IMS/VS or the IMS BMP
environments, you must also specify a resource association part that associates the
serial file with a message queue, as well as the name of the PCB to use. In this
case, the I/O PCB is used for input, as shown in the ResourceAssociations part in
the previous section. The systemName property is optional. The program reads the
message queue associated with the transaction that started the program, based on
the IMS system definition. EGL sets sysVar.transactionID based on the IMS
transaction id in the input message.

Mutliple users and message queues


When you write an EGL program, you only need to consider the processing that
must occur for a single user at a single terminal. EGL generates control logic into
the program to handle the complex situation on IMS when you have multiple
users in contention for the resources. Assume USER1 and USER2 both enter
MYTRXCD1 on their terminals at the same time. Assume that USER1’s transaction
code ends up first on the message queue associated with MYTRXCD1.
1. IMS schedules the PSB associated with the transaction code MYTRXCD1. That
PSB happens to be named MYTRXCD1 as well, though it does not have to be.

324 EGL Programmer’s Guide


The program associated with the PSB, however, must have the same name as
the PSB in IMS. Therefore IMS loads the program MYTRXCD1 (known as
addtrans to EGL).
2. The EGL-generated control logic in program MYTRXCD1 determines that this
is the first time the program has been invoked for USER1, so processing begins
at the top.
3. Eventually the program reaches the converse statement and performs the
following actions:
v Saves the data for all records and forms the program is using
v Saves information about where in the program the converse statement
occurred
v Performs the ISRT command with the specified form
4. Following the logic that EGL added, the program loops back to the beginning
and finds USER2 waiting on the message queue. The program follows the same
steps for USER2 that it did for USER1, reaching the converse statement,
sending the form, then looping back to check the message queue again.
5. Here the program is likely to find USER1’s response to the converse statement.
The EGL-generated control logic determines that this response is a continuation
of USER1’s processing, and does the following:
v Restores USER1’s data (including the location of the converse statement)
v Refreshes a number of system variables
v Runs any validation checks that FORM1 requested
v Assuming no input errors, resumes processing at the statement after the
converse statement
6. Eventually, the program reaches another converse statement, saves all data, and
sends a response to USER1. The program then loops back to check the message
queue again.
7. Assume that USER2 has gone to lunch and there is nothing left on the message
queue associated with the transaction code MYTRXCD1. Program MYTRXCD1
ends.
8. Later, if USER1 responds to the most recent console message, IMS will once
again have a message on the queue associated with transaction code
MYTRXCD1 and will start the program MYTRXCD1 again. The EGL-generated
control logic determines that this response is a continuation of USER1’s
processing, restores all data, and continues processing.
Related concepts
“Developing EGL programs for the IMS environment” on page 307
Related tasks
“Interacting with terminals in IMS” on page 315

Developing EGL programs for the IMS environment 325


326 EGL Programmer’s Guide
Overview of EGL Rich UI
EGL Rich UI is a new technology for writing applications that will be deployed on
Web servers. The technology builds on an idea central to EGL: write simple code,
which is converted automatically to output that is useful for running a business.
The output in this case is client-side JavaScript, called client-side because the
JavaScript runs in the browser, not on the remote machine that serves the Web
page. Client-side JavaScript is important because it makes the Web page more
responsive, providing greater flexibility so that the user’s experience can go
beyond receiving and submitting a page. After the user clicks a radio button, for
example, the logic might respond by changing the content of a text box. The
change occurs quickly because the JavaScript runs locally and, in most cases,
redraws only one area of the page.

An extension of client-side JavaScript is Ajax, a technology that permits the


runtime invocation of remote code and the subsequent update of a portion of a
Web page, even as the user continues working elsewhere on the page. After the
user selects a purchase order from a list box, for example, the JavaScript logic
might request transmission of order-item details from the remote Web server and
then place those details in a table displayed to the user. In this way, the application
can access content from the server but can save time by selecting, at run time,
which content is transmitted.

A developer writes Rich UI applications using EGL syntax. For advanced purposes,
however, a developer can write custom JavaScript or use JavaScript libraries
instead of relying on the default behavior provided by EGL. For example, you can
use Rich UI to access the following software:
v The Dojo Toolkit (http://dojotoolkit.org/)
v Microsoft Silverlight (http://silverlight.net/)

A Rich UI application can act as the front end for services that access databases
and do other complex processing. You can access the following kinds of services,
which are described in Overview of service access:
v SOAP Web services
v REST Web services that are provided by third parties such as Yahoo and Google
v EGL REST services, which are REST Web services for which the access code is
particularly simple

Outline of development tasks

As a Rich UI developer, you do the following tasks in the EGL Rich UI


perspective:
1. Create a Rich UI project
2. Create a kind of EGL handler part called an EGL Rich UI handler
3. Open the handler in the EGL Rich UI editor and add content to the Rich UI
handler in the following ways:
v By dragging on-screen controls called widgets onto a Web page surface. In
this situation, you can set widget properties by typing values into dialogs
that are part of the Rich UI editor.
v By coding widget details directly into the Rich UI handler.

© Copyright IBM Corp. 1996, 2008 327


v By writing the following kinds of logic directly into the Rich UI handler:
– Startup logic, which runs when the browser first receives the application
from a Web server
– Event logic, which runs in response to user actions such as a button click

When you are ready to deploy your code, you use the EGL deployment wizard
and store output in one of the following locations:
v A Web project that is configured for WebSphere Application Server
v A Web project that is configured for Apache Tomcat
v A directory whose content is ultimately provided to a simple HTTP server such
as the Apache HTTP server. However, Rich UI does not support service access in
this case.

The EGL Rich UI Editor

You can use the EGL Rich UI editor to modify a Rich UI handler and to preview
the handler’s runtime behavior. The editor includes the following views:
v The Design view is a graphical design area that shows the displayable content of
the Rich UI handler. You can drag-and-drop widgets from a palette into the
display and then customize those widgets in the Properties view.
v The Source view provides the EGL editor, where you update logic and add or
update widgets. The Design view and Source view are integrated: changes to the
Design view are reflected in the Source view; and, if possible, changes to the
Source view are reflected in the Design view.
v The Preview view is a browser, internal to the Workbench, where you can run
your logic. You can easily switch to an external browser if you prefer.

The EGL Rich UI Perspective

Here is the EGL Rich UI perspective as it appears when a Rich UI handler is open
in the Rich UI editor:

328 EGL Programmer’s Guide


Related concepts
“Understanding how browsers handle a Rich UI application” on page 334
“Introduction to the EGL Rich UI editor” on page 337
You can use the EGL Rich UI editor to modify a Rich UI handler and to
preview the handler’s runtime behavior.
Overview of service access
Overview of EGL Rich UI generation and deployment
“Securing a Rich UI application” on page 352
Related tasks
“Starting to work with EGL Rich UI”
This topic tells how to start developing applications with EGL Rich UI.
Related reference
Rich UI handler part
Rich UI widgets
Reference to widgets
Extending the Rich UI widget set

Starting to work with EGL Rich UI


This topic tells how to start developing applications with EGL Rich UI.

Enabling the Rich UI capability

If you are working in an existing workspace, enable the Rich UI capability:


v Click Window > Preferences. The Preferences dialog box is displayed.
v Expand General and click Capabilities. The Capabilities page is displayed.

Overview of EGL Rich UI 329


v Click Advanced. The Advanced Capabilities dialog is displayed.
v Click EGL Rich UI and click OK.
v Click Apply to save your changes and remain on the Preferences dialog box.
Alternatively, click OK to save the changes and exit the page; or click Cancel to
cancel the changes and exit the dialog box.

Switching to the EGL Rich UI perspective

When you first open the Workbench, switch to the EGL Rich UI perspective:
v Click Window -> Open Perspective -> Other
v At the Open Perspective dialog, double-click EGL Rich UI

Setting the Rich UI editor as the default for EGL files

If most of your EGL work will involve Rich UI, you will want to make the Rich UI
editor the default for EGL files:
1. Click Window > Preferences. The Preferences dialog box is displayed.
2. Expand General and Editors and click File Associations. The File Associations
dialog is displayed.
3. In the File types section, click .egl
4. In the Associated editors section, click EGL Rich UI Editor and, at the right,
click Default
5. Click OK

Accessing the Rich UI samples

We recommend that you use the Rich UI samples to explore the technology:
1. Click Help -> Samples. The Help dialog box is displayed.
2. Expand Samples, Technology samples.
3. Click Rich UI technical sample.
4. If your workbench does not already have the project com.ibm.egl.rui_1.0.0, click
the entry to it.
5. Click the entry to import the samples.
6. In the workbench Project Explorer, expand the project com.ibm.egl.rui.samples,
file EGL Source, package contents.
7. If you previously set the Rich UI editor to be the default for EGL files,
double-click contents.egl. Otherwise, right-click contents.egl and select Open
with → EGL Rich UI Editor.
8. Select the Preview tab at the bottom of the editor.
9. Follow the on-screen directions and try out the alternatives presented there.

Creating your first Rich UI project

When you want to work outside of the Rich UI samples project, do as follows:
1. Click File -> New -> Project. The New Project wizard is displayed.
2. Expand EGL, click EGL Project and then Next. The New EGL Project page is
displayed.
3. Type a project name and select Rich UI Project. In most cases, complete the
task by clicking Finish, However, if you want to consider additional options,
continue here:

330 EGL Programmer’s Guide


a. Click Next so that the EGL Project page is displayed.
b. To include the project in the directory that stores the current workspace,
select the check box for Use the default location for the project; otherwise,
specify a different directory by clearing the check box and using the Browse
mechanism.
c. An EGL service deployment descriptor lets your application access remote
services in a flexible way, so that at configuration time, an installer can
change the details of service access. The overhead of including the
descriptor is small, and we recommend that you select the check box for
Create an EGL service deployment descriptor regardless of your intent.
Click Next. The EGL Settings page is displayed.
d. The Projects tab lists all other projects in your workspace. Click the check
box beside each project that you want to add to the project’s EGL build
path.
e. To put the projects in a different order or to export any of them, click the
Order and Export tab and do as follows: (i) To change the position of a
project in the build-path order, select the project and click the Up and
Down buttons; (ii) to export a project, select the related check box; and (iii)
to handle all the projects at once, click the Select All or Deselect All
button.
f. Click Finish.

Reviewing general information on EGL

EGL Cafe provides is a center of information about the products that include EGL:

http://www.ibm.com/software/rational/eglcafe

For a concise introduction to EGL, see IBM Rational Business Developer with EGL:

http://www.mc-store.com/5087.html

The content of that book will be included in a new work that focuses on Rich UI.
Enterprise Web 2.0 with EGL is expected from MC Press in May 2009.

See the following topics in the EGL Programmer’s Guide (aside from topics
specifically on Rich UI):
v Using EGL with the Eclipse IDE
v Introduction to EGL projects through Properties:
– In relation to Data parts, ignore references to Form Group and
ArrayDictionary
– In relation to Logic parts, ignore references to Handlers (other than Rich UI
handlers) and Programs
– Ignore Build parts other than the build descriptor and the deployment
descriptor
v Content assist
v Searching for EGL files and parts
v Setting Preferences in the EGL editor; specifically, the following topics:
– Setting Preferences for folding in the EGL editor
– Setting Preferences for organizing import statements in the EGL editor
– Setting Preferences for source styles
– Enabling and disabling code templates

Overview of EGL Rich UI 331


v EGL debugger commands
v Setting preferences for the EGL debugger

Exclude the following subjects when reviewing the EGL Language Reference:
v File and database access; related statements such as forEach and get, and related
Exception records. When you work with Rich UI, all such access is handled by
invoked services.
v The Program-related statements transfer and call.
v User interfaces.
v Record stereotypes other than BasicRecord and ExceptionRecord.
v Details that are specific to Java or COBOL processing; in particular, details
related to J2EE, CICS, IMS, and z/OS batch.
v Compatibility with VisualAge Generator or Informix 4GL.
v System libraries ConsoleLib, ConverseLib, DliLib, J2eeLib, JavaLib, LobLib,
PortalLib SqlLib, VgLib, and VgVar.

See the following topics in the EGL Generation Guide (aside from topics specifically
on Rich UI):
v Introduction to EGL generation
v Build descriptor part

Reviewing compatibility issues

Here are the major compatibility issues:


v File, database, and printer access is supported only by service access, not
directly by the Rich UI application code. However, Rich UI supports
non-structured Record parts, stereotype SQLRecord (as well as stereotypes
BasicRecord and ExceptionRecord). Not supported are the Record part properties
containerContextDependent, i4glItemsNullable, and textLiteralDefaultIsString.
v Reporting is not directly supported.
v Function overloading is not supported
v Generation of the following outputs is not supported: programs, forms, form
groups, data tables, services, or other outputs that are specific to Java or
COBOL.
v A version of the call statement is supported, but only to invoke services.
v Only the following variations of the exit statement are supported: exit for, exit
if, exit while, and exit case.
v The following statements are not supported: add, close, converse, continue,
delete, display, execute, forEach, forward, get, freeSQL, goTo, move, open,
openUI, prepare, print. replace, set, and transfer.
v The following types are supported: ANY, BIGINT, BIN (but only in the absence
of decimal places), Boolean, DataItem, DATE, DECIMAL, Delegate, Dictionary,
FLOAT, INT, NUM, NUMBER, SMALLFLOAT, SMALLINT, STRING (but only in
the absence of a size limit) , TIME, TIMESTAMP, NUM, MONEY, Service parts,
Interface parts, External types (stereotype JavaScript), arrays of supported types,
and non-structured Basic, Exception, and SQL Record parts.
v The following types are not supported: ArrayDictionary, BIN (with decimal
places), BLOB, CHAR, CLOB, DataTable, DBCHAR, HEX, INTERVAL,
MBCHAR, NUMC, STRING (with a size limit), PACF, UNICODE, structured
Record parts, and parts specific to the technologies Console UI, JSF, reports, Text
UI, and Web transactions.

332 EGL Programmer’s Guide


v The following system libraries are not supported: ConsoleLib, ConverseLib,
DliLib, DliVar, J2eeLib, JavaLib, LobLib, PortalLib ReportLib, SqlLib, VgLib, and
VgVar.
v The following dateTimeLib functions are not supported: intervalValue() and
intervalValueWithPattern().
v The mathLib function assign() is not supported. Also, the data-type restrictions
noted earlier limit the support for the following mathLib functions: abs, max,
min, precision, and round.
v The StrLib constant nullFill is not supported.
v The following strLib functions are not supported: byteLen(), charAsInt(),
defaultMoneyForm(), defaultNumericFormat(), formatNumber(),
getNextToken(), getTokenCount(), intAsChar(), intAsUnicode(),
setBlankTerminator(), setNullTerminator(), unicodeAsInt(). Also, the data-type
restrictions noted earlier limit the support for the following mathLib functions:
getNextToken() and indexOf().
v The only supported sysLib functions are conditionAsInt(), writeStdError(), and
writeStdOut().
v The only supported sysVar variable is sysVar.systemType.
v Literals of type CHAR, DBCHAR, and MBCHAR are not supported.
v The three bitwise operators (& | Xor) are not supported; nor is the in operator.
v Only the following variations of the is and not operators are supported: use of
sysVar.systemType and record-specific tests of blanks and numeric.
v Rich UI code cannot compare a variable of type ANY to a value variable:
// Not supported
if (myAny == 1)
;
end
v The details on using the EGL debugger are slightly different, as described in
Rich UI debugging.
v Elsewhere in EGL, a variable may be used (for example, as a property value)
before or after the variable is declared. In Rich UI, a variable must be declared
before it is used, with the following exception: widgets can be referenced in the
initialUI or children property before the widgets are declared.
To understand the initialUI and children properties, see Understanding how
browsers handle a Rich UI application and then Rich UI Handler part.
Related concepts
“Overview of EGL Rich UI” on page 327
“Understanding how browsers handle a Rich UI application” on page 334
“Introduction to the EGL Rich UI editor” on page 337
You can use the EGL Rich UI editor to modify a Rich UI handler and to
preview the handler’s runtime behavior.
Overview of service access
Overview of EGL Rich UI generation and deployment
“Securing a Rich UI application” on page 352
Related tasks
Rich UI debugging
Related reference
Rich UI handler part
Rich UI widgets
Reference to widgets

Overview of EGL Rich UI 333


Understanding how browsers handle a Rich UI application
This topic gives details on how browsers handle a Rich UI application at run time.
The purpose is twofold:
v To help you learn the technology faster, as is possible if you understand the
runtime effect of what you code at development time
v To make it easy for you to do advanced tasks

When a user enters a Web address into a browser, the browser transmits a request
to a Web server, which is usually on a second machine. The address identifies a
specific server and indicates what content is to be returned to the browser. For
example, if you enter the address http://www.ibm.com, an IBM server replies with a
message that the browser uses to display the IBM home page. The question that is
of interest now is, how does the browser use the message?

The browser brings portions of the message into an internal set of data areas. The
browser then uses the values in those data areas to display on-screen controls,
which are commonly called widgets. Example widgets are buttons and text fields.

Consider the following Web-page content:

Six widgets are displayed:


v The enclosing box is myBox
v The upper box within myBox is myBox02 and includes the text field myHelloField
v The lower box within myBox is myBox03 and includes the text field myInTextField,
the button myButton, and the textField myOutTextField

The internal data areas used by the browser are represented as an inverted tree:

334 EGL Programmer’s Guide


The tree is composed of a root -- named document -- and a set of elements, which
are units of information. The topmost element that is available to you is named
body. The elements subordinate to body are specific to your application.

A set of rules describes both the tree and how to access the data that the tree
represents. That set of rules is called the Document Object Model (DOM). We refer to
the tree as the DOM tree; and we refer to the relationships among the DOM
elements by using terms of family relationships:
v myBox03 and myInTextField are parent and child
v myBox and myButton are ancestor and descendant
v myInTextField, myButton, and myOutTextField are siblings

In the simplest case (as in our example), a widget reflects the information in a
single DOM element. In other cases, a widget reflects the information in a subtree
of several elements. But in all cases, the spacial relationship among the displayed
widgets reflects the DOM-tree organization, at least to some extent. The following
rules describe the default behavior:
v A widget that reflects a child element is displayed within the widget that reflects
a parent node
v A widget that reflects a sibling element is displayed below or to the right of a
widget that reflects the immediately previous sibling element

We often use a technical shorthand that communicates the main idea without
distinguishing between the displayed widgets and the DOM elements. Instead of
the previous list, we might say, ″A widget is contained within its parent, and a
sibling is displayed below or to the right of an earlier sibling.″

The DOM tree organization does not completely describe how the widgets are
arranged. A parent element may include detail that causes the child widgets to be
arranged in one of two ways: one sibling below the next or one sibling to the right

Overview of EGL Rich UI 335


of the next. The display also may be affected by the specifics of a given browser;
for example, by the browser-window size, which the user can update at run time
in most cases. Last, the display may be affected by settings in a cascading style
sheet.

When you develop a Web page with Rich UI, you declare widgets much as you
declare integers. However, the widgets are displayable only if your code also adds
those widgets to the DOM tree. Your code can also update the tree—adding,
changing, and removing widgets—in response to runtime events such as a user’s
clicking a button. The central point is as follows: Your main task in Web-page
development is to create and update a DOM tree.

When you work in the Design tab of the Rich UI editor, some of the tasks needed
for initial DOM-tree creation are handled for you automatically during a
drag-and-drop operation. When you work in the Source tab of the Rich UI editor
or in the EGL editor, you can write code directly and even reference DOM
elements explicitly.

In general terms, you create and update a DOM tree in three steps:
1. Declare widgets of specific types—Button for buttons, TextField for text fields,
and so forth—and customize the widget properties. For example, you might set
the text of a button to ″Input to Output,″ as in our example.
2. Add widgets to the initial DOM tree.
3. Alter the DOM tree by adding, changing, and removing widgets at those points
in your code when you want the changes to be displayable.

We say that a widget or its changes are ″displayable″ rather than ″displayed″
because a widget in a DOM tree can be hidden from view.
Related concepts
“Overview of EGL Rich UI” on page 327
“Introduction to the EGL Rich UI editor” on page 337
You can use the EGL Rich UI editor to modify a Rich UI handler and to
preview the handler’s runtime behavior.
Overview of service access
Overview of EGL Rich UI generation and deployment
“Securing a Rich UI application” on page 352
Related reference
Rich UI handler part
Rich UI widgets
Reference to widgets
Extending the Rich UI widget set

336 EGL Programmer’s Guide


Introduction to the EGL Rich UI editor
You can use the EGL Rich UI editor to modify a Rich UI handler and to preview
the handler’s runtime behavior.

Here is an example of an open file in the Rich UI editor.

The Rich UI editor includes three views:


v As shown in the example, the Design surface is a rectangular area that shows
the displayable content of the Rich UI handler. You can drag-and-drop widgets
from the palette into the Design surface and then customize those widgets in the
Properties view.
v The Source view provides an embedded version of the EGL editor, where you
update logic and add or update widgets. The Design view and Source view are
integrated: changes to the Design view are reflected in the Source view; and, if
possible, changes to the Source view are reflected in the Design view.
v The Preview view is a browser, internal to the Workbench, where you can run
your logic. You can easily switch to an external browser if you prefer.

Using the Design surface to create a DOM tree

When you drag a widget from the palette to the Design surface, the areas that can
receive the widget are called potential drop locations, and the color of those areas is
yellow by default. When you hover over a potential drop location, the area is
called a selected drop location, and the color of that area is green by default. You can
customize the colors in the Workbench preferences.

When you first drag a widget to the Design surface, the entire surface is a selected
drop location, and the effect of the drop is to declare the widget and to identify it
as the first element in the Rich UI handler’s initialUI property. That property

Overview of EGL Rich UI 337


accepts an array of widgets at development time. The array is ultimately used to
create a DOM tree, which is a runtime data structure described in Understanding
how browsers handle a Web application. Specifically, the elements in the Rich UI
handler’s initialUI array become children of the document element, with the
order of initialUI array elements at development time equivalent to the order of
sibling DOM elements at run time.

When you drag another widget to the Design surface, you have the following
choices:
v You can place the widget adjacent to the initially placed widget. The effect on
your source code is to declare the second widget and to identify it as another
element in the initialUI array. Your placement of the new widget is either
before or after the first widget and indicates where the widget is placed in the
array.
v If the initially placed widget was a container—for example, a box—you can
place the second widget inside the first. The effect on your source code is to add
an element to the children property of the container. The effect is ultimately to
add a child element to the DOM tree; specifically, to add a child element to the
element that represents the container.

Your subsequent work continues to build the DOM tree. You can repeatedly fulfill
drag-and-drop operations, with the placement of a widget determining what array
is affected and where the widget is placed in the array. The drag-and-drop
operation is an alternative to writing a widget declaration and array assignment in
the code itself, whether in the Source tab of the Rich UI editor or in the EGL
editor.

New widget declarations are added to the source code before the declarations that
were already there; that is, the order of the statements is opposite to the order of
the drag-and-drop operations.

Understanding the transparency options

The Design surface is composed of two layers. The bottom layer is the Web
browser, which displays widgets, including initial text values. The top layer is an
editing overlay, including angle brackets at each corner of each widget.

The background of the top layer can have any of the following characteristics:
transparent, a pattern of white and transparent dots, or (on Windows platforms) a
white layer with a varying level of transparency. You can set those transparency
options by setting a Workbench preference, as described in Setting preferences for
Rich UI appearance. When you are working in the editor, you can change the
transparency options that are in use for the editing session.

Combining the EGL Rich UI editor and the EGL editor

You can complement the features in the Rich UI editor by opening a single file in
both the EGL Rich UI editor and the EGL editor. For example, the following screen
shot displays the file GridDemo.egl in two ways. At the top is the Design tab of
the Rich UI editor, along with a palette that lists the available Widget types. At the
bottom is the EGL editor. Your work in either editor affects the same file and is
reflected in the content displayed in the other editor.

338 EGL Programmer’s Guide


Related concepts
“Overview of EGL Rich UI” on page 327
“Understanding how browsers handle a Rich UI application” on page 334
Related tasks
“Opening the EGL Rich UI editor”
“Creating a Web interface in the Rich UI editor” on page 340
This topic describes how to add, select, move, and delete widgets in the EGL
Rich UI editor. In each case, you work on the Design surface, which you access
by clicking on the Design tab.
“Running a Web application in the EGL Rich UI editor” on page 344
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
Rich UI handler part
Rich UI widgets
Reference to widgets
Extending the Rich UI widget set

Opening the EGL Rich UI editor


As described in Starting to work with EGL Rich UI, you can set the EGL Rich UI
editor to be the default editor for every EGL file and then, in most cases, you can
open the Rich UI editor by double-clicking an EGL file in the Project Explorer.
Here are the alternative procedures:
v To open an existing file:
1. Right-click on the EGL file in the Project Explorer

Overview of EGL Rich UI 339


2. Select Open with → EGL Rich UI Editor
v To create a new file and open it in the Rich UI editor:
1. Select menu item File → New → Other. A wizard is displayed.
2. Expand EGL
3. Select Rich UI Handler
4. Complete the wizard

If the EGL source editor automatically opens:


v Close the source editor
v Right-click on the empty new file in the Project Explorer
v Select Open with → EGL Rich UI Editor
Related concepts
“Overview of EGL Rich UI” on page 327
“Understanding how browsers handle a Rich UI application” on page 334
Related tasks
“Introduction to the EGL Rich UI editor” on page 337
You can use the EGL Rich UI editor to modify a Rich UI handler and to
preview the handler’s runtime behavior.
“Creating a Web interface in the Rich UI editor”
This topic describes how to add, select, move, and delete widgets in the EGL
Rich UI editor. In each case, you work on the Design surface, which you access
by clicking on the Design tab.
“Running a Web application in the EGL Rich UI editor” on page 344
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
Rich UI handler part
Rich UI widgets
Reference to widgets
Extending the Rich UI widget set

Creating a Web interface in the Rich UI editor


This topic describes how to add, select, move, and delete widgets in the EGL Rich
UI editor. In each case, you work on the Design surface, which you access by
clicking on the Design tab.

To learn the implication of the actions described here, see Introduction to the EGL
Rich UI editor.

Adding a widget

Add a widget to a Rich UI handler:


1. Click a Widget type in the palette and hold the left mouse button
2. Drag the widget to the Design surface
3. Use the widget-placement guide to help identify where to drop the widget
4. At the selected drop location, release the mouse button

340 EGL Programmer’s Guide


Selecting a widget when multiple widgets overlap

When multiple widgets overlap a given area, click the area repeatedly to cycle
through the available widgets, making each one the current one in turn. You can
move or delete the current widget as described in the next sections.

Moving a widget

Move a widget from one location to another:


1. Click a widget on the Design surface and hold the left mouse button
2. Drag the widget to the preferred location
3. Use the widget-placement guide to help identify where to drop the widget
4. At the selected drop location, release the mouse button

Deleting a widget

Delete a widget:
v Click the widget and press the Delete key; or
v Right-click the widget and, at the popup menu, select Delete.

The deletion removes the reference to the widget in the handler-specific initialUI
property or in the container-widget-specific children property, but does not
remove the widget declaration from the Rich UI handler.
Related concepts
“Overview of EGL Rich UI” on page 327
“Understanding how browsers handle a Rich UI application” on page 334
Related tasks
“Introduction to the EGL Rich UI editor” on page 337
You can use the EGL Rich UI editor to modify a Rich UI handler and to
preview the handler’s runtime behavior.
“Using the tools on the Design surface”
“Selecting a palette” on page 342
“Setting widget properties and events” on page 343
You use the Properties and Events views when working at the Design surface
of the Rich UI editor.
“Running a Web application in the EGL Rich UI editor” on page 344
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
Rich UI handler part
Rich UI widgets
Reference to widgets
Extending the Rich UI widget set

Using the tools on the Design surface


To design an EGL Rich UI application in the EGL Rich UI editor, click the Design
tab. Here is the toolbar:

Overview of EGL Rich UI 341


The tools on the Design surface provide the following functionality, as indicated by
the hover help that is displayed when you move the mouse over a given tool:
v At the left is the Show transparency controls tool, which is a toggle. Click it to
display or hide the transparency tools, which are described in Setting preferences
for Rich UI appearance.
v The second tool is the Show browser size controls tool, which is also a toggle.
Click it to display or hide the scroll bars that let you specify the browser size
within the constraints that you set in the preferences. Again, further details are
in Setting preferences for Rich UI appearance.
v The next tool is the Configure bidirectional options tool, which (if enabled) lets
you open the preference page described in Setting preferences for Rich UI
bidirectional text. See that topic for details on enabling the tool on the Design
surface.
v The fourth tool is the Configure preferences tool. Click it to access the
preferences that are described in Setting preferences for Rich UI appearance.
v Second to the right is the Refresh palette tool, which searches the Workspace for
widgets that have the @VEWidget complex property and then refreshes the palette
to reflect the outcome of that search.
v At the right is the Refresh web page tool. Click it to refresh the Web page, as
may be necessary after you change the widgets in an embedded handler. For an
introduction to embedded handlers, see Rich UI handler part.
Related concepts
“Overview of EGL Rich UI” on page 327
“Understanding how browsers handle a Rich UI application” on page 334
Related tasks
“Introduction to the EGL Rich UI editor” on page 337
You can use the EGL Rich UI editor to modify a Rich UI handler and to
preview the handler’s runtime behavior.
“Setting preferences for Rich UI appearance” on page 347
“Opening the EGL Rich UI editor” on page 339
“Using the tools on the Design surface” on page 341
“Setting widget properties and events” on page 343
You use the Properties and Events views when working at the Design surface
of the Rich UI editor.
“Running a Web application in the EGL Rich UI editor” on page 344
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
Rich UI handler part
Rich UI widgets
Reference to widgets

Selecting a palette
Two palettes are available to the Rich UI editor. Each provides the same widgets as
the other, and in each case you can right-click the palette or one of its drawers to
display a menu that provides Eclipse-based options.

The default palette is tied to the Rich UI editor. You can resize the width of the
palette or dock it on the left or right.

342 EGL Programmer’s Guide


The other palette is a view, which you can move anywhere in the perspective or
detach from the Workbench. If you want the extra flexibility provided by the
Palette view, do as follows:
1. Click Window -> Show View -> Other. The Show View dialog is displayed.
2. Expand General.
3. Click Palette and then OK.

The effect of selecting the Palette view is to close the Rich UI editor palette. If you
want to return to the Rich UI editor palette, close the Palette view.
Related concepts
“Overview of EGL Rich UI” on page 327
“Understanding how browsers handle a Rich UI application” on page 334
Related tasks
“Introduction to the EGL Rich UI editor” on page 337
You can use the EGL Rich UI editor to modify a Rich UI handler and to
preview the handler’s runtime behavior.
“Opening the EGL Rich UI editor” on page 339
“Using the tools on the Design surface” on page 341
“Setting widget properties and events”
You use the Properties and Events views when working at the Design surface
of the Rich UI editor.
“Running a Web application in the EGL Rich UI editor” on page 344
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
Rich UI handler part
Rich UI widgets
Reference to widgets

Setting widget properties and events


You use the Properties and Events views when working at the Design surface of
the Rich UI editor.

To make the Properties and Events views available, do as follows:


1. Click the Design tab
2. Right-click a widget and select Properties

Setting properties

At the Properties tab, you can add a value to a widget property, and the editor
updates when you press Tab or Enter.

To remove a property value from a text box, select the value and press the Delete
key. To remove a property value from a list box, select the (none).

To handle color selection, do as follows:


1. Click the color or background Color property, if available. The Color selection
dialog is displayed
2. Three alternatives are available:
v To work in the traditional Color dialog, click the Number format radio
button and the subordinate Color button. On returning to the Color selection
Overview of EGL Rich UI 343
dialog, you can also specify whether the numeric color values retained from
the Color dialog should be saved in RGB or hexadecimal format.
v To select from a list of named colors instead, click the Name Format radio
button and select a color.
v To specify a value of your own, click the Custom radio button option. RGB
and hexadecimal formats are both valid.

Creating new functions and enabling events

At the Events tab, you can create a new function in the Rich UI handler:
1. Click the New event handler icon. The New event handler dialog is displayed.
2. Specify the function name and click OK.

Also at the Events tab, you can specify which Rich UI handler function to run in
response to an event such as a user’s click on a button. In this case, you also add
an entry for an event property such onClick. Here are the keystroke details:
v To specify an existing Rich UI handler function, select the event of interest and
use the dropdown to select the function name.
v Alternatively, to create a new function, do as follows:
1. Select the event of interest and click the New event handler icon. The New
event handler dialog is displayed.
2. Specify the function name and, if you want to link the function to the event,
ensure that the checkbox is selected.
3. Click OK.
Related concepts
“Overview of EGL Rich UI” on page 327
“Understanding how browsers handle a Rich UI application” on page 334
Related tasks
“Introduction to the EGL Rich UI editor” on page 337
You can use the EGL Rich UI editor to modify a Rich UI handler and to
preview the handler’s runtime behavior.
“Opening the EGL Rich UI editor” on page 339
“Using the tools on the Design surface” on page 341
“Selecting a palette” on page 342
“Running a Web application in the EGL Rich UI editor”
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
Rich UI handler part
Rich UI widgets
Reference to widgets

Running a Web application in the EGL Rich UI editor


To run an EGL Rich UI application in the EGL Rich UI editor, click the Preview
tab. Here is the toolbar:

344 EGL Programmer’s Guide


The tools at the Preview tab provide the following functionality, as indicated by
the hover help that is displayed when you move the mouse over a given tool:
v At the left is the Debug tool. For details, see EGL Rich UI debugging.
v Second is the Launch external browser tool. Click it to place the output of the
Rich UI application in an external browser as well as in the Preview view. You
can select which external browser is invoked by setting a system preference:
1. Click Window -> Preferences.
2. At the Preferences dialog, expand General and click Web Browser.
3. The check boxes Use Internal Web Browser and Use External Web Browser
have no effect on Rich UI. However, you can select your external browser by
selecting from the list of browsers shown at that dialog and then clicking
OK.
v The third tool is the Configure preferences tool. Click it to access the
preferences that are described in Setting preferences for Rich UI appearance.
v At the right is the Refresh Web page tool. Click it to rerun a generated Web
page from the start.
Related concepts
“Introduction to the EGL Rich UI editor” on page 337
You can use the EGL Rich UI editor to modify a Rich UI handler and to
preview the handler’s runtime behavior.
“Overview of EGL Rich UI” on page 327
“Understanding how browsers handle a Rich UI application” on page 334
Related tasks
Rich UI debugging
“Setting preferences for Rich UI appearance” on page 347
“Opening the EGL Rich UI editor” on page 339
“Creating a Web interface in the Rich UI editor” on page 340
This topic describes how to add, select, move, and delete widgets in the EGL
Rich UI editor. In each case, you work on the Design surface, which you access
by clicking on the Design tab.
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
Rich UI handler part
Rich UI widgets
Reference to widgets
Extending the Rich UI widget set

Setting preferences for Rich UI


Set the initial Rich UI preferences as follows:
1. From the main menu, click Window → Preferences. The Preferences page is
displayed.
2. Expand EGL and then Rich UI. The Rich UI dialog box is displayed.
3. Select one of two values in the Generation mode list box:
Development mode
The generated output has information required by the EGL debugger and
the EGL Rich UI editor.

Overview of EGL Rich UI 345


Deployment mode
The generated output lacks the extra information but is smaller and more
efficient. Deployment mode is appropriate immediately before you add
fully tested code to a production environment.
4. In the Locales area, specify the locales that are available in the Rich UI editor
and in the Rich UI deployment wizard. The settings are used for globalization.
The availability of a locale means that you can invoke and deploy a Rich UI
application that provides messages appropriate to the locale. For details, see
Use of properties files for displayable text.
To add a locale, do as follows:
a. Click Add. The Create a new locale dialog is displayed.
b. Specify a locale code and description.
c. Specify a locale for the EGL runtime messages, which are provided by the
EGL Runtime and are distinct from the messages included in a properties
file that you customize.
d. Click OK.
To remove a locale from the list, do as follows:
a. Double-click a locale entry
b. Click Remove
At the Rich UI dialog box, you can click into the Locale Description or Locale
Code column and change the content. Also, by clicking in the Runtime
Messages Locale column and selecting from a list, you can assign a locale for
the EGL runtime messages, even if that locale is distinct from the locale used
for the messages that you provide.
5. If you want to return the settings on the Rich UI dialaog to the original
product settings, click Restore Defaults.
6. Click Apply to save your changes and remain in the Preferences page.
Alternatively, click OK to save the changes and exit the page; or click Cancel to
cancel the changes and exit the page.
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related tasks
“Enabling EGL capabilities” on page 11
Capabilities keep the workbench menus from becoming cluttered by hiding
items you do not use. You can always perform these tasks, but to make them
appear in the menus, you must enable the capability for that area of
functionality.
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
“Setting preferences for Rich UI appearance” on page 347
“Setting preferences for Rich UI bidirectional text” on page 349
When you establish preferences for Rich UI bidirectional text, you provide
initial values for the bidirectional settings assigned to widgets as they are
dragged from the palette and dropped on the Design surface.
“Setting preferences for Rich UI deployment” on page 351
Preferences guide the behavior of the Rich UI deployment wizard. We introduce
that wizard in Overview of Rich UI generation and deployment.

346 EGL Programmer’s Guide


Setting preferences for Rich UI appearance
Begin to set the appearance of the Rich UI editor as follows:
1. From the main menu, click Window → Preferences. The Preferences dialog box
is displayed.
2. Expand EGL and Rich UI; and then click Appearance. The Appearance page is
displayed, with three tabs: General, Browser size, and Languages.

We describe each tab in turn. On completing the tabs, do as follows:


1. If you want to return the settings on the Appearance pane to the original
product settings, click Restore Defaults.
2. Click Apply to save your changes and remain on the Preferences dialog box.
Alternatively, click OK to save the changes and exit the dialog box; or click
Cancel to cancel the changes and exit the dialog box.

General tab
At the General tab, do as follows:
1. In the Editor tab section, select Design, Source, or Preview to indicate which
tab to initially use whenever you open the Rich UI editor.
2. In the Widget creation section, indicate whether the Rich UI editor must
prompt you for a variable name each time you drag a widget from the palette
to the Design surface. If you clear the checkbox, the Rich UI editor creates its
own variable name, which is the widget type name (for example, Button)
followed by a sequentially assigned integer. For example, the assigned names
might be Button1, Button2, Box1, and so forth.
3. In the Transparency section, indicate how to handle the transparency controls,
which vary how widgets are displayed in the Design tab of the Rich UI editor.
The transparency controls are particularly useful when you are working on a
Design surface with many widgets that are close together.
The Design surface is composed of two layers. The bottom layer is the Web
browser, which displays widgets, including initial text values. The top layer is
an editing overlay, including angle brackets at each corner of each widget. The
background of the top layer can have any of the following characteristics:
transparent, or a pattern of white and transparent dots, or (on Windows
platforms) a white layer with a varying level of transparency.
The transparency options provided in the Appearance pane affect the behavior
of the Rich UI editor every time you open the editor. However, when you are
working in the editor, you can change the transparency options that are in use
for the editing session. The options are as follows:
a. Select or clear the check box Show transparency controls to indicate
whether to display the transparency controls. When you start working with
Rich UI, you are likely to prefer hiding the controls, as is the default setting
for this preference.
b. Next, select one of the following transparency modes, which affect the
background of the top layer of the Design surface:
v Fully transparent means that the background is transparent.
v Dotted transparency pattern means that the background is a pattern of
white and transparent dots. The refresh rate of your monitor may cause
the pattern to shimmer.
v On Windows platforms, Variable transparency means that the
background is a white layer with a varying level of transparency. You
vary the level by changing the numeric value of a slider. The dotted

Overview of EGL Rich UI 347


transparency pattern described earlier is roughly equivalent to the
variable transparency pattern at 38%.
c. The checkbox named Enable semi-transparency while dragging allows use
of a temporary transparency mode as you drag a widget from the palette to
the Design surface or from one location on the Design surface to another.
Selecting the checkbox means that the temporary mode is the dotted
transparency pattern. Clearing the checkbox means that your usual
transparency mode remains in effect. The checkbox has no effect if your
usual transparency mode is the dotted transparency pattern.
4. In the Colors section, specify details on the following issues:
v The border of the currently selected widget
v The potential drop locations for a widget being dragged from the palette to
the Design surface or from one location on the Design surface to another
v The selected drop location, which is a potential drop location over which the
widget is hovering during a drag-and-drop operation
For the border and each location, you can click the adjacent button to display a
color dialog, where you can choose or refine a color. Also, for the border and
the selected drop location, you can select (or clear) a check box to include (or
exclude) the displayed pattern.
5. In the Performance section, select the radio button that reflects your current
need, whether for greater responsiveness or for less usage of runtime resources
such as memory. One effect of selecting Optimize to use fewer resources is
that you increase the amount of time needed to display content when you
select the Design or Preview tab.
6. In the Dependencies section, you can cause the Rich UI editor to prompt you
before adding a project to the EGL build path. The nature of project
dependencies is described in The EGL build path.
The dependency issue arises in this case because the Widget types available in
the palette may be from any project in the workspace. The prompt, if any,
occurs when you attempt to drop a widget for which the type is defined in a
project that is not already in the EGL build path.
Select the checkbox to cause a prompt, which lets you add the entry to the EGL
build path or to cancel the operation. Clear the checkbox to add the entry
automatically.

Browser size tab

In the Browser size tab, you set the browser size that is appropriate for a specific
kind of device such as a cell phone. Specifically, you set options that are in effect
whenever you open the Rich UI editor. However, when you are working in the
editor, you can change the browser-size options for the file being edited.

The options are as follows:


1. Select or clear the check box Browser size controls to indicate whether to
display the controls when a file is opened in the Rich UI editor. When you start
working with Rich UI, you are likely to prefer hiding the controls, as is the
default setting for this preference.
2. Change the numeric values of the sliders to specify the default height and
width in pixels. The default you set becomes the browser size that is provided
initially in the Rich UI editor. Similarly, change the numeric values of the
sliders to specify the minimum and maximum height and width that are valid
in any file open in the Rich UI editor. You can change the maximum and
minimum only by returning to the Appearance page.

348 EGL Programmer’s Guide


Languages tab

In the Languages tab, you assign values that determine what messages to use
when you run Rich UI applications in the Preview tab of the Rich UI editor or in
an external browser. For details on the use of locales, see Use of properties files for
displayable text.

When you work in the Languages tab, you choose among locales that are listed in
the Rich UI pane, as described in Setting preferences for Rich UI. Your tasks are as
follows:
1. In the Runtime messages locale list box, select the locale for the EGL runtime
messages, which are provided by the EGL Runtime and are distinct from the
messages included in a properties file that you customize.
2. In the Rich UI handler locale list box, select the locale for the messages
included in a properties file, if any, that you customize.
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related tasks
“Setting preferences for Rich UI” on page 345
“Setting preferences for Rich UI bidirectional text”
When you establish preferences for Rich UI bidirectional text, you provide
initial values for the bidirectional settings assigned to widgets as they are
dragged from the palette and dropped on the Design surface.
“Setting preferences for Rich UI deployment” on page 351
Preferences guide the behavior of the Rich UI deployment wizard. We introduce
that wizard in Overview of Rich UI generation and deployment.
“Enabling EGL capabilities” on page 11
Capabilities keep the workbench menus from becoming cluttered by hiding
items you do not use. You can always perform these tasks, but to make them
appear in the menus, you must enable the capability for that area of
functionality.
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.

Setting preferences for Rich UI bidirectional text


When you establish preferences for Rich UI bidirectional text, you provide initial
values for the bidirectional settings assigned to widgets as they are dragged from
the palette and dropped on the Design surface.

You can set these preferences only if you previously enabled bidirectional text as
follows:
1. From the main menu, click Window → Preferences. The Preferences dialog box
is displayed.
2. Expand EGL and select Bidirectional text. The Bidirectional text page is
displayed.
3. Select the Enable bidirectional support checkbox. After this check box is
selected, the other options are available.
4. To display and edit the bidirectional text fields in visual mode (the way the text
will be displayed), select Enable visual data ordering.
5. For languages that read from right to left, select Enable right-to-left
orientation.

Overview of EGL Rich UI 349


Here are the steps for setting the Rich UI preferences:
1. From the main menu, click Window → Preferences. The Preferences dialog box
is displayed.
2. Expand EGL, Rich UI, and then Appearance; and click on Bidirectional text.
The Bidirectional text page is displayed.
3. Establish the following settings:
Widget Orientation
The setting is either LTR (left-to-right) or RTL (right to left):
v When you specify LTR, the widgets acts as a standard
non-bidirectional widget
v When you specify RTL, the widgets are mirrored; that is, scroll bars
for dropdown lists appear on the left, the text-typing orientation for
input fields is right-to-left, and the text is right-aligned
Text Layout
The setting is either Visual or Logical:
v If the setting is Visual and the user types ″A″ and then ″B″ (and if
″A″ and ″B″ are characters in a bidirectional language), the displayed
characters are ″AB″. The order of display is the order of input, left to
right, which is also the order in which the data is stored in local
memory.
v If the setting is Logical, the displayed characters are ″BA″.
In most cases, Visual is appropriate for Arabic or Hebrew content
derived from a machine that runs z/OS or IBM i.
Reverse Text direction
The setting indicates whether to reverse the text direction in the widget.
Symmetric Swapping
This setting indicates whether to replace pairs of special characters and
in this way to preserve the logical meaning of the presented text. If the
value is ″Yes″, the effect is to replace paired characters such as <, >, [,
and { with >, <, ], and }.
Numeric Swapping
Lets you use Hindi numerals in Arabic text. To use Hindi numerals, set
numericSwap and reverseTextDirection to Yes.
4. If you want to return the settings on the Bidirectional text pane to the original
product settings, click Restore Defaults.
5. Click Apply to save your changes and remain on the Preferences dialog box.
Alternatively, click OK to save the changes and exit the dialog box; or click
Cancel to cancel the changes and exit the dialog box.
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related tasks
“Setting preferences for Rich UI” on page 345
“Setting preferences for Rich UI appearance” on page 347
“Setting preferences for Rich UI deployment” on page 351
Preferences guide the behavior of the Rich UI deployment wizard. We introduce
that wizard in Overview of Rich UI generation and deployment.
“Enabling EGL capabilities” on page 11
Capabilities keep the workbench menus from becoming cluttered by hiding

350 EGL Programmer’s Guide


items you do not use. You can always perform these tasks, but to make them
appear in the menus, you must enable the capability for that area of
functionality.
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.

Setting preferences for Rich UI deployment


Preferences guide the behavior of the Rich UI deployment wizard. We introduce
that wizard in Overview of Rich UI generation and deployment.

Set the deployment preferences as follows:


1. From the main menu, click Window → Preferences. The Preferences dialog box
is displayed.
2. Expand EGL and Rich UI and then click Deployment. The Deployment page
is displayed.
3. In the Prompts area, indicate what is to occur when the generation mode is
Development and you run the Rich UI deployment wizard. Selecting the check
box means that the wizard must prompt you to change the generation mode to
Deployment. Clearing the check box means that the deployment will proceed
without a prompt, and no regeneration occurs; the generation mode remains
Development.
4. In the Rich UI Application locales area, you select which locales are supported
by default when you run the Rich UI deployment wizard. For details on the
use of locales, see Use of properties files for displayable text. All the locales that are
available to you in the Rich UI Application locales area are listed in the Rich
UI pane, as described in Setting preferences for Rich UI.
5. If you want to return the settings on the Deployment page to the original
product settings, click Restore Defaults.
6. Click Apply to save your changes and remain on the Preferences dialog box.
Alternatively, click OK to save the changes and exit the dialog box; or click
Cancel to cancel the changes and exit the dialog box.
Related concepts
Overview of EGL Rich UI generation and deployment
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related tasks
“Setting preferences for Rich UI” on page 345
“Setting preferences for Rich UI bidirectional text” on page 349
When you establish preferences for Rich UI bidirectional text, you provide
initial values for the bidirectional settings assigned to widgets as they are
dragged from the palette and dropped on the Design surface.
“Setting preferences for Rich UI appearance” on page 347
“Enabling EGL capabilities” on page 11
Capabilities keep the workbench menus from becoming cluttered by hiding
items you do not use. You can always perform these tasks, but to make them
appear in the menus, you must enable the capability for that area of
functionality.
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
Use of properties files for displayable text

Overview of EGL Rich UI 351


Securing a Rich UI application
Implementing security is an integral part of Web application development that you
should consider carefully when you design a Rich UI application. In the rush to
unveil new dynamic, interactive Web applications, developers sometimes forgo
adding security measures. Attackers know how to exploit the vulnerabilities of
applications. All kinds of organizations have been victimized, with results ranging
from simple embarrassment to the public distribution of sensitive data. The best
approach to avoid such problems is to eliminate weaknesses before they can be
exploited.

Typically, security is configured after a Rich UI application is deployed; however,


the security design should be determined early and integrated with the design of
the application. When you apply security early in the development cycle, the
process can be easier and you can avoid problems that might be costly if found
late in the cycle.

You should also evaluate JSF applications that are rewritten into Rich UI
applications for security issues. Even if the JSF application was not originally
secure, the introduction of the EGL Rich UI Proxy in V7.5.1 presents security risks
that must be mitigated. You might need to change the design of the application.

This section contains considerations that are specific to securing the resources that
are related to Rich UI applications. It also provides a quick overview and examples
of how to configure and use Java™ Enterprise Edition (JEE) authentication and
Secure Sockets Layer (SSL). Security is not available when you preview a Rich UI
application from the EGL Rich UI editor. Because security is a large and complex
topic, also consult the online documentation of your application server and other
security documentation.
Related concepts
“Overview of Rich UI security”
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
“Resources to secure” on page 355
“JSF versus Rich UI applications” on page 357
“Using Web container-managed (JEE) authentication” on page 357
“Using application-managed (custom) authentication” on page 362
“Authentication summary” on page 367
“Authorization” on page 368
“Overview of SSL” on page 377
“Overview of EGL Rich UI” on page 327
Related tasks
“Preventing client-side security threats” on page 376
Related reference
“Sample login and error pages for JEE form-based authentication” on page 374
“JEE security example” on page 369

Overview of Rich UI security


Security can be managed either by a Web container (the environment in which an
application runs) or by the application itself. A Web container is synonymous to a
JEE application server, such as IBM® WebSphere® Application Server or Apache

352 EGL Programmer’s Guide


Tomcat. Web container-managed security is also known as JEE or J2EE security.
Security that is written by the developer of the application, application-managed
security, is also known as custom security. Both kinds of security have advantages
and drawbacks that you must understand before you implement them.

You can choose to use either declarative or programmatic security. In declarative


security, security policies are defined outside of the application in deployment
descriptors or configuration files so the application is security-unaware. With
programmatic security, the application code contains explicit security calls.

Web container-managed (JEE) security is declarative because security constraints


are defined in deployment descriptors or configuration files. JEE security can also
be programmatic because it includes some security-related APIs that can be called
from within an application. Application-managed (custom) security is
programmatic because security is handled completely from within the application.

Major components of security include authentication, authorization, confidentiality,


and integrity:
Authentication
The method by which the identity of a user is verified. Typically,
authentication occurs by providing a user id and password in a login
screen.
Authorization
The process of determining whether a user has permission to access a
particular resource
Confidentiality
Guarantees that the data that is passed between a sender and recipient is
protected from eavesdroppers.
Integrity
Ensures that the data that flows between a sender and recipient was not
modified in transit
Related concepts
“Securing a Rich UI application” on page 352
“Authentication and Authorization”
“Confidentiality and Integrity” on page 355
Overview of service access
Overview of EGL Rich UI generation and deployment
Related reference
Rich UI handler part
Rich UI widgets

Authentication and Authorization


Authentication and authorization support can be provided by the following:
v Web container-managed (JEE) security that is provided by application servers,
such as WebSphere Application Server or Apache Tomcat.
v Application-managed (custom) security that is written in the application.

Consider using JEE security to protect your Rich UI application in the following
cases:
v The entire Rich UI application needs to be secured.

Overview of EGL Rich UI 353


v You do not need to access security-related information from within the Rich UI
application.
v You do not want to write security-related code in your application.

Consider using custom security to protect your Rich UI application in the


following cases:
v Access to some or all of your Rich UI application needs to be restricted.
v You want to access the user id, password, or both from within the application.
v You want to combine the authentication of your Rich UI application with the
authentication of other resources that the application uses in a process called
EGL single sign-on. For more details, see ″EGL single sign-on.″.

Web container-managed (JEE) security

Web container-managed security transfers the responsibility of user authentication


and authorization to the container, allowing the EGL developer to focus on
business logic.

Two common types of JEE authentication are basic and form-based. In JEE basic
authentication (also known as HTTP basic authentication), when a client, such as a
browser, requests a Web page from a server without providing a user id and
password, the server sends back a 401 response code. The client then prompts the
user for a user id and password by displaying a default login dialog to the user.
The client resends the request to the server, including the user id and password in
the HTTP header. If the user is authenticated, the server returns the requested
page. If the user id and password are invalid, the server returns a 401 response
code and the client prompts the user again. In JEE form-based authentication, you
can use a customized login screen with the look and feel of the application instead
of the browser-provided login dialog. The user id and password are passed to the
server in the form data instead of in the HTTP header of the request.

JEE security uses roles to manage access to resources. Certain roles are allowed
access to certain resources. Users and groups are mapped to appropriate roles. For
example, the user bob might be mapped to the role administrator.

JEE authorization can be declarative or programmatic. Declarative authorization is


available because security information is specified in deployment descriptors. The
application servers access these deployment descriptors to determine if a specific
user is assigned to a role and decides whether a particular resource can be
accessed by that role. While JEE security also includes programmatic authorization
through the use of APIs, such as isUserInRole(), these functions are not available
from within a Rich UI application. Therefore, Rich UI applications should perform
authorization either declaratively or through custom, user-provided code.

User registries, such as Lightweight Directory Access Protocol (LDAP) directory


servers or relational databases used with JEE security, are external to the JEE
environment. A system administrator must perform administrative tasks, such as
adding a new user to the repository.

While JEE security is available through WebSphere Application Server and Apache
Tomcat, it is not available from the Workbench. You need to deploy a Rich UI
application to WebSphere or Tomcat to apply and test security.

354 EGL Programmer’s Guide


To determine if JEE security is appropriate for your situation, review the
documentation in this chapter and the more detailed online documentation for
your application server.

Application-managed (custom) security

If Web container-managed security is not suitable for your needs, you can build
custom security into your Rich UI application. Although custom security requires
that you add security-related code to your Rich UI application, you cannot avoid it
if JEE security alone is not sufficient to express the security model of an
application. If you prefer, you can combine both forms of security.

Custom authorization can provide a more granular level of authorization than JEE
roles. You might want to use custom security to authenticate users before they can
access restricted parts of your application.
Related concepts
“Overview of Rich UI security” on page 352
“Confidentiality and Integrity”
“Authentication summary” on page 367
Related tasks
“Using Web container-managed (JEE) authentication” on page 357
“Using application-managed (custom) authentication” on page 362

Confidentiality and Integrity


Although you can use JEE security to secure Web resources from unauthenticated
or unauthorized users, JEE security cannot prevent the data that flows between a
client and server from being intercepted or read. For these purposes, you can use
Secure Sockets Layer (SSL). SSL guarantees data integrity, ensures that messages
between a client and server are not tampered with or modified, and provides
confidentiality through encryption. SSL also includes server authentication, which
allows a client to confirm the identity of a server, and client authentication, which
allows a server to confirm the identity of a client.

It is important that you authenticate over SSL, whether you use JEE form-based,
JEE basic, or custom authentication. For more information about SSL, see
″Overview of SSL.″
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353

Resources to secure
When you determine which resources to secure, review all of the components that
have a URL mapping and that your Rich UI application accesses:

Generated HTML file

EGL generates a Rich UI application into an HTML file. HTML files are generated
into the WebContent folder (or into a subfolder in the WebContent folder) of your
deployed project. If an HTML file is secure, you must authenticate before you
access the Rich UI application that is defined in the HTML file. To secure the entire
HTML file, you can use JEE authentication. To restrict sensitive areas of the Rich
UI application, you can use custom security.

Overview of EGL Rich UI 355


EGL Rich UI Proxy

The EGL Rich UI Proxy handles communication between the HTML file that EGL
generates for a Rich UI application and Web services Because of the Same Origin
policy for JavaScript™, the HTML file cannot invoke a Web service that has a
different origin (defined as protocol, domain, and port) than that of the HTML file.
To get to Web services on different origins, the HTML file uses a Java servlet
known as the EGL Rich UI Proxy. All Web services that are invoked in a Rich UI
application are accessed through the proxy.

The EGL Rich UI Proxy servlet is of the type


com.ibm.javart.services.RestServiceServlet and is shipped with the EGL runtime in
fda7.jar. The servlet is deployed to the same project as your generated HTML file.
While the HTML file runs in a browser, the EGL Rich UI Proxy runs on an
application server.

Because the URL of the EGL Rich UI Proxy is visible in the JavaScript that EGL
generates for your Rich UI application, you must prevent the proxy from being
used by anyone other than your Rich UI client to invoke Web services. If you leave
the proxy unsecured, it can be used to instigate JavaScript hijacking attacks. If your
Rich UI application does not use the EGL Rich UI Proxy (that is, if the application
invokes no Web services), remove access to the proxy from your deployed project.
For more information, see Removing access to the EGL Rich UI Proxy servlet.
Otherwise, you can use JEE basic authentication to prevent the proxy from being
invoked by an unauthenticated client. While this action cannot guarantee
protection against Web threats, it can reduce the possibility of one occurring.

If both the HTML file and EGL Rich UI Proxy are secure, authentication is required
only before you can access the HTML file. If the EGL Rich UI Proxy is secure and
the HTML file is not, authentication is required before you can access the proxy
(that is, before the application calls a Web service that is invoked through the
proxy).

EGL Web service

To secure EGL Web services that are generated into a Web project, you can use JEE
security through HTTP basic authentication. In HTTP basic authentication, you
access secure Web services by passing a valid user id and password in the HTTP
header. EGL provides a system function in ServiceLib,
setHTTPBasicAuthentication, which sets these values in the header. Precede each
call to a secure Web service with a call to setHTTPBasicAuthentication.

To avoid security exposures, never hardcode the user id and password into the
Rich UI application. Instead, the Rich UI application should display a user-defined
login screen to prompt the user for the values to pass to
setHTTPBasicAuthentication. Once you obtain the password, you can store it in
your Rich UI handler or a library for future Web service calls. Whenever you need
a different set of credentials to pass to a Web service, you must prompt the user
again.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355

356 EGL Programmer’s Guide


JSF versus Rich UI applications
Differences exist between generated and deployed JSF applications and Rich UI
applications. You should understand these ramifications because they can affect the
type of security you choose to implement.

For JSF applications, each JSF handler is associated with a Faces JSP. The JSF
handler and EGL parts it references are generated into Java. Each JSP is generated
into its own file and has its own URL, which might need to be secured from
unauthenticated users using JEE security. When securing URLs, you can choose to
include some or all of the JSPs in your JSF application. Depending on your choices,
you can keep some JSPs in your JSF application public and restrict other JSPs to
authenticated users.

For Rich UI applications, EGL generates the contents of all the Rich UI handlers in
an application into JavaScript in a single HTML file. If your Rich UI application
calls EGL Web services, you must generate those services into Java because Web
services run on an application server, not in a Web browser. The HTML file that
EGL generates for a Rich UI application is associated with a single URL that can be
secured with JEE security. If you choose to secure a URL with JEE security, users
will be prompted to authenticate before they can access any part of your Rich UI
application. If you want to make some of the areas of your Rich UI application
public, you cannot use JEE authentication. Instead, use custom security to prompt
users to log in before they can access the restricted parts of your application.

Another major difference between JSF and Rich UI applications is that the EGL
Rich UI Proxy, which Rich UI applications use to call Web services, is not needed
by JSF applications because JSF handlers are generated into Java instead of
JavaScript.
Related concepts
“Using Web container-managed (JEE) authentication”
“Using application-managed (custom) authentication” on page 362

Using Web container-managed (JEE) authentication


After you deploy a Rich UI application, you can secure the resources in your
deployed project from unauthenticated users by using the Web container-based,
JEE security that is provided by WebSphere Application Server or Apache Tomcat.
After resources, such as the HTML file generated for your Rich UI application, are
secured with JEE security, users will have to authenticate before they can access
those resources. Every action that the Web container or JRE takes on behalf of the
user is done only if the user belongs to a set of roles that have permission to take
that action. The user is only requested to authenticate once even if multiple
resources are secured.

In JEE authentication, a system administrator performs administration tasks, such


as adding or deleting user data from a repository, independently of the
applications that access the repository. Application servers support various types of
repositories, or realms, such as the local OS registry, LDAP directories, and custom
directories such as relational databases and flat files. You can use these repositories
to store user ids, passwords, and other security information.

To secure the entire Rich UI application, the EGL Rich UI Proxy, and Web services,
you can use JEE security.

Overview of EGL Rich UI 357


In JEE role-based security, access to resources is granted to roles, which are then
mapped to actual user registry entries. Security information, such as roles and
constraints, are defined declaratively, or outside of the application, in deployment
descriptors such as web.xml and application.xml. . In V7.5.1, you must use
declarative JEE security with Rich UI applications. The J2EELib system functions
that are available for programmatic security from JSF handlers (getRemoteUser(),
isUserInRole(), and getAuthenticationType()) are not available from Rich UI
handlers.

In both JEE basic and form-based authentication, the password is encoded using
the Base64 encoding scheme, a format that is easy to decode. To ensure that the
password is not compromised, use SSL in conjunction with these types of
authentication. For an introduction to SSL, see ″Overview of SSL.″

For more details on Web container-managed authentication, see WebSphere


Application Server or Apache Tomcat documentation.
Related concepts
“Overview of Rich UI security” on page 352
“Securing a Rich UI application” on page 352
Related tasks
“Defining URL patterns for Rich UI resources”
“Securing the HTML file by using form-based authentication” on page 359
“Securing the EGL Rich UI Proxy by using basic authentication” on page 359
“Removing access to the EGL Rich UI Proxy servlet” on page 360
“Securing EGL Web services by using basic authentication” on page 361

Defining URL patterns for Rich UI resources


Security constraints define how the content of a Web project is protected. To use
JEE security to protect a resource, in the security constraints in the deployment
descriptor (web.xml) of your deployed project, specify the URLs of the resources to
secure.

The following sections contain information on how to secure the various


components of a Rich UI application:
v Securing the HTML file by using form-based authentication
v Securing the EGL Rich UI Proxy by using basic authentication
v Securing EGL Web services by using basic authentication

Those sections also refer to URL patterns.

To secure all the resources that are in the WebContent folder of a deployed project,
specify /* as the URL pattern. Specifying /* as your URL pattern secures your
HTML page, EGL Rich UI Proxy, and SOAP and REST services.
Related concepts
“Overview of Rich UI security” on page 352
“Securing a Rich UI application” on page 352
“Using Web container-managed (JEE) authentication” on page 357
Related tasks
“Securing the HTML file by using form-based authentication” on page 359
“Securing the EGL Rich UI Proxy by using basic authentication” on page 359
“Removing access to the EGL Rich UI Proxy servlet” on page 360

358 EGL Programmer’s Guide


“Securing EGL Web services by using basic authentication” on page 361

Securing the HTML file by using form-based authentication


To secure your Rich UI application, you can use JEE form-based authentication (the
most popular Web authentication method in use) for which you to supply your
own customized login page that contains a user id and password. Users cannot
access any part of the Rich UI application until they authenticate. The encoding
scheme for the password is Base64 encoding, which can be easily decoded. To
ensure password confidentiality, use SSL connections with form-based
authentication. When you use form-based authentication, error handling, such as
displaying specific error messages, is difficult to implement. If an authentication
error occurs, an error page is returned with the status code of the response set to
401.

For sample login and error pages that you can use with form-based authentication,
see ″Sample login and error pages for JEE form-based authentication.″

To secure the HTML file that EGL generates for a Rich UI application named
RSSReader, specify a URL pattern of /RSSReader.html. If RSSReader.html is in a
subdirectory of WebContent named Secured, specify a URL pattern of
/Secured/RSSReader.html.

When you use form-based authentication to secure the HTML file, include the EGL
Rich UI Proxy in the security constraint. To secure the EGL Rich UI Proxy, specify
a URL pattern of /___proxy (three underscores). By specifying this pattern, you
prevent unauthenticated users from accessing the proxy. After logging in, users
will gain access to the EGL Rich UI Proxy as well as the HTML file.
Related concepts
“Overview of Rich UI security” on page 352
“Securing a Rich UI application” on page 352
“Using Web container-managed (JEE) authentication” on page 357
Related tasks
“Defining URL patterns for Rich UI resources” on page 358
“Securing the EGL Rich UI Proxy by using basic authentication”
“Removing access to the EGL Rich UI Proxy servlet” on page 360
“Securing EGL Web services by using basic authentication” on page 361

Securing the EGL Rich UI Proxy by using basic authentication


Use JEE basic authentication to secure the EGL Rich UI Proxy. Require users to
authenticate to the proxy before it can be used to process Web service calls. If you
require users to authenticate, you prevent unauthenticated clients from accessing
the proxy for illegal purposes.

To secure the EGL Rich UI Proxy, in a security constraint in your web.xml, specify
a URL pattern of /___proxy (three underscores).

By using JEE basic authentication, the Web server uses a browser-provided dialog
to collect a user id and password. This dialog looks like the following dialog for
Mozilla® Firefox® V2.0:

Overview of EGL Rich UI 359


If you use this login dialog, you cannot customize the dialog to look like the rest of
your Rich UI application. The dialog is redisplayed until a valid user id and
password are entered. The HTTP standard requires that when login fails, the server
returns a response code of 401. This response code is presented to the user on an
error page with a generic error message.

If you use JEE security to protect both the HTML file and EGL Rich UI Proxy, use
form-based authentication. When a user requests the HTML file, the login page
that is specified for form-based authentication is displayed. After users
authenticate, they can also access the proxy, bypassing the browser-provided
dialog.

If you want to protect sensitive parts of your application without securing the
entire Rich UI application, you can use custom security. You can combine
authentication for custom security with JEE authentication of the EGL Rich UI
Proxy in a process called EGL single sign-on. In EGL single sign-on, you use a
user-defined login screen to capture credentials that allow the end user to
authenticate to more than one resource, including the EGL Rich UI Proxy. To
prevent the user from seeing the browser-provided dialog, use EGL single sign-on.
Related concepts
“EGL single sign-on” on page 362
“Overview of Rich UI security” on page 352
“Securing a Rich UI application” on page 352
“Using Web container-managed (JEE) authentication” on page 357
Related tasks
“Defining URL patterns for Rich UI resources” on page 358
“Securing the HTML file by using form-based authentication” on page 359
“Removing access to the EGL Rich UI Proxy servlet”
“Securing EGL Web services by using basic authentication” on page 361

Removing access to the EGL Rich UI Proxy servlet


If your Rich UI application does not call Web SOAP or REST services, the EGL
Rich UI Proxy will not be used. In this case, you have three options:
1. Remove the EGL Rich UI Proxy servlet from the web.xml of your deployed
project so a third party cannot access it.
2. Use JEE basic authentication to secure the proxy.
3. Leave the proxy unsecured.

360 EGL Programmer’s Guide


Option 1 is the best option for EGL. It is simple and removes all security risks that
are related to the proxy, as described in EGL Rich UI Proxy. Option 2 is valid, but it
requires more work from the EGL developer or a security administrator. For
directions on how to use JEE basic authentication to secure the EGL Riche UI
Proxy, see JEE security example. If you choose Option 3, you leave the EGL Rich UI
Proxy vulnerable to security threats.

To remove access to the EGL Rich UI Proxy:


1. Double-click on the deployment descriptor (WebContent/WEB-INF/web.xml)
of your deployed Web project to open it with the Deployment Descriptor
Editor.
2. Click the Servlets tab.
3. In the Servlets and JSPs pane, click EGLRichUIProxy.
4. In the URL Mappings pane, select /___proxy->EGLRichUIProxy.
5. Click Remove.
6. Save your changes and exit the Deployment Descriptor Editor.

If you want to invoke Web services from your Rich UI application later, edit the
web.xml and add a servlet URL mapping into EGLRichUIProxy by using the URL
pattern /___proxy.
Related concepts
“Overview of Rich UI security” on page 352
“Securing a Rich UI application” on page 352
“Using Web container-managed (JEE) authentication” on page 357
Related tasks
“Defining URL patterns for Rich UI resources” on page 358
“Securing the HTML file by using form-based authentication” on page 359
“Securing the EGL Rich UI Proxy by using basic authentication” on page 359
“Securing EGL Web services by using basic authentication”

Securing EGL Web services by using basic authentication


You can use JEE security and basic authentication to secure EGL Web services that
are generated into an EGL Web project. If you are only securing services in your
project, specify ″BASIC″ as your authentication type.

To secure all EGL SOAP services in a Web project, in a security constraint in the
web.xml, specify a URL pattern of /services/*. You can replace the asterisk with a
specific name to secure a specific SOAP service. To secure a specific function in a
SOAP service, specify the service and function name, as in /services/
accountService/checkBalance.

To secure all EGL REST services in a Web project, in a security constraint in the
web.xml, specify a URL pattern of /restservices/*. You can replace the asterisk
with a specific name to secure a specific REST service. To secure a specific function
in a REST service, specify the service and function name, as in
/restservices/accountService/checkBalance.
Related concepts
“Overview of Rich UI security” on page 352
“Securing a Rich UI application” on page 352
“Using Web container-managed (JEE) authentication” on page 357
Related tasks

Overview of EGL Rich UI 361


“Defining URL patterns for Rich UI resources” on page 358
“Securing the HTML file by using form-based authentication” on page 359
“Securing the EGL Rich UI Proxy by using basic authentication” on page 359
“Removing access to the EGL Rich UI Proxy servlet” on page 360

Using application-managed (custom) authentication


If you do not want to use JEE authentication to secure your HTML file, you can
incorporate custom security into your Rich UI application. You must still use JEE
security to protect the EGL Rich UI Proxy and Web services.

When you use custom security, your Rich UI application must include a
user-defined login screen. To hide the password as it is being typed, use the
PasswordTextField widget in your Rich UI handler. Your Rich UI application can
require authentication to occur either at the beginning of the application or before
accessing a restricted area. You can integrate this form of security into the rest of
the application.

The first step in defining custom security is to determine which parts of the
application should be secured (that is, which parts can be accessed only after
logging in with a valid user id and password). Even if you are not using JEE
security protect to the HTML file, use JEE security to secure the EGL Rich UI
Proxy. This is an important factor to remember when you design your Rich UI
application. A design that uses EGL single sign-on will reduce the number of times
a user will have to authenticate.

When authenticating with custom security, use SSL to ensure that the user id and
password are secure during transmission between the browser and server. For an
introduction to SSL, see Overview of SSL.
Related concepts
“EGL single sign-on”
“Accessing user repositories” on page 364
“Adding a new user to a repository” on page 366
“Authentication summary” on page 367

EGL single sign-on


Combining application and proxy authentication

By using EGL single sign-on, you can combine the following aspects of security
into a single step: authentication to your application (protected by custom security)
and authentication to the EGL Rich UI Proxy (protected by JEE security). You can
also include authentication to Web services.

Although the user registries that you use for authentication to the application, EGL
Rich UI Proxy, and Web services do not need to be the same, the user ID and
password used during EGL single sign-on must exist in all the relevant user
registries to prevent an authentication error.

For EGL single sign-on, the Rich UI application must define a login screen that
contains a user ID field, password field, and command button, as in the following
example:
useridLabel TextLabel { text = "User ID:", width = 80 };
useridField TextField { width = 100 };
useridBox Box { children = [ useridLabel,
useridField ], margin = 3 };

362 EGL Programmer’s Guide


passwordLabel TextLabel { text = "Password:", width = 80 };
passwordField PasswordTextField { width = 100 };
passwordBox Box { children = [ passwordLabel,
passwordField ], margin = 3};
button Button { text = "Log in", onClick ::= authenticate };
ui Box { background = "blue",
children = [ useridBox, passwordBox, button ],
columns = 1, width = 200 };

Whenever a Web service is called, a request is sent to the EGL Rich UI Proxy.
Because the proxy is secured with JEE basic authentication, a user must log in
before accessing it. If a user has not logged in yet, a browser-provided login screen
that is similar to the example in ″Using basic authentication to secure the EGL Rich
UI Proxy″ will be displayed the first time a Web service is invoked.

With EGL single sign-on, when the user authenticates to the Rich UI application
using the user-defined login screen above, EGL passes those credentials (user ID
and password) to JEE security to use to authenticate to the proxy also. Therefore,
authenticating to the application is combined with authentication to the proxy in
one step. For EGL single sign-on to work, design the Rich UI application so that
the Web service for authentication to the application is invoked before any other
Web service. Doing so bypasses the browser-provided login dialog.

To implement EGL single sign-on, use the


ServiceLib.setProxyBasicAuthentication() system function to pass the user ID and
password to authenticate to the proxy. Before you call the service to log in to the
application, invoke this system function. The authenticate function for the EGL
code above might look like the following example:
function authenticate( e Event in )
ServiceLib.setProxyBasicAuthentication(useridField.text,passwordField.text );
srvc LDAPLoginService{ @bindService };
call srvc.login( useridField.text, passwordField.text )
returning to loginCallback onException loginException;
end

Adding Web service authentication

Typically, to authenticate to a secure Web service, a Rich UI application must


prompt the user for a user ID and password. However, you can pass the user ID
and password that you use for EGL single sign-on to a secure Web service. To do
so, invoke the ServiceLib.setHTTPBasicAuthentication() system function before
you call the secure Web service and pass it the user ID and password used for
EGL single sign-on.
function withdraw( e Event in )
ServiceLib.setHTTPBasicAuthentication(srvc, useridField.text,
passwordField.text );
srvc BankingService{ @bindService };
call srvc.withdraw( useridField.text, passwordField.text )
returning to withdrawCallback onException withdrawException;
end

Handling authentication errors

If you use EGL single sign-on to authenticate to your application and to the EGL
Rich UI Proxy, authentication to the proxy occurs before authentication to your
application. Because the EGL Rich UI Proxy is secured using JEE basic
authentication, the Web container, not the application, handles login failures.
Because the Web container steps in, you can no longer authenticate in a single step.

Overview of EGL Rich UI 363


At this point, the user must authenticate to the EGL Rich UI Proxy first, and log in
to the application, Web services, or both afterward.

If users enter an invalid password for EGL Rich UI Proxy authentication on the
login screen, a browser-provided login dialog is displayed so that they can try to
authenticate again. In JEE basic authentication, the Web container prompts the
browser to display this dialog until the user logs in successfully. The application
cannot access the password that a user enters on this dialog.

After users enter valid credentials for the EGL Rich UI Proxy, they must
authenticate to the application, Web services, or both. The application should direct
users to re-enter a valid user ID and password in the user-defined login screen and
to click the ″Login″ button again.

If an error occurs when users authenticate to a Web service that is secured with
HTTP basic authentication, control falls into the exception handler that is specified
on the call statement. Your Rich UI application must detect this error and present
appropriate instructions to the user to reauthenticate. The following example
shows the specifics of this kind of error:

Web service authentication error


Configuration
A Web service is secured using JEE basic authentication.
Problem
A valid user ID and password for the Web service are not found in the
HTTP header.
Error A ServiceInvocationException is thrown with message ID ″EGL1539E″ and
message, ″An exception occurred while communicating with the service.
URL: {0}″ is issued where {0} is the URL of the Web service. detail1 of the
ServiceInvocationException is set to ″401″; detail2 is set to ″Unauthorized″;
detail3 is set to ″Server returned HTTP response code: 401 for URL: {0}″,
″name″: ″egl.core.ServiceInvocationException″.
Solution
Call ServiceLib.setHTTPBasicAuthentication() to set a valid user ID and
password in the HTTP header before consuming the Web service.

If both EGL Rich UI Proxy and Web service authentication are successful but an
error occurs when you try to authenticate to your application, your Rich UI
application must handle the error. When the Web service returns, control passes to
the callback or ″returning to″ function that is specified on your call statement.
Related concepts
“Accessing user repositories”
“Adding a new user to a repository” on page 366
“Authentication summary” on page 367

Accessing user repositories


You can use various types of repositories, such as LDAP directories, relational
databases, and flat files with either JEE or custom security. You can use EGL
single-sign on to access different repositories to authenticate to the application,
proxy, and Web services. For single-sign on to succeed, the user id and password
that the end user enters in the login screen must exist in each of the various
repositories.

364 EGL Programmer’s Guide


The most popular type of repository is a Lightweight Directory Access Protocol
(LDAP) directory, which is a specialized database that is optimized for read access
and that organizes its data in a tree structure. Before you access an LDAP directory
for JEE authentication, configure the application server to connect to the LDAP
directory server. For WebSphere Application Server, specify this information in the
Administrative Console; for Apache Tomcat, specify this information in the
\conf\server.xml file.

You can also use EGL code that is generated into Java and running on a server to
access an LDAP directory. To use EGL code to access an LDAP directory, define
either an EGL REST or SOAP service. The service can use EGL external types that
map to JNDI LDAP Java classes to access an LDAP directory. Here is an example
of EGL code that establishes a connection to an LDAP directory server:
// External types needed to access an LDAP directory server.
externalType ControlArray type JavaObject
{ JavaName = "Control[]", PackageName = "javax.naming.ldap" }
end

externalType InitialDirContext type JavaObject


{ JavaName = "InitialDirContext",
PackageName = "javax.naming.directory" }
function modifyAttributes( name String in,
mods ModificationItemArray in );
end

externalType InitialLdapContext extends InitialDirContext type JavaObject


{ JavaName = "InitialLdapContext",
PackageName = "javax.naming.ldap" }
constructor( environment Hashtable in, connCtls ControlArray in );
end

externalType ModificationItemArray extends Object type JavaObject


{ JavaName = "ModificationItem[]",
PackageName = "javax.naming.directory" }
end

// Instantiate a hashtable for binding criteria.


// Hashtable is already defined within EGL.
hashtable Hashtable = new Hashtable();

// Properties can be found at


// http://java.sun.com/j2se/1.4.2/docs/guide/jndi/jndi-ldap.html.

// Set JNDI environment properties.


// userid and password are passed in as strings.
hashtable.put( "java.naming.factory.initial",
"com.sun.jndi.ldap.LdapCtxFactory" );
hashtable.put( "java.naming.provider.url",
"ldap://localhost:389/o=sample" );
hashtable.put( "java.naming.security.principal",
"uid=" + userid + ",ou=people,o=sample");
hashtable.put( "java.naming.security.credentials", password );
hashtable.put( "java.naming.security.authentication", "simple" );
hashtable.put( "java.naming.referral", "follow" );
hashtable.put( "java.naming.security.protocol", null );

// Set LDAP-specific properties.


hashtable.put( "java.naming.ldap.version", "3" );

// Connect to the LDAP directory server.


ctx InitialLdapContext = new InitialLdapContext( hashtable, null );

Overview of EGL Rich UI 365


if ( ctx != null )
// Retrieve data
...
end

For more sample EGL code, including code that retrieves and modifies data in an
LDAP directory, see ″EGL LDAP Access″ or ″J2EE Security with EGL LDAP
Access″ in the IBM Rational® Business Developer documentation (in the ″Contents″
under ″Samples″).
Related concepts
“EGL single sign-on” on page 362
“Adding a new user to a repository”
“Authentication summary” on page 367

Adding a new user to a repository


If your Rich UI application requires security, you have two options to give new
users permission to access the secure areas: a system or security administrator can
add a new user to the repository or the Rich UI application can contain code to
add a new user to the repository. The method that you choose depends largely on
the level of security that you need. For example, if the user must be a company
employee or must possess a bank account to access a Web site, a system
administrator likely wants to tightly control access to the repository. On the other
hand, if the repository is mainly a way to keep a log of users and new users
constantly request access, it might be inconvenient or impractical to go through a
system administrator. In this case, an application might add new users to the
repository.

Note that the tighter your user registry is controlled, the tighter the security will be
of your Rich UI application and EGL Rich UI Proxy. Although securing your EGL
Rich UI Proxy with JEE security prevents unauthenticated users from accessing the
proxy, it does not prevent malicious authenticated users from using the proxy to
inflict damage. Therefore, when you require new users to go through a system
administrator, the EGL Rich UI Proxy will be more secure than if you allow the
application to add new entries to the user registry.

If you must add new users to a repository with your Rich UI application, you can
write EGL code to add the users. This code must run on an application server. You
can write the code as either a Web service or a JSF application.

If you use a Web service to write the code to add a new user, the EGL Rich UI
Proxy has to invoke the code. If the proxy is secure, a new user cannot access it.
Therefore, you can use a Web service to add a new user only if the proxy is not
protected by JEE security.

If you use JEE security to secure the proxy, you can use a JSF application to add a
new user to the repository. To link to a JSF application in a new window to update
the repository, the Rich UI handler can use a hyperlink widget that is similar to the
following example:
registerLink Hyperlink = new Hyperlink { target = "_blank",
href = "http://localhost:9080/LDAPSample/ldapLogin.faces",
text = "Click here to register" };

To close the window after authentication completes, the JSF page can invoke a
JavaScript ″window.close″.
Related concepts

366 EGL Programmer’s Guide


“EGL single sign-on” on page 362
“Accessing user repositories” on page 364
“Authentication summary”

Authentication summary
During the design phase of your Rich UI application, determine the type of
security that you need and integrate that security with the rest of your application.
If your entire Rich UI application needs to be secured and you do not need to
access security credentials from within the application, consider using JEE
authentication. Otherwise, you might need to implement custom security.

To secure the EGL Rich UI Proxy, use JEE security. If you use JEE form-based
authentication for your HTML file, include the URL pattern of the proxy in your
security constraint. Otherwise, use JEE basic authentication to secure the proxy. If
your application requires custom security or calls secure Web services, consider
using EGL single sign-on to eliminate the need for a user to log in more than once.

You can secure Web services using by JEE basic authentication and set a user id
and password in the HTTP header before invoking them by using the
ServiceLib.setHTTPBasicAuthentication system function.

Use SSL, described in Overview of SSL, to secure data transmitted to and from your
Rich UI application. Securing data is vital to keeping your passwords from being
compromised.

The following table summarizes the combinations of resources that you can secure
with JEE or custom authentication. For each of the eight scenarios (columns), an
″X″ represents a secure resource. These scenarios assume that the HTML file is
calling Web services. Otherwise, remove access to the EGL Rich UI Proxy by
deleting its URL mapping from the deployment descriptor. The safer scenarios are
identified with an ″*″.
Table 53. Authentication scenario
1 2 3* 4 5* 6* 7 8*
HTML x x x x
file
EGL x x x x
Rich UI
Proxy
Web x x x x
service

Scenario descriptions
1. In this scenario, the proxy is publicly accessible. If possible, do not implement
this scenario. Secure the proxy with JEE basic authentication (scenario 3).
2. Although the HTML file is secured with either JEE or custom security, the
proxy is still publicly accessible. If possible, do not implement this scenario.
Secure the proxy with JEE authentication (scenario 5).
3. In this scenario, the proxy is secured with JEE basic authentication. This
scenario is safer than the first two.
4. In this scenario, the proxy is publicly accessible. If possible, do not implement
this scenario. Secure the proxy with JEE authentication (scenario 6).

Overview of EGL Rich UI 367


5. If Web service does not require security, this scenario can be safe. If both the
HTML file and proxy are secured with JEE security, use form-based
authentication to require the user to log in only once. If the HTML file is
secured with custom security and the credentials to log in to the HTML file
match those used to log in to the proxy, use EGL single sign-on to combine
application authentication with JEE authentication to the proxy.
6. Although the Rich UI application does not require authentication, a
user-defined login screen is required to obtain Web service credentials, which
should never be hardcoded into the application. If the credentials that are used
to log in to the Web service match those that are used to log in to the proxy,
use EGL single sign-on to combine Web service authentication with JEE basic
authentication to the proxy.
7. In this scenario, the proxy is publicly accessible. If possible, do not implement
this scenario. Secure the proxy with JEE authentication (scenario 8).
8. If both the HTML file and proxy are secured with JEE security, use form-based
authentication. A user-defined login screen is required in the application to
authenticate to the secure Web services. Thus, the user must log in twice. If the
credentials to authenticate to the HTML file, the proxy, and Web services match,
consider securing the HTML file with custom authentication. Then use EGL
single sign-on to capture credentials for all three types of resources.
Related concepts
“Securing a Rich UI application” on page 352
“Overview of Rich UI security” on page 352

Authorization
You can perform authorization through JEE security or through the application
itself. JEE security uses roles to manage access to resources. A logical security role
has permission to access certain resources. Actual users and groups who are
mapped to that logical role can access those resources. The web.xml deployment
descriptor specifies the type of access that is granted to each role. For WebSphere
Application Server, roles are bound to users and groups in the application.xml. For
Apache Tomcat, the binding occurs in a repository such as the tomcat-users.xml
file, LDAP directory, or relational database.

Although you can check authorization in a JSF application by calling the


J2EELib.isUserInRole and J2EELib.getRemoteUser EGL system functions, these
system functions are not available from a Rich UI application in V7.5.1 because the
JEE security that is used from a Rich UI application must be declarative.

If JEE authorization is not suitable for your Rich UI application, perhaps because
programmatic security is unavailable or the overhead of administering JEE security
roles is too high, authorization can be accomplished using your own application
code. One way to implement authorization is to organize user entries into groups
in a repository like an LDAP directory. You can then invoke a Web service from
your Rich UI application to retrieve an entry from the repository and check if a
user is in a group that has access a certain resource.

For details concerning authorization, see your WebSphere Application Server,


Apache Tomcat, or LDAP directory server documentation.

368 EGL Programmer’s Guide


Related information
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
“Resources to secure” on page 355

JEE security example


The following example shows how to use JEE basic authentication to secure an
EGL Rich UI Proxy in a Web project to which a Rich UI application has been
deployed.

For WebSphere Application Server, perform the following steps:


1. In the web.xml, specify security criteria
2. In the application.xml, specify security criteria
3. Use the Administrative Console to enable security
4. Enable security in the server configuration

For Apache Tomcat, perform the following steps:


1. In the web.xml, specify security criteria
2. In tomcat-users.xml, bind roles to users and groups
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
Related tasks
“Specifying security criteria in web.xml”
“Specifying security criteria in application.xml for WebSphere” on page 371
“Enabling security by using the Administrative Console for WebSphere” on
page 372
“Binding roles to users and groups in tomcat-users.xml” on page 373

Specifying security criteria in web.xml


You can specify security criteria in the deployment descriptor of your deployed
project (web.xml) in two ways:
v By using the Security Editor.
v By editing the web.xml in the Deployment Descriptor Editor.

The Security Editor is used in this example because it provides an easy way to
specify and view security criteria.

Using the Security Editor

You can use the Security Editor to define the following things in web.xml:
v Security roles
v Security constraints
v Authentication method

From the Project Explorer in the EGL Rich UI perspective, open the Security Editor
by double-clicking on the Security Editor icon of your deployed project.

Overview of EGL Rich UI 369


Defining security roles

In JEE role-based security, users must be assigned roles to access resources. Roles
are mapped to actual user registry entries.
v In the Create a Security Role dialog, click OK.
v In the Add Roles window, type user as the role name and click Add.
v Click Finish.

Defining security constraints

To specify the resources that are protected and the roles that have access to the
resources, define a security constraint.
1. In the Resources pane, expand the folder with your project name, Servlets,
EGLRichUIProxy, and Servlet Mappings. Under Servlet Mappings, you should
see /___proxy.
2. To secure the proxy and allow anyone in the user role to access the proxy, drag
the user role from the Security Roles pane to /___proxy in the Resources pane.
3. To see the security constraints, in the Resources pane, right click on /___proxy
(user) and click Assign Roles. In the Select Roles window, select user and click
Advanced>>>. You should see the userConstraint security constraint that is
mapped to user, which specifies how you can access the /___proxy secure
resource. The userConstraint security constraint contains the default HTTP
method access (GET, PUT, HEAD, TRACE, POST, DELETE, OPTIONS). Click
OK. To change the defaults for your security constraints, in the Security Editor,
click Security Preferences.

Selecting an authentication method

To specify an authentication method:


1. Click Authentication.
2. For the authentication method, click BASIC.
3. To name the example, type Sample registry.
4. Click OK.
5. Save your changes and close the Security Editor.

Defining a user data constraint

A user data constraint specifies how data is protected while it is in transit between
a client and server. If you do not want to use the default user data constraint
(NONE), you must specify the user data constraint directly into the web.xml
because that information is not available from the Security Editor.

You can set a user data constraint to a value of NONE, INTEGRAL, or


CONFIDENTIAL. An INTEGRAL value guarantees content integrity, preventing
tampering of messages in transit between a client and server. A CONFIDENTIAL
setting guarantees confidentiality, preventing reading of data by others during the
transfer. If you use a value of INTEGRAL or CONFIDENTIAL, requests must be
submitted over SSL.

To specify a user data constraint in the web.xml:


v From the EGL Rich UI perspective, open the deployment descriptor of your
deployed project by double-clicking on the deployment descriptor.
v Select the Security tab.

370 EGL Programmer’s Guide


v Under Security Constraints, click userConstraint.
v To require that requests be submitted over SSL, under User Data Constraint,
select INTEGRAL or CONFIDENTIAL.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
Related tasks
“Specifying security criteria in application.xml for WebSphere”
“Enabling security by using the Administrative Console for WebSphere” on
page 372
“Binding roles to users and groups in tomcat-users.xml” on page 373

Specifying security criteria in application.xml for WebSphere


When you use WebSphere Application Server, you can specify security criteria in
the deployment descriptor of your Enterprise Application project (application.xml)
in two ways:
v By using the Security Editor
v By editing application.xml

The Security Editor is used in the following example because it provides an easy
way to specify and view security criteria.

Using the Security Editor

To bind the roles that are defined in your web.xml to actual users and groups in
your user registry, use the Security Editor. This binding information is stored in the
deployment descriptor of your Enterprise Application project (application.xml).

To open the Security Editor from the Project Explorer in the EGL Rich UI
perspective, double-click on the Security Editor icon of your deployed project.

Defining security role bindings

To define security role bindings:


1. Click Role Mapping.
2. In the WAS Specific Role Mappings window, click user.
3. Click Map User.
4. In the Map User window, click All Authenticated Users.
5. Click OK.
6. In the WAS Specific Role Mappings window, click OK.
7. Save your changes and close the Security Editor.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
Related tasks
“Specifying security criteria in web.xml” on page 369
“Enabling security by using the Administrative Console for WebSphere” on
page 372

Overview of EGL Rich UI 371


“Binding roles to users and groups in tomcat-users.xml” on page 373

Enabling security by using the Administrative Console for


WebSphere
To enable application and administrative security:
1. From the Servers view in the Workbench, start a WebSphere V6.1 or V7.0
server.
2. Right click on the server, click Administration → Run administrative console, .
3. When you are prompted, type a user id. Because administrative security is not
yet enabled, the user id is not really used.
4. In the Administrative Console, take the following steps:
a. Expand Security.
b. For WebSphere V6.1, select Secure administration, applications, and
infrastructure.
c. For WebSphere V7.0, select Global security.
d. From the Available realm definitions, select the type of user registry to use.
In this example, use Local operating system.
e. Click Set as current.
f. Click Configure. The configuration page for the realm opens.
g. Enter the properties. Note the Primary administrative user name, which you
must also enter in the User ID field of the server configuration that is
described in the next section. For Local operating system, type the user id
that you use to log in to your operating system.
h. Click OK to return to Secure administration, applications, and infrastructure
for WebSphere V6.1 or Global security for WebSphere V7.0.
i. Click Enable administrative security, which also selects Enable application
security.
j. Clear the Use Java 2 security to restrict access to local resources checkbox.
k. Click Apply → Save.
l. Exit the Administrative Console and stop the server. Before you start the
server again, follow the instructions in ″Enable security in the server
configuration for WebSphere.″
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
Related tasks
“Specifying security criteria in web.xml” on page 369
“Specifying security criteria in application.xml for WebSphere” on page 371
“Binding roles to users and groups in tomcat-users.xml” on page 373

Enabling security in the server configuration for WebSphere


To enable security in the server configuration:
1. To open your WebSphere Application Server V6.1 or V7.0 server in the Servers
view, double click WebSphere Application Server V6.1 or V7.0.
2. For WebSphere V6.1, under the Server section, select SOAP as the server
connection type.
3. For WebSphere V7.0, under the Server section, click Manually provide
connection settings and select SOAP as the server connection type.

372 EGL Programmer’s Guide


4. Under the Security section, click Security is enabled on this server. Type the
user ID and password that you set in your Administrative Console. The User
ID field should match the Primary administrative user name field in the
Configuration page of your realm in the Administrative Console. For this
example, type the password that you use to log in to your operating system.
5. Save your changes and exit the server configuration.
6. Start the server. If an authentication error occurs, ensure that the user id and
password in your server configuration match those that you used to log in to
your operating system.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
Related tasks
“Specifying security criteria in web.xml” on page 369
“Specifying security criteria in application.xml for WebSphere” on page 371
“Enabling security by using the Administrative Console for WebSphere” on
page 372
“Binding roles to users and groups in tomcat-users.xml”

Binding roles to users and groups in tomcat-users.xml


When you use Apache Tomcat V5.5 or V6.0, the user repository in a production
environment is typically an LDAP directory or relational database, but by default
is the tomcat-users.xml file. In the tomcat-users.xml file, which is located in the
<tomcat-users>
<user name="bob" password="guesswhat" roles="user"/>
</tomcat-users>
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
Related tasks
“Specifying security criteria in web.xml” on page 369
“Specifying security criteria in application.xml for WebSphere” on page 371
“Enabling security by using the Administrative Console for WebSphere” on
page 372

Running a Rich UI application with a secure proxy


When a Web service is invoked from a Rich UI application, a request for that Web
service is sent to the EGL Rich UI Proxy. Before you can access the proxy, you
must enter a valid user id and password into a browser-specific dialog, such as the
following dialog for Mozilla Firefox V2.0. For this example, the user id and
password that you use to log in to your operating system are also used to
authenticate to the EGL Rich UI Proxy.

Overview of EGL Rich UI 373


You can use EGL single sign-on to combine custom authentication to your
application with JEE authentication to the EGL Rich UI Proxy and bypass this
dialog.
Related concepts
“EGL single sign-on” on page 362

WebSphere Application Server hints and tips: If you want to turn off
administrative security but cannot start the server to run the Administrative
Console, you can turn off administrative security from the command line:
1. Go to the WebSphere Application Server install directory.
2. Type bin\wsadmin.bat –conntype NONE
3. When the system prompt redisplays, type securityoff.
4. When you are finished, type quit.

After turning off administrative security, clear the Security is enabled on this
server checkbox in the server configuration before restarting the server.

When testing your Rich UI application, after authenticating with JEE security, if
you make a change to your application or configuration and want to retest
authentication, you might have to stop the server and exit the Workbench in order
to clear all saved values. For Windows®, before you restart, use the Task Manager
to ensure the java.exe process for the server has finished.

If you have trouble starting your server with administrative security enabled, make
sure you specified SOAP as your server connection type in your WebSphere server
configuration.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355

Sample login and error pages for JEE form-based


authentication
In JEE form-based authentication, you can specify a customized login page and an
error page. The login page, which prompts the user to enter a user id and

374 EGL Programmer’s Guide


password, refers to a special j_security_check servlet. Two HTTP request
parameters (form input fields) must always be in the request, one called
j_username and the other, j_password.

When the Web container receives a request for the j_security_check servlet, it
passes the request to the security mechanism of WebSphere Application Server to
perform the authentication. If authentication fails, the error page is displayed.
Below is code for a sample login page. Copy and save this code in login.jsp under
the WebContent folder.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Sample Login Page for JEE Security</title>
<style type="text/css">H1 {color: navy}</style>
</head>
<body>
<table width="500" border="0">
<tbody>
<tr>
<td colspan="3" width="80%" align="center"><b><font face="Verdana"size="+2"
color="#15406a">Sample Login</font></b><hr>
</td>
</tr>
<tr>
<td colspan="3" width="560" height="65">
<form method="POST" action="j_security_check">
<div>
<table width="100%" border="1" bgcolor="#e9e9e9">
<tbody>
<tr>
<td align="right" width="169"
bgcolor="#e9e9e9"><b>
<font face="Verdana">User id:</font></b></td>
<td width="315"><input type="text" name="j_username"></td>
</tr>
<tr>
<td align="right" width="169" bgcolor="#e9e9e9">
<font face="Verdana"><b>Password:</b></font></td>
<td width="315"><input type="password" name="j_password"></td>
</tr>
<tr bgcolor="white">
<td align="right" width="169" bgcolor="white"></td>
<td width="315"><input type="submit" value="Login"></td>
</tr>
</tbody>
</table>
</div>
</form></td>
</tr>
<tr>
<td colspan="3" width="560" align="center" height="58" valign="top">
<script> document.write(Date()+".")
</script>
</td>
</tr>
</tbody>
</table></body>
</html>

Overview of EGL Rich UI 375


The following code is for a sample error page. Copy and save this code in error.jsp
under the WebContent folder.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Sample Error Page for JEE Security</title>
<style type="text/css">H1 {color: navy}</style>
</head>
<body>
<table width="500" border="0">
<tbody>
<tr>
<td colspan="3" width="80%" align="center"><b><font face="Verdana" size="+2"
color="#15406a">Sample Login Error</font></b><hr>
</td>
</tr>
<tr>
<td colspan="3" width="560" align="center" height="58"
valign="top"><br>Authentication error.
Please check your user id and password, and try again.</td>
</tr>
</tbody>
</table></body>
</html>
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
“Using Web container-managed (JEE) authentication” on page 357

Preventing client-side security threats


Unfortunately, the technologies that provide a richer interactive experience can also
make applications less secure. Rich UI applications are susceptible to the security
vulnerabilities that threaten any Web 2.0 applications including cross-site scripting,
SQL injection, and JavaScript hijacking.

When you use EGL, you are protected from some of these client-side threats. For
example, EGL prevents malicious data being sent to the client using either
JavaScript Object Notation (JSON) or XML. It also guards its usage of ″eval″ in
runtime code. However, it is very difficult for EGL to defend against certain types
of attacks like cross-site scripting and SQL injection without limiting the types of
applications customers can write.

You can prevent unauthenticated clients from calling the proxy and reduce the
possibility of proxy misuse by securing the EGL Rich UI Proxy with JEE security.
However, securing the proxy with JEE security does not prevent authenticated
users from using the proxy for unintended purposes. The more tightly your user
registry is controlled, the safer your proxy will be. Therefore, for security reasons, a
system administrator should control the access of your user registry.

You can keep a log of the end users who have accessed your Rich UI application if
you are using your own login screen, rather than one supplied through JEE
form-based authentication or the browser-provided login dialog from JEE basic
authentication. (In your Rich UI application, you cannot retrieve user ids from the

376 EGL Programmer’s Guide


application server if you are using JEE security.) This log could help you determine
the guilty party if an authenticated user is illegally using your EGL Rich UI Proxy
for anything from calling Web services on other domains to instigating JavaScript
hijacking attacks. Also check the documentation of your application server to see if
it maintains logs that might be of help to you.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355

Overview of SSL
Secure Sockets Layer (SSL) ensures data integrity and confidentiality, and is used
extensively for securing communications. SSL is a protocol that runs above TCP/IP
and below higher-level application protocols such as HTTP and LDAP.

To initiate an HTTP-based SSL connection, the client uses a URL that starts with
HTTPS:// instead of with HTTP://. Always use an SSL-enabled port with the
HTTPS protocol.

In SSL, a server authenticates itself to the client, and the client optionally
authenticates itself to the server, insuring against imposters. By using SSL, you can
prevent the interception and tampering of messages and provide confidentiality
through encryption.

Although much of the SSL material in these topics applies to both WebSphere and
Tomcat, SSL example focuses solely on WebSphere Application Server. For
instructions on how to install and configure SSL for Tomcat, see Apache Tomcat
documentation
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
“SSL transport between WebSphere Application Server and LDAP” on page 386
“How SSL works” on page 380
Related tasks
“Using SSL with Rich UI applications”
“Preventing SSL handshaking exceptions” on page 385
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
“SSL-related errors” on page 378
“SSL terminology” on page 380
“SSL example” on page 381

Using SSL with Rich UI applications


When the HTML file that EGL generates for your Rich UI application is requested,
a connection is made between the browser and the server to which your Rich UI
application (including the EGL Rich UI Proxy) was deployed. Whenever a Web
service is invoked in your Rich UI application, the EGL Rich UI Proxy creates a

Overview of EGL Rich UI 377


new connection between its server and the one on which the Web service is
deployed. These connections are independent of one another and can use different
protocols.

Requesting an HTML file with the SSL protocol (HTTPS) results in an SSL
connection between the browser and server. If you use JEE authentication to secure
an HTML file or the EGL Rich UI Proxy, require SSL to protect the user id and
password from eavesdroppers as they are transmitted between the browser and
server. When you use JEE authentication, to require SSL for the request, set the
user data constraint in the web.xml to INTEGRAL or CONFIDENTIAL.

When you use custom authentication, you have various options to require HTTPS
for the HTML file request. For instance, you can configure your Web server to
redirect all HTTP requests to HTTPS. To redirect a specific HTML request, consider
purchasing or writing a Java redirect filter, which you can specify on the Filters tab
of your web.xml. You can use these filters to redirect certain HTTP requests to their
HTTPS equivalent.

When a Web service is invoked with the SSL protocol, the EGL Rich UI Proxy
creates a new SSL-enabled connection between its server and the one on which the
Web service is deployed. When you secure Web services with HTTP basic
authentication, require SSL to protect the user id and password during
transmission. To require SSL for the request, set the user data constraint in
theweb.xml of the Web service project to INTEGRAL or CONFIDENTIAL. After
you require SSL, invoke the Web service by using the HTTPS protocol.

When you invoke a secure Web service with SSL, ensure that the Rich UI
application also uses the SSL protocol to protect the user id and password in the
channel between the browser and server.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
“Overview of SSL” on page 377
“SSL transport between WebSphere Application Server and LDAP” on page 386
“How SSL works” on page 380
Related tasks
“Preventing SSL handshaking exceptions” on page 385
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
“SSL-related errors”
“SSL terminology” on page 380
“SSL example” on page 381

SSL-related errors
If the EGL Rich UI Proxy or Web service requires SSL, but HTTPS is not used on
the request, you might see the following errors:

Proxy
Configuration

378 EGL Programmer’s Guide


The EGL Rich UI Proxy is secured by using JEE basic authentication and
includes a CONFIDENTIAL or INTEGRAL user data constraint.
Problem
HTTP is used to request the proxy instead of HTTPS. (Because of the Same
Origin policy for JavaScript, the protocol that is used to request the HTML
file is the protocol that is used to request the proxy. The same is true for
the domain name and port number.)
Errors
A ServiceInvocationException is thrown with messageID ″CRRUI3658E″
and the message, ″An error occurred on proxy at ‘{0}’ while trying to
invoke service on ‘{1}’″ where {0} is the URL of the proxy and {1} is the
URL of the Web service. detail1 of the ServiceInvocationException is set to
″302″; detail2 is set to ″Found″.
A ServiceInvocationException is thrown with messageID ″EGL1546E″ and
the message, ″The request could not be converted to a service call. The
received request was ’’.″
Solution
Request the HTML file with HTTPS instead of HTTP.

Web service
Configuration
A Web service is secured by using JEE basic authentication and includes a
CONFIDENTIAL or INTEGRAL user data constraint.
Problem
HTTP is used to request the Web service instead of HTTPS.
Error A ServiceInvocationException is thrown with messageID ″CRRUI3655E″
and the message, ″An error occurred while processing response object:
‘ReferenceError: urlString is not defined’″. detail1 of the
ServiceInvocationException is set to ″302″; detail2 is set to ″Found″.
Solution
Request the Web service with HTTPS instead of HTTP.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
“Overview of SSL” on page 377
“SSL transport between WebSphere Application Server and LDAP” on page 386
“How SSL works” on page 380
Related tasks
“Using SSL with Rich UI applications” on page 377
“Preventing SSL handshaking exceptions” on page 385
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
“SSL terminology” on page 380
“SSL example” on page 381

Overview of EGL Rich UI 379


SSL terminology
A key store is a file that contains public and private keys. Public keys are stored as
signer certificates and are sent to the clients that request them. Private keys are
stored in the personal certificates and are never sent to others.

A trust store is a file that contains public keys, which are stored as signer
certificates from target servers whom you have deemed trustworthy. If the target
uses a self-signed certificate, extract the public certificate from the server key store
and add the extracted certificate into the trust store as a signer certificate.
Otherwise, add the CA root certificate to your trust store.

A certificate is sent from the server to the client during SSL authentication to
confirm the identity of the server. Certificates contain data such as the owner’s
name and email address, duration of validity, web site address, and certificate ID
of the person who certifies or signs this information. Trusted parties called
Certificate Authorities (CAs) issue digital certificates. For internal Web sites that do
not need a CA certificate, you can use WebSphere Application Server to create
self-signed certificates.

In SSL server authentication, the client prompts the server to prove its identity. The
opposite occurs in client authentication, which is also supported through SSL, but
not covered here. Client authentication is used when the server needs to send
confidential financial information to a customer but wants to verify the identity of
the recipient first.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
“Overview of SSL” on page 377
“SSL transport between WebSphere Application Server and LDAP” on page 386
“How SSL works”
Related tasks
“Using SSL with Rich UI applications” on page 377
“Preventing SSL handshaking exceptions” on page 385
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
“SSL-related errors” on page 378
“SSL example” on page 381

How SSL works


SSL uses both symmetric and asymmetric encryption algorithms. Symmetric
algorithms use the same key to encrypt and decrypt data. They are faster than
asymmetric algorithms but can be insecure. Asymmetric algorithms use a pair of
keys. Data encrypted using one key can only be decrypted using the other.
Typically, one of the keys is kept private while the other is made public. Because
one key is always kept private, asymmetric algorithms are generally secure;
however, they are much slower than symmetric algorithms. To reap the benefits of
both algorithms, SSL encapsulates a symmetric key that is randomly selected each
time inside a message that is encrypted with an asymmetric algorithm. After both
the client and server possess the symmetric key, the symmetric key is used instead
of the asymmetric ones.

380 EGL Programmer’s Guide


When server authentication is requested, SSL uses the following process:
1. To request a secure page, a uses HTTPS.
2. The server sends the client its public key and certificate.
3. The client checks that the certificate was issued by a trusted party (usually a
trusted Certificate Authority) that the certificate is still valid, and that the
certificate is related to the contacted site.
4. The client uses the public key to encrypt a random symmetric encryption key
and sends it to the server, along with the encrypted URL required and other
encrypted HTTP data.
5. The server decrypts the symmetric encryption key using its private key and
uses the symmetric key to decrypt the URL and HTTP data.
6. The server sends back the requested HTML document and HTTP data that are
encrypted with the symmetric key.
7. The client decrypts the HTTP data and HTML document using the symmetric
key and displays the information.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
“Overview of SSL” on page 377
“SSL transport between WebSphere Application Server and LDAP” on page 386
Related tasks
“Using SSL with Rich UI applications” on page 377
“Preventing SSL handshaking exceptions” on page 385
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
“SSL-related errors” on page 378
“SSL terminology” on page 380
“SSL example”

SSL example
The following example illustrates how to use WebSphere V6.1 or V7.0 to create and
use your own SSL-enabled port. Before WebSphere Application Server V6.1 was
released, certificates were managed through the use of an external tool called
iKeyman. As of WebSphere Application Server V6.1, you can use the
Administrative Console to manage both certificates and keys. Although you can
use WebSphere V6.0 with SSL to run Rich UI applications, the instructions for
doing so are not included here. The differences between V6.1 and V7.0 are
described below.

For instructions on how to install and configure SSL for Tomcat, see Apache
Tomcat documentation.

Create an SSL-enabled port

To create a sample SSL-enabled port, take the following steps. For more details, see
your WebSphere Application Server documentation.

Overview of EGL Rich UI 381


Changing your key store and trust store passwords

In the following procedure, you create a new self-signed certificate in your


WebSphere Application Server default key store and import the certificate into
your default trust store. Before you use the default key and trust stores, change
their passwords from the defaults to another value to create a more secure
environment. To change your key store and trust store passwords:
1. Start your WebSphere V6.1 or V7.0 server
2. Right click on the server and click Administration.
3. Click Run administrative console.
4. Log in to the Administrative Console.
5. Expand Security and click SSL certificate and key management.
6. Under Related Items, click Key stores and certificates.
7. For WebSphere V6.1, click NodeDefaultKeyStore.
8. For WebSphere V7.0, click NodeDefaultKeyStore. Click Change password.
9. Type your new password into the Change password and Confirm password
fields.
10. Click OK.
11. Repeat this process for NodeDefaultTrustStore.

Creating a personal certificate

A self-signed certificate is useful when you are testing or when your Web site is
behind a firewall. Otherwise, obtain a certificate from a Certificate Authority. To
create a personal certificate:
1. From your list of key stores and trust stores, click NodeDefaultKeyStore.
2. Under Additional Properties, click Personal certificates.
3. For WebSphere V6.1, click Create a self-signed certificate.
4. For WebSphere V7.0, click Create → Self-signed certificate.
5. Type the following values for the certificate:
Alias
SampleCert
Common name
Sample Server
Organization
IBM
6. Click OK.

In the list of certificates, you should now see samplecert.

Creating an SSL configuration

WebSphere Application Server uses SSL configurations for SSL-based transports. To


create an SSL configuration:
1. From the left-hand pane, expand Security and click SSL certificates and key
management.
2. Under Related Items, click SSL configurations.
3. Click New.
4. Type the following values:

382 EGL Programmer’s Guide


Name
SampleConfig
Trust store name
NodeDefaultTrustStore
Keystore name
NodeDefaultKeyStore
5. Click Get certificate aliases.
6. Ensure that samplecert is selected as the Default server certificate alias and the
Default client certificate alias.

Click OK, and click Save. In the list of SSL configurations, you should see
SampleConfig.

Creating a Web container transport chain

Create a Web container transport chain to use the SSL configuration that you
created:
1. For WebSphere V6.1, from the left-hand pane, expand Servers and click
Application servers.
2. For WebSphere V7.0, from the left-hand pane, expand Servers and Server
Types. Click WebSphere application servers.
3. Click server1 or your server name.
4. Under Container Settings, expand Web Container Settings and click Web
container transport chains.
5. Click New.
6. In the Transport chain name field, type SampleInboundSecure.
7. To select the Transport chain template, from the drop-down list, click
WebContainer-Secure(templates/chains | webcontainer-chains.xml#Chain_2).
8. Click Next.
9. In the Select a port page, type the following values:
Port
SamplePort
Host
*
Port number
9444
If port 9444 is already in use, pick another port number and use that
number for the rest of the exercise.
10. Click Next.
11. Click Finish → Save.

SampleInboundSecure is now listed as a Web container transport chain. Associate


the sample SSL configuration with this transport chain:
1. Click SampleInboundSecure.
2. Click SSL inbound channel.
3. Under SSL Configuration, from the Select SSL Configuration drop-down list,
select SampleConfig .
4. Click OK → Save.

Overview of EGL Rich UI 383


Adding the SSL-enabled port to the virtual host

Add port 9444 to the virtual host:


1. In the left-hand pane, expand Environment and click Virtual Hosts .
2. Click default_host.
3. Under Additional Properties, click Host Aliases.
4. On the Host Aliases page, click New.
5. Keep * as the host name. Change the port to 9444.
6. OK → Save. In the list of ports, you should see 9444.

Stop and restart the server. Port 9444 is now an SSL-enabled port.

Using the new SSL-enabled port to run a sample

To use your port, start a WebSphere V6.1 or V7.0 server. On your WebSphere
server, install the EAR that contains your deployed Rich UI application. To request
an HTML file such as RSSReader.html in the RSSReaderSample context, take one of
the following steps:
v Open a browser such as Internet Explorer, Safari®, or Mozilla Firefox. Enter a
URL in your browser using the newly-enabled SSL port: https://localhost:9444/
RSSReaderSample/RSSReader.html
v In your Project Explorer, right-click on an HTML file of an application that has
been published to WebSphere. Click Run As, then click Run on Server.

If you are using a self-signed certificate, you might see a ″Security Alert″, ″Website
Certified by an Unknown Authority″, or another warning, depending upon the
browser. This warning indicates that the certificate was signed by an unknown
certifying authority. Click the ″View Certificate″ or ″Examine Certificate″ button to
verify if the certificate is correct. If so, continue.

If the Common Name on the certificate does not match the domain name in the
requested URL (localhost, in this case), you might also see a ″Security Error:
Domain Name Mismatch″ error. To verify the certificate, click the View Certificate
button, and continue as appropriate. To prevent ″man-in-the-middle″ attacks,
where a rogue program intercepts all communication between a client and server,
the client must verify the server domain name that is specified in the certificate.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
“Overview of SSL” on page 377
“SSL transport between WebSphere Application Server and LDAP” on page 386
“How SSL works” on page 380
Related tasks
“Using SSL with Rich UI applications” on page 377
“Preventing SSL handshaking exceptions” on page 385
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
“SSL-related errors” on page 378

384 EGL Programmer’s Guide


“SSL terminology” on page 380

Preventing SSL handshaking exceptions


To prevent SSL handshaking exceptions, ensure that the certificate of a server can
be found in the trust store of a client. If the certificate is not found in the trust
store and the client is a browser, a security alert dialog is displayed. A user can use
the dialog to view the certificate and select whether to proceed.

When a Web service is invoked from a Rich UI application, the EGL Rich UI Proxy
establishes a HTTP or HTTPS connection between the proxy and Web service. This
connection is independent of the connection between the browser and proxy. If the
Web service has an HTTPS protocol, the connection between the proxy and Web
service uses SSL. Because no browser is available to display a security alert and
prompt for a response, the certificate that belongs to the server of the Web service
must be in the trust store of the server of the EGL Rich UI Proxy before the
connection is initiated. Otherwise a handshaking error occurs.

To obtain a copy of the server’s certificate when calling a third-party Web service,
enter the URL of the Web service in a browser over HTTPS. The way in which you
receive the certificate of the server varies depending on the browser. A common
way is through a ″View Certificate″ button, Details tab, and ″Copy to File″ button.
Save the certificate to a file. Use the Administrative Console to open the trust store
of your EGL Rich UI Proxy and import the saved certificate as a signer certificate.

Alternatively, you can connect to the remote SSL host and port and receive the
signer certificate during the handshake by using the ″Retrieve from port″ option. If
you try to use the SSL-enabled port 9444 you created in ″SSL Example″ to request
a Web service called from an HTML file requested on the WebSphere default SSL
port 9443, you a handshaking error occurs. To fix this problem, import the
certificate that is associated with port 9444 into the trust store that is associated
with port 9443:
1. Start the WebSphere V6.1 or V7.0 server that contains your EGL Rich UI
Proxy. The proxy is deployed to the same location as the generated HTML file
of your Rich UI application.
2. Right click the server. Click Administration → Run administrative console.
3. Log in to the Administrative Console.
4. Expand Security and click SSL certificates and key management.
5. Under Related Items, click Key stores and certificates.
6. Click the appropriate trust store.
7. Click Signer certificates.
8. Click Retrieve from port.
9. Specify the following values:
Host
localhost
Port
9444
SSL configuration for outbound connection
NodeDefaultSSLSettings
Keystore name
SampleCert
10. Click Retrieve signer information → OK.

Overview of EGL Rich UI 385


Restart the server. You should now be able to request a Web service on port 9444
from port 9443 without receiving a handshaking error.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
“Overview of SSL” on page 377
“SSL transport between WebSphere Application Server and LDAP”
“How SSL works” on page 380
Related tasks
“Using SSL with Rich UI applications” on page 377
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
“SSL-related errors” on page 378
“SSL terminology” on page 380
“SSL example” on page 381

SSL transport between WebSphere Application Server and LDAP


If you use an LDAP directory as your registry, WebSphere Application Server
verifies the password of a user by using the standard ldap_bind, which requires
sending the password to the LDAP directory server. A password can flow in clear
text when you use a non-SSL channel between WebSphere and the LDAP directory
server. To use SSL, create a certificate for the LDAP directory and import it into the
trust store of your server. Also enable SSL on your LDAP directory server. For
more details, see LDAP directory server and application server documentation.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
“Overview of SSL” on page 377
“How SSL works” on page 380
Related tasks
“Using SSL with Rich UI applications” on page 377
“Preventing SSL handshaking exceptions” on page 385
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
“SSL-related errors” on page 378
“SSL terminology” on page 380
“SSL example” on page 381

IBM Rational AppScan


IBM Rational AppScan® is a Web application security assessment suite that you can
use to identify and fix common Web application vulnerabilities. Use Rational
AppScan to scan and test the code that EGL generates for your EGL Rich UI
application to pinpoint any critical areas that are susceptible to a Web attack. For
more information on the Rational AppScan product line, see http://www-
306.ibm.com/software/rational/offerings/websecurity/webappsecurity.html.
386 EGL Programmer’s Guide
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355

Overview of EGL Rich UI 387


388 EGL Programmer’s Guide
Building EGL JSF Web applications
In an EGL JSF Web application, EGL logic parts control Web pages, enabling you to
put data on Web pages, get data from user input on Web pages, and forward users
from page to page.

EGL also supports two other ways to write code for Web browsers:
v Rich UI applications
v Web transactions, which are available for compatibility with previous versions of
EGL
Related concepts
“Elements of a JSF Web application”
The main elements of an EGL Web application are the Web pages themselves
and JSF Handlers, which are logic parts that control the Web pages.
“Binding JSF controls to EGL variables and functions” on page 394
When you have a JSP file and an associated JSF Handler part, you can begin
developing the Web page’s behavior. This means binding, or connecting,
elements on the Web page to variables and functions in the JSF Handler.
“Overview of EGL Rich UI” on page 327
Related reference
“Working with Web transaction applications in EGL” on page 561
Related reference
Web pages with JavaServer Faces

Elements of a JSF Web application


The main elements of an EGL Web application are the Web pages themselves and
JSF Handlers, which are logic parts that control the Web pages.

JSF Handler part

A JSF Handler part, also called a JSF Handler, is a logic part that is customized to
control a Web page at run time. In prior versions of EGL, JSF Handlers were
PageHandler parts and referred to generally as page handlers.

Like other types of logic part, JSF Handler parts can contain any number of
user-defined functions. You might use functions in a JSF Handler to validate or
change the data that a user types into a Web page, to assign values to fields in a
Web page, to respond to a user’s actions on the page, or to forward the user or
data to a different page. However, it is best to keep JSF Handlers as simple as
possible and to use libraries or services for complicated business logic, because
functions in a JSFHandler part behave as though they are private and are not
available to other EGL logic parts or other JSF Handlers.

JSF Handler parts also contain specialized functions that run automatically at
certain points in the life of a Web page. For more information, see “Executing
commands when a page loads” on page 411.

You can also make variables and functions that are defined in the JSF Handler
available to the Web page. In this case, you bind the variable to an input or output

© Copyright IBM Corp. 1996, 2008 389


component on the page, or bind the function to a command button. When a
variable is bound to a component on the page and the user changes the value in
the component, the value of the variable changes to match, and if the logic in the
JSF Handler changes the value of the variable, the value on the page changes to
match. Likewise, if a user clicks a button bound to a function in the JSF Handler,
that function is called.

Generally, there is a one-to-one relationship between JSF Handlers and Web pages.

See JSF Handler part for more information about JSF Handler parts.

Java Server Pages (JSP) files

The Java Server Pages (JSP) files in an EGL Web project are the files that most
resemble the Web pages that a user will actually see in the browser. In Web terms,
these files create the view portion of a Web application. JSP files contain all the text,
tables, and other elements that are commonly seen on Web pages, plus dynamic
areas that can change at run time based on the logic in the JSF Handler. For these
dynamic areas, EGL Web applications use JavaServer Faces (JSF), a technology that
includes reusable user interface components, such as command buttons, links,
input fields, and output fields. In EGL Web applications, you add JSF components
to your JSP files and refer to those JSF components in your JSF Handler code.

For more information on JSP files, see JavaServer Pages (JSP) technology. For more
information on JSF technology, see JavaServer Faces (JSF) overview.

JSF configuration file

The JavaServer Faces (JSF) configuration file contains information for your pages
and for the JSF components on those pages. In general you will not need to edit
the JSF configuration file yourself, but you should be aware of the information
stored in the file and how it affects your EGL pages. For example, the JSF
configuration file contains navigation rules, or navigation aliases for your pages.
EGL uses these aliases with the forward statement to allow your JSF Handlers to
forward the user from one page to another. See “Navigating among Web pages
with navigation rules” on page 408.

By default, the JSF configuration file is named faces-config.xml and is located in


the WebContent/WEB_INF folder.

Web deployment descriptor

The Web deployment descriptor, not to be confused with the EGL deployment
descriptor, provides deployment information

The Web deployment descriptor is visible in your EGL Web project in two places:
v As the web.xml file, located in the project’s WebContent/WEB_INF folder by
default.
v As the Deployment Descriptor file at the root of your project, visible only in the
Project Explorer view.
These references point to the same file.

For more information on the Web deployment descriptor, see Configuring Web
applications using the Web deployment descriptor editor.

390 EGL Programmer’s Guide


Web Site Navigation

By default, all Web projects in the workbench, including EGL Web projects, contain
a Web Site Navigation file. This file is labeled Web Site Navigation in the Project
Explorer view and named .website-config in the Navigator view. The Web Site
Navigation file allows you to plan your Web application with a map of the pages
and the relationships between them. For more information, see Designing Web
sites.For more information, see ″Designing Web sites″ in the online help.

Web diagrams

By default, all Web projects in the workbench, including EGL Web projects, contain
a Web diagram. EGL does not support Web diagrams. Use the Web Site Navigation
file instead. For information on working with Web diagrams, see Web diagrams
and the Web diagram editor.

Other Web resources

Like other Web projects, an EGL Web application can contain files that are used to
control the runtime appearance and behavior of Web pages, including images,
Cascading Style Sheet (CSS) files, and JavaScript files. For more information about
using style sheet files, see Defining styles. For more information about using
JavaScript, see Adding code to Web pages.

Common tasks in Web applications


This section covers some common tasks that you might want to perform when
working with EGL Web applications.
Related tasks
“Creating a Web page” on page 392
When you create a Web page in an EGL Web project, EGL creates a JSF Handler
part to go along with the page.
“Binding JSF controls to EGL variables and functions” on page 394
When you have a JSP file and an associated JSF Handler part, you can begin
developing the Web page’s behavior. This means binding, or connecting,
elements on the Web page to variables and functions in the JSF Handler.
“Navigating among Web pages with navigation rules” on page 408
A JSF Handler can control the navigation on a Web site, forwarding the user
from one page to another and passing data between pages. EGL works closely
with JavaServer Faces (JSF) navigation functionality to control page navigation
in this way.
“Forwarding data between Web pages” on page 410
You can use the forward statement to pass data from one Web page to another
when you transfer control.
“Executing commands when a page loads” on page 411
A JSF Handler can include functions that run automatically when the page
loads.
“Retrieving the value of a clicked row in a data table” on page 417
The getClickedRowValue snippet in the EGL drawer of the Snippets view is a
function that retrieves the hyperlinked value of a clicked row in a data table.
“Setting the focus to a form field” on page 418
The Set cursor focus snippet in the EGL drawer of the Snippets view is a
JavaScript function that sets the cursor focus to a specified form field on a Web
page. It must be placed within a <script> tag in a JSP page.

Building EGL JSF Web applications 391


“Updating a row in a relational table” on page 423
The database update snippet in the EGL drawer of the Snippets view is a
function that updates a single row of a relational table when passed a record
from a JSF Handler. This snippet is intended to be placed in an EGL library.
“Storing data in the user’s session” on page 424
“Testing browsers for a session variable” on page 425
The Auto redirect snippet in the JSP drawer of the Snippets view tests for the
presence of a session variable. If the session variable is not present, the
customized code forwards control to a different Web page.
“Localizing text in Web applications” on page 426
“Creating a resource bundle” on page 430
“Locales for resource bundles” on page 431
“Running a Web page on a server” on page 448
When you are working with a Web page in EGL, you can run the page on a
server to see how it will look when deployed.
“Accessing the JSF component tree with the source assistant” on page 454

Creating a Web page


When you create a Web page in an EGL Web project, EGL creates a JSF Handler
part to go along with the page.

Prerequisites
v An EGL Web project

Additionally, it is best if you choose a target server for your project before creating
Web pages. If your project does not have a target server, support for Faces
components will not work at run time, and you might see a warning reminding
you to choose a target server. See Specifying target servers for J2EE projects.

Creating a page along with a JSF Handler part

When you create a Web page to be used with EGL, be sure to select the correct
type of Web page:
1. Click File → New → Other. The New window opens.
2. Expand Web and click Web page (not JSP).
3. Click Next.
4. In the File Name field, type the name for the new Web page. The
accompanying JSF Handler will have the same name with an .egl extension.
5. In the Folder field, select the location for the new Web page. The location must
be in the WebContent folder of an EGL Web project. The accompanying JSF
Handler will be put into the project’s jsfhandlers package unless you specified
a different package in the workbench preferences.
6. Optionally, select a template that is compatible with JSP files in the Template
box. If you don’t select a template, the new Web page will be an empty JSP file
with no template.
v For a blank Web page, click Basic Templates → JSP.
v For a Web page with placeholders for graphics and navigation elements that
are linked to a page template, expand Sample Templates and select a
template.
v To use a template that is already in your project, click My Templates and
choose the template from the Preview box.

392 EGL Programmer’s Guide


If you select a template other than the basic JSP template, the template files are
added to your project, and you can create more pages from the same template.
Then, when you change an area in the template, the matching area in each Web
page changes as well. See Page templates for more information on templates.
If you have selected a template that is not compatible with JSP files, a warning
will appear at the top of the page. Some templates default to file types other
than JSP, so by typing the .jsp extension into the File Name field, you
constrain yourself to templates compatible with JSP files.
7. Click Finish.

The new Web page and its JSF Handler part are created in your Web project.
Additionally, EGL creates a navigation rule in the JSF configuration file that
enables you to forward users to this page.

Creating a page from an existing JSF Handler part

An alternate way to create an EGL-controlled Web page is to create a JSF Handler


part separately, and then let EGL create a default JSP file for you based on the
information in the JSF Handler.
1. Click File → New → Other.
2. Expand EGL and click JSF Handler.
3. Click Next.
4. Set the location and file name of the new Handler part.
5. Click Finish.
6. In the new JSF Handler, create variables to represent the data that you want to
use on the page.
7. On each variable that you want to display on the page, set the displayUse
property to input for an input field and output for a read-only output field. For
example, an integer field that you want to be displayed as an editable input
field on the page might look like this:
myInputVar string {displayUse = input};

For other options for the displayUse property, see displayUse.


8. Set the view property of the JSF Handler to the name of the page you want to
create, including the .jsp extension. For example, if your JSF Handler is named
myPage, you might set the Handler’s properties as follows:
Handler myPage type JSFHandler
{view = "myPage.jsp"}
...
end
9. Save and generate the JSF Handler. EGL generates a default JSP that is based
on the Handler.

You can regenerate the JSP file at any time by deleting the JSP file and generating
the JSF Handler.
Related tasks
“Setting preferences for Web projects” on page 465
These preferences control defaults for EGL Web projects and JSF Handler parts.

Adding a Web server


You must have a Web server started and synchronized before you can run Web
applications.

Building EGL JSF Web applications 393


A Web server is a program that delivers responses to HTTP requests from a Web
browser. EGL can work with a variety of Web servers, many of which have
multiple versions. For this reason this topic can offer only very general
instructions. For more information, refer to the documentation for the specific Web
server software.

Set up a new Web server by following these steps:


1. Go to Window → Preferences → Server → Installed runtimes and click Add.
2. Select the type of runtime to install from the displayed list, then click Next.
3. Enter the path to the directory where the server programs are located, as well
as any other requested information (which varies with the type of runtime),
then click Finish.

If you are in the EGL perspective, you can now add a Server view to the
workbench (Window → Show View → Other → Server → Servers). From this view,
you can create a Server based on the Installed Runtime you just created.
1. Right-click anywhere in the blank Server view and select New → Server from
the pop-up menu.
2. Select the server type from the list. Your Server runtime should appear
automatically in the appropriate text box. Click Next.
3. Accept the default server settings on the next page and click Next.
4. Add any projects that will use the server to the Configured projects list. If you
use an EAR project, the projects that use the EAR will appear underneath it.
Click Finish when you are done.

You should now be able to right-click the name of the server in the Server view
and choose Start from the pop-up menu.
Related concepts
“Common tasks in Web applications” on page 391
This section covers some common tasks that you might want to perform when
working with EGL Web applications.
“Working with Web transaction applications in EGL” on page 561

Binding JSF controls to EGL variables and functions


When you have a JSP file and an associated JSF Handler part, you can begin
developing the Web page’s behavior. This means binding, or connecting, elements
on the Web page to variables and functions in the JSF Handler.

The specific steps involved depend on the complexity of the Web page and of the
related EGL parts:
v You can bind a button on the page to a function in the JSF Handler so that when
the user clicks the button, the associated function in the JSF Handler runs. See
“Binding a JSF button to a function” on page 395.
v You can bind input and output controls on the Web page to variables in the JSF
Handler so that when the value changes on the page, the value of the associated
variable changes to match and when the value of the variable changes in the JSF
Handler, that value displayed on the page changes. See “Binding a control on a
Web page to a variable” on page 397.
v You can bind variables in the JSF Handler to a JSF single-select control, such as a
combo box or list box. See “Binding a JSF single-select control to a variable” on
page 401.

394 EGL Programmer’s Guide


v You can bind an array of records to a data table on the page and return an array
of integers indicating which items the user has selected. See “Returning the
indexes of selected rows in a data table” on page 404.
v You can bind the inputs, outputs, and functions from a service to controls on the
page. These steps are essentially the same as binding ordinary input, output,
and command button controls to EGL variables and functions, but EGL provides
shortcuts for dealing with services on a Web page in this way. See “Binding JSF
controls to services” on page 407.

Although EGL is not case-sensitive, JSF is. EGL names referenced in the JSP file
must have the same case as the EGL variable or function declaration. For this
reason, you should avoid changing the case of variable or function names in a JSF
Handler after binding them to a JSF control. You can always repeat the binding
process to create a new, correct reference in the JSP file.
Related tasks
“Binding a JSF button to a function”
When you bind a JSF button to a function in the JSF Handler, the function runs
when the user clicks the button.
“Binding a control on a Web page to a variable” on page 397
You can bind a variable in the JSF Handler to an input or output control on the
Web page. When a variable is bound to a control on the page and the user
changes the value in the control, the value of the variable changes to match,
and if the logic in the JSF Handler changes the value of the variable, the value
on the page changes to match.
“Binding a JSF single-select control to a variable” on page 401
Binding a JSF single-select control, such as a combo box or group of radio
buttons, to an EGL variable is more complicated than binding an input or
output control because you must use two EGL variables: one for the options in
the control and one for the selected value.
“Returning the indexes of selected rows in a data table” on page 404
“Binding JSF controls to services” on page 407
Binding functions and variables from a service to controls on a Web page is no
different from binding any other type of functions and variables, but EGL
provides shortcuts for working with service controls in this way.
Related reference
JSF Handler part
Component tree access

Binding a JSF button to a function:

When you bind a JSF button to a function in the JSF Handler, the function runs
when the user clicks the button.

The easiest way to accept a command from a Web page is to write the function
first and then bind it to the button:
1. Create a Web page in an EGL Web project.
2. In the page’s JSF Handler, create a function. At this point, you only need the
basics of the function to do the binding; you can code the logic for the function
later.
3. Save the JSF Handler.
4. Open the associated JSP file.

Building EGL JSF Web applications 395


5. From the Enhanced Faces Components drawer of the Palette view, drag a
Button - Command onto the page.
6. In the Page Data view, expand JSF Handler. The functions and variables in the
JSF Handler are listed here.
7. From the Page Data view, drag the function directly onto the button that you
added to the page.
The function is bound to the button.

Alternatively, you can code the function from the Quick Edit view while working
on the Web page:
1. Open the JSP file.
2. From the Enhanced Faces Components drawer of the Palette view, drag a
Button - Command onto the page.
3. Right-click the button and then click Edit Events. The Quick Edit view opens.
Typically, this view is for JavaScript code, but you can use it to write functions
in the JSF Handler as well.
4. In the Quick Edit view, click Command at the left side of the view.
5. Click on the right area of the Quick Edit view to set focus there. The view
shows a new EGL function that is actually in the JSF Handler.
6. Type your EGL statements in the new function. You must at least add a
comment in the function in the Quick Edit view. If you do not change the code
in the function, the editor assumes that the function is not needed and removes
it.

Limitations

Command elements on the page can be bound only to functions in the JSF
Handler, not functions in other logic parts such as libraries. Also, you can bind
only functions with no parameters. If the function needs input to run, create a
variable in the JSF Handler and bind it to an input control on the page. Then, you
can use that variable as a parameter in a function invocation.

Also, see “Binding a control on a Web page to a variable” on page 397 for a
limitation having to do with the location of buttons and controls within a <form>
tag.
Related concepts
“Building EGL JSF Web applications” on page 389
In an EGL JSF Web application, EGL logic parts control Web pages, enabling
you to put data on Web pages, get data from user input on Web pages, and
forward users from page to page.
Related tasks
“Binding JSF controls to EGL variables and functions” on page 394
When you have a JSP file and an associated JSF Handler part, you can begin
developing the Web page’s behavior. This means binding, or connecting,
elements on the Web page to variables and functions in the JSF Handler.
“Binding a control on a Web page to a variable” on page 397
You can bind a variable in the JSF Handler to an input or output control on the
Web page. When a variable is bound to a control on the page and the user
changes the value in the control, the value of the variable changes to match,
and if the logic in the JSF Handler changes the value of the variable, the value
on the page changes to match.

396 EGL Programmer’s Guide


“Binding a JSF single-select control to a variable” on page 401
Binding a JSF single-select control, such as a combo box or group of radio
buttons, to an EGL variable is more complicated than binding an input or
output control because you must use two EGL variables: one for the options in
the control and one for the selected value.
“Returning the indexes of selected rows in a data table” on page 404
“Binding JSF controls to services” on page 407
Binding functions and variables from a service to controls on a Web page is no
different from binding any other type of functions and variables, but EGL
provides shortcuts for working with service controls in this way.

Binding a control on a Web page to a variable:

You can bind a variable in the JSF Handler to an input or output control on the
Web page. When a variable is bound to a control on the page and the user changes
the value in the control, the value of the variable changes to match, and if the logic
in the JSF Handler changes the value of the variable, the value on the page
changes to match.

There are several ways to bind Web page controls to EGL variables:
v Create the controls automatically from existing EGL variables.
v Create the controls yourself and explicitly bind variables to those controls.
v Create both the controls and the variables at the same time.

Creating JSF controls automatically from EGL variables

With this method, you create variables in the JSF Handler and then allow EGL to
create appropriate representations on the page.
1. Open the JSF Handler that is associated with the Web page. If you are looking
at the JSP file in the editor, you can open its JSF Handler by right-clicking the
page and then clicking Edit page code.
2. In the JSF Handler, define one or more EGL primitives, data items, or record
variables, and save the file. To be used on the Web page, the variables must be
directly within the JSF Handler part and not within any function in the part.
3. Open the JSP file.
4. In the Page Data view, expand JSF Handler. The variables that are defined in
the JSF Handler are listed here.
5. Drag the variable from the Page Data view directly onto the Web page.
Depending on the type of variable that you drag, the Insert Control or Insert
List Control window opens.
6. Click a radio button under Create controls for:
v If you want read-only output controls, select Displaying an existing record.
v If you want editable input controls, select Updating an existing record or
Creating a new record. In this context, the two options are equivalent.
This wizard treats all EGL variables as if they were records.
7. If you selected a record variable or more than one variable, select the check
boxes next to the controls or variables that you want to display. You can also
choose a type of control to represent the controls or variables from the Control
type column.
8. Click Finish.

Building EGL JSF Web applications 397


The controls are added to the page, and they are automatically bound to the
variables that you dragged onto the page. You can check to see which variable a
JSF control is bound to by clicking the control to select it and then opening the
Properties view. The Value field tells you which variable the selected control is
bound to.

Creating JSF controls and binding them manually

You can create your own controls and bind them manually to EGL variables. This
method is useful if you want to design the look of your page first and then add
data.
1. Open the JSF Handler associated with the Web page. If you are looking at the
JSP file in the editor, you can open its JSF Handler by right-clicking the page
and then clicking Edit page code.
2. In the JSF Handler, define one or more EGL primitive, data item, or record
variables and save the file. To be used on the Web page, the variables must be
directly within the JSF Handler part and not within any function in the part.
3. Open the JSP file.
4. From the Palette view, expand the Enhanced Faces Components drawer and
drag a control onto the Web page.
If you want the control to be read-only, use an output control, such as an
Output text control. If you want to make the control editable for input and
output, use an Input control. For records, use a Data Table control and create a
column in the data table for each field in the record.
5. In the Page Data view, expand JSF Handler. The variables defined in the JSF
Handler are listed here.
6. Drag the variable from the Page Data view directly onto the control on the Web
page, making sure to use appropriate controls for the EGL variable types. For
example, single primitive variables or data items can be bound to single input
or output controls. Arrays and records need to be bound to columns within a
data table.

Creating controls and variables at the same time

You can create controls and variables that are bound together at the same time
with the New Variable item in the EGL drawer of the Palette view.
1. In the Palette view, expand the EGL drawer.
2. Drag a New Variable onto the page. The Create a New EGL Data Variable
window opens.
3. Under Type Selection, select whether you want a primitive, data item, or
record variable. The rest of the options on the page differ depending on the
type of variable you choose.
4. Select the type of variable. For data items and records, choose a part from
your project. For primitive variables, choose a primitive type and specify a
dimension if appropriate.
5. Name the variable in the Enter the name of the field field.
6. If you want the variable to be an array, select the Array check box and specify
a starting length in the Size field.
7. Select Add controls to display the EGL element on the page.
8. Click OK. Depending on the type of variable, the Insert Control or Insert List
Control window opens.
9. Click a radio button under Create controls for:

398 EGL Programmer’s Guide


v If you want read-only output controls, select Displaying an existing record.
v If you want editable input controls, select Updating an existing record or
Creating a new record. In this context, the two options are equivalent.
This wizard treats all EGL variables as though they were records.
10. If you selected a record variable with more than one field, select the check
boxes next to the fields that you want to display. You can also choose a type
of control to represent the fields or variables from the Control type column.
11. Click Finish.

Limitations

Binding controls to variables has limitations because of the way Web pages behave.
One major limitation is that the JSF Handler receives only the changed variables
from the form that is submitted on the Web page.

For example, assume the following JSF Handler with two variables and one
function:
handler formTestPage type JSFHandler
{view = "formTestPage.jsp"}

stringOne string;
stringTwo string;

function doSomething()
SysLib.writeStderr("stringOne = " + stringOne);
SysLib.writeStderr("stringTwo = " + stringTwo);
end
end

If you bind the function to a button and the variables to two input controls, you
can type values into the controls, press the button, and see the values that you
typed written to the console.

This example assumes that you have placed the button and controls in the same
HTML form. The code of the body of the Web page might look like this:
<body>
<hx:scriptCollector id="scriptCollector1"
preRender="#{formTestPage._preRender}"
postRender="#{formTestPage._postRender}">

<h:form id="form1" styleClass="form">

<h:inputText id="text1" styleClass="inputText"


value="#{formTestPage.stringOne}"
binding="#{formTestPage.stringOne_Ref}"></h:inputText>
<br>
<h:inputText id="text2" styleClass="inputText"
value="#{formTestPage.stringTwo}"
binding="#{formTestPage.stringTwo_Ref}"></h:inputText>
<br>
<hx:commandExButton id="buttonDoSomething1"
styleClass="commandExButton" type="submit" value="doSomething"
action="#{formTestPage.doSomething}"
actionListener="#{formTestPage._commandActionListener}">
</hx:commandExButton>

</h:form>

</hx:scriptCollector>
</body>

Building EGL JSF Web applications 399


Note that the <h:form> tag surrounds both the button (represented on the page as
a commandExButton tag) and the two input controls (represented on the page as
inputText tags). This way, when you click the button, both input controls are made
available to the JSF Handler; that is, the values typed into the input controls are
assigned to the variables in the handler.

However, if you put the controls on the page far apart, they might not be within
the same form tag:
<body>
<hx:scriptCollector id="scriptCollector1"
preRender="#{formTestPage._preRender}"
postRender="#{formTestPage._postRender}">

<h:inputText id="text1" styleClass="inputText"


value="#{formTestPage.stringOne}"
binding="#{formTestPage.stringOne_Ref}"></h:inputText>
<br>

<h:form id="form1" styleClass="form">

<h:inputText id="text2" styleClass="inputText"


value="#{formTestPage.stringTwo}"
binding="#{formTestPage.stringTwo_Ref}"></h:inputText>
<br>
<hx:commandExButton id="buttonDoSomething1"
styleClass="commandExButton" type="submit" value="doSomething"
action="#{formTestPage.doSomething}"
actionListener="#{formTestPage._commandActionListener}">
</hx:commandExButton>

</h:form>

</hx:scriptCollector>
</body>

In this case, the first input control is outside the form, but the second input control
and the button are within the form. When you click the button now, the JSF
Handler receives only the second control, and the variable bound to the first
control is not changed.
Related concepts
“Building EGL JSF Web applications” on page 389
In an EGL JSF Web application, EGL logic parts control Web pages, enabling
you to put data on Web pages, get data from user input on Web pages, and
forward users from page to page.
Related tasks
“Binding JSF controls to EGL variables and functions” on page 394
When you have a JSP file and an associated JSF Handler part, you can begin
developing the Web page’s behavior. This means binding, or connecting,
elements on the Web page to variables and functions in the JSF Handler.
“Binding a JSF button to a function” on page 395
When you bind a JSF button to a function in the JSF Handler, the function runs
when the user clicks the button.
“Binding a JSF single-select control to a variable” on page 401
Binding a JSF single-select control, such as a combo box or group of radio
buttons, to an EGL variable is more complicated than binding an input or
output control because you must use two EGL variables: one for the options in
the control and one for the selected value.
“Returning the indexes of selected rows in a data table” on page 404

400 EGL Programmer’s Guide


“Binding JSF controls to services” on page 407
Binding functions and variables from a service to controls on a Web page is no
different from binding any other type of functions and variables, but EGL
provides shortcuts for working with service controls in this way.

Binding a JSF single-select control to a variable:

Binding a JSF single-select control, such as a combo box or group of radio buttons,
to an EGL variable is more complicated than binding an input or output control
because you must use two EGL variables: one for the options in the control and
one for the selected value.

In general, you need to create an array that represents the options in the control, as
well as a single variable to hold the value of the selected option. The simplest way
to do this is by defining an array of strings and populating the array with the
options for the control. See ″Using an array of STRING as the selection options.″
Alternatively, you can use an array of records as the options for the control by
specifying fields in the record as the option that is displayed in the control and as
the value for the selection. See ″Using an array of records as the selection options.″

Using an array of STRING as the selection options


1. In a JSF Handler, create an array of strings to hold the options for the
single-select control:
selectionOptions string[4];
2. Assign values to the array. You can assign values dynamically or simply assign
literal values to the array:
selectionOptions string[4]
{"First choice", "Second choice",
"Third choice", "Fourth choice"};
3. Create a string variable to hold the selected option:
selectedChoice string;
4. Indicate that the single variable receives the option selected from the list of
options by adding the SelectedValueItem property to the list of options:
selectionOptions string[4]
{"First choice", "Second choice",
"Third choice", "Fourth choice",
SelectedValueItem = selectedChoice};
5. Save and generate the JSF Handler.
6. On the page that is associated with the JSF Handler, drag the variable that
represents the list of options (in this case, selectionOptions) from the Page
Data view onto the page. The Insert List Control window opens.
7. In the Insert List Control window, click Displaying an existing record.
8. Under Control Type, select the type of single-select JSF control to put on the
page.
You can choose from Combobox (also called a list box or drop-down box), List
Box - single select, or Radio Button Group. In each case, the options will be
added dynamically depending on the number of elements in the list of options
at run time.
9. Click Finish. The control is added to your page and it is automatically bound
to the variables in the JSF Handler.

You can check which variables the JSF control is bound to by clicking the control
to select it and then opening the Properties view. In the Properties view, the Value
field represents the variable that will receive the value of the selected option, and

Building EGL JSF Web applications 401


the table of variables at the right side of the view lists the variable or variables that
are used to provide the options for the control.

This is a complete example of a JSF Handler that uses a single-select control in this
way:
handler singleSelect type JSFHandler
{view = "singleSelect.jsp"}

selectionOptions string[4]
{"First choice","Second choice",
"Third choice","Fourth choice",
SelectedValueItem = selectedChoice};

selectedChoice string;

outputMessage string;

function getChoice()
outputMessage = "You chose: "
+ selectedChoice;
end
end

This example assumes that you have dragged the selectionOptions variable onto
the page and created a combo box, list box, or radio button group based on this
variable. You will also need to bind the outputMessage variable to an output
control and the getChoice function to a button on the page. When you click the
button, the output control displays the text of the option you selected in the JSF
single-select control.

Using an array of records as the selection options

The method of using an array of strings as the selection options is simple, but it
might not be the most convenient method. You might need to retrieve the options
from an array of records, or you might need to use one value for the option and
pass a different value to the selection result variable. In this case, use the
@SelectionList record property to indicate which fields in the record should be
used for the option and which should be used for the value of the selection.

To use an array of records as the selection options:


1. In a Record part, use @SelectionList to specify which field in the record
should be the selection option (the labelItem) and which field should be the
value of the option (the valueItem:
record optionsRec type BasicRecord
{@SelectionList {labelItem = displayOption,
valueItem = optionValue}}
displayOption string;
optionValue string;
end

The record can contain other fields, but you must select two of these fields to
be the label and the value.
2. In the JSF Handler, create an array that is based on this Record part:
selectionOptions optionsRec[3];
3. Assign values to the array. You can assign values dynamically or simply
assign literal values to the array. You might want to use the
onPreRenderFunction to set values for this array:

402 EGL Programmer’s Guide


function onPreRender()
selectionOptions[1].displayOption = "Option one";
selectionOptions[1].optionValue = "first option";
selectionOptions[2].displayOption = "Option two";
selectionOptions[2].optionValue = "second option";
selectionOptions[3].displayOption = "Option three";
selectionOptions[3].optionValue = "third option";
end
4. Create a single variable to receive the selected option:
selectedChoice string;

The type of this variable must match the type of the field marked as
valueItem in the Record part.
5. Indicate that the single variable will receive the option that is selected from
the list of options by adding the SelectedValueItem property to the list of
options:
selectionOptions optionsRec[3]
{selectedValueItem = selectedChoice};
6. Save and generate the JSF Handler.
7. On the page that is associated with the JSF Handler, drag the variable that
represents the list of selection options (in this case, selectionOptions from the
Page Data view onto the page. The Insert List Control window opens.
8. In the Insert List Control window, click Displaying an existing record.
9. Under Control Type, select the type of single-select JSF control to put on the
page.
You can choose from Combobox (also called a list or drop-down box), List
Box - single select, or Radio Button Group. In each case, the options will be
added dynamically depending on the number of elements in the list of
selection options at run time.
10. Click Finish. The control is added to your page and it is automatically bound
to the variables in the JSF Handler.

You can check which variables the JSF control is bound to by clicking the control
to select it and then opening the Properties view. In the Properties view, the Value
field represents the variable that will receive the value of the selected option, and
the table of variables at the right side of the view lists the variable or variables that
are used to provide the options for the control.

This is a complete example of a JSF Handler that uses a single-select control in this
way:
handler singleSelect type JSFHandler
{view = "singleSelect.jsp",
onPreRenderFunction = onPreRender}

selectionOptions optionsRec[3]
{selectedValueItem = selectedChoice};

selectedChoice string;

outputMessage string;

function onPreRender()
selectionOptions[1].displayOption = "Option one";
selectionOptions[1].optionValue = "first option";
selectionOptions[2].displayOption = "Option two";
selectionOptions[2].optionValue = "second option";
selectionOptions[3].displayOption = "Option three";
selectionOptions[3].optionValue = "third option";

Building EGL JSF Web applications 403


end

function getChoice()
outputMessage = "You chose: "
+ selectedChoice;
end
end

record optionsRec type BasicRecord


{@SelectionList {labelItem = displayOption,
valueItem = optionValue}}
displayOption string;
optionValue string;
end

This example assumes that you have dragged the selectionOptions variable onto
the page and created a combo box, list box, or radio button group that is based on
this variable. You also need to bind the outputMessage variable to an output
control and the getChoice function to a button on the page. When you click the
button, the output control displays the text of the option that you selected in the
JSF single-select control.
Related concepts
“Building EGL JSF Web applications” on page 389
In an EGL JSF Web application, EGL logic parts control Web pages, enabling
you to put data on Web pages, get data from user input on Web pages, and
forward users from page to page.
Related tasks
“Binding JSF controls to EGL variables and functions” on page 394
When you have a JSP file and an associated JSF Handler part, you can begin
developing the Web page’s behavior. This means binding, or connecting,
elements on the Web page to variables and functions in the JSF Handler.
“Binding a JSF button to a function” on page 395
When you bind a JSF button to a function in the JSF Handler, the function runs
when the user clicks the button.
“Binding a control on a Web page to a variable” on page 397
You can bind a variable in the JSF Handler to an input or output control on the
Web page. When a variable is bound to a control on the page and the user
changes the value in the control, the value of the variable changes to match,
and if the logic in the JSF Handler changes the value of the variable, the value
on the page changes to match.
“Returning the indexes of selected rows in a data table”
“Binding JSF controls to services” on page 407
Binding functions and variables from a service to controls on a Web page is no
different from binding any other type of functions and variables, but EGL
provides shortcuts for working with service controls in this way.
Related reference
selectFromListItem

Returning the indexes of selected rows in a data table:

JSF provides the ability to include a ″selection column″ of check boxes in a data
table. With this column of check boxes, you can select one or more rows in the
table to perform a particular action on. For example, you might select several rows
for deletion.

404 EGL Programmer’s Guide


You can set a specific arrangement of properties on an array of records to indicate
that the array should be displayed on a Web page with a selection column. Then
the user can select one or more of the check boxes. EGL indicates which rows were
selected by returning an array of integers that represent the indexes of the selected
rows. For example, if the check boxes for the first, third, and fourth rows in the
data table are selected, EGL sets the array of integers to [1,3,4]. EGL
automatically converts 0-based JSF arrays to 1-based EGL arrays.

In this way, to be able to select multiple rows in a JSF data table, you need two
arrays:
v An array of records that will be the data in the table
v An array of integers to hold the indexes of the selected records

This task has the following prerequisites:


v An EGL Web project with at least one Web page
v A Record part that you want to show on the Web page

Follow these steps to set up a data table with a multiple selection column. This
example displays a list of customers and their total purchases and enables you to
select one or more rows to add together:
1. In the JSF Handler for an EGL-controlled Web page, create an array of records
to represent the table of data you want shown on the page:
purchaseList customerPurchase[3];

This example uses the following sample Record part:


record customerPurchase type BasicRecord
custName string;
totalPurchases decimal(10,2);
end
2. Retrieve data to populate this array with the data that you want the user to
select on the page. The example later in this topic will assign literal values to
the array, but you can retrieve the data from a database or populate the array
in any other way. You might want to put this retrieval logic in the function
specified in the onPreRenderFunction property of the JSF Handler.
3. Create the array of integers that will hold the indexes of the selected records:
allSelectedRows int[0];
4. For the record variable, set the selectedRowItem property to the name of the
array that will hold the indexes of the selected records:
purchaseList customerPurchase[3]
{selectedRowItem = allSelectedRows};
5. On the Web page, drag the array of records from the Page Data view onto the
page. The Insert List Control window opens.
6. In the Insert List Control, select a radio button under Create controls for. If
you want read-only output controls, select Displaying an existing record. If
you want editable input controls, select Updating an existing record.
7. Click Finish. The records are displayed on the page as a JSF data table.
This table includes a small, unlabeled column that contains check box elements.
If you click the check box control to select it and go to the Properties view, you
can see that this check box is bound not to any fields in the record variable but
to the integer array that you defined to hold the indexes of the selected rows.

Building EGL JSF Web applications 405


Now the integer array will hold the row numbers of the rows that are selected on
the Web page. You can define a function to process the selected records when a
user clicks a button on the page, for example:

For example, this JSF Handler uses a selection column in this way:
handler multiSelectPage type JSFHandler
{onPreRenderFunction = onPreRender,
view = "multiSelectPage.jsp"}

//Array of customer records and their purchase amount


purchaseList customerPurchase[3]
{selectedRowItem = allSelectedRows};

//indexes of the selected rows


allSelectedRows int[0];

//Sum of selected purchases


purchaseSum decimal(10,2);

function onPreRender()
//initialize the array of customers
purchaseList[1].custName = "Company A";
purchaseList[1].totalPurchases = "500.23";
purchaseList[2].custName = "Company B";
purchaseList[2].totalPurchases = "232.55";
purchaseList[3].custName = "Company C";
purchaseList[3].totalPurchases = "499.12";
end

function sumRows()
purchaseSum = 0;
counter int = 0;
customerIndexToAdd int;
for (counter from 1 to allSelectedRows.getSize() by 1)
customerIndexToAdd = allSelectedRows[counter];
purchaseSum += purchaseList[customerIndexToAdd].totalPurchases;
end
end

end

record customerPurchase type BasicRecord


custName string;
totalPurchases decimal(10,2);
end

This example assumes that you have dragged the purchaseList array onto the
page to make a JSF data table and that you have bound the sumRows function and
purchaseSum variable to a command button and output control on the Web page,
respectively.
Related concepts
“Building EGL JSF Web applications” on page 389
In an EGL JSF Web application, EGL logic parts control Web pages, enabling
you to put data on Web pages, get data from user input on Web pages, and
forward users from page to page.
Related tasks
“Binding JSF controls to EGL variables and functions” on page 394
When you have a JSP file and an associated JSF Handler part, you can begin
developing the Web page’s behavior. This means binding, or connecting,
elements on the Web page to variables and functions in the JSF Handler.

406 EGL Programmer’s Guide


“Binding a JSF button to a function” on page 395
When you bind a JSF button to a function in the JSF Handler, the function runs
when the user clicks the button.
“Binding a control on a Web page to a variable” on page 397
You can bind a variable in the JSF Handler to an input or output control on the
Web page. When a variable is bound to a control on the page and the user
changes the value in the control, the value of the variable changes to match,
and if the logic in the JSF Handler changes the value of the variable, the value
on the page changes to match.
“Binding a JSF single-select control to a variable” on page 401
Binding a JSF single-select control, such as a combo box or group of radio
buttons, to an EGL variable is more complicated than binding an input or
output control because you must use two EGL variables: one for the options in
the control and one for the selected value.
“Binding JSF controls to services”
Binding functions and variables from a service to controls on a Web page is no
different from binding any other type of functions and variables, but EGL
provides shortcuts for working with service controls in this way.
Related reference
selectFromListItem

Binding JSF controls to services:

Binding functions and variables from a service to controls on a Web page is no


different from binding any other type of functions and variables, but EGL provides
shortcuts for working with service controls in this way.

This task has the following prerequisites:


v An EGL Web project and Web page.
v A service client binding. See “Adding service client binding information from a
WSDL file” on page 489; “Calling a local service” on page 483; or “Calling a
remote service” on page 485.

To bind functions and variables from a service to fields on a Web page:


1. Open the Web page in the editor.
2. From the EGL drawer of the Palette view, drag a Service onto the page. The
Add Service window opens, listing all the services for which you have
defined client bindings.
3. In the Add Service window, select the service that you want to use in the
Select a service list. The Select a function list shows the functions that are
available in this service.
4. Under Select a function, select the function that you want to use. You can
select more than one function by pressing and holding Ctrl and clicking the
functions.
5. Click Finish. The Page Data view now shows the service in its Services folder,
and variables and functions are added to the JSF Handler.
From this point you can add controls and buttons to the page just as in
“Binding a control on a Web page to a variable” on page 397 and “Binding a
JSF button to a function” on page 395, but the entry for the service in the
Services folder enables you to create all the controls that are needed for the
service at once.
6. From the Services folder of the Page Data view, drag the service onto the
page. The Insert Service window opens.
Building EGL JSF Web applications 407
7. In the Function list, select a function to use on the page.
8. Under Fields to display, set the options for the input controls.
9. Click Next.
10. On the Results Form page, set the options for the output controls.
11. Click Finish.

The controls for input and output and buttons to invoke the function are added to
the page and bound to the corresponding variables and functions in the JSF
Handler.
Related concepts
“Building EGL JSF Web applications” on page 389
In an EGL JSF Web application, EGL logic parts control Web pages, enabling
you to put data on Web pages, get data from user input on Web pages, and
forward users from page to page.
Related tasks
“Binding JSF controls to EGL variables and functions” on page 394
When you have a JSP file and an associated JSF Handler part, you can begin
developing the Web page’s behavior. This means binding, or connecting,
elements on the Web page to variables and functions in the JSF Handler.
“Binding a JSF button to a function” on page 395
When you bind a JSF button to a function in the JSF Handler, the function runs
when the user clicks the button.
“Binding a control on a Web page to a variable” on page 397
You can bind a variable in the JSF Handler to an input or output control on the
Web page. When a variable is bound to a control on the page and the user
changes the value in the control, the value of the variable changes to match,
and if the logic in the JSF Handler changes the value of the variable, the value
on the page changes to match.
“Binding a JSF single-select control to a variable” on page 401
Binding a JSF single-select control, such as a combo box or group of radio
buttons, to an EGL variable is more complicated than binding an input or
output control because you must use two EGL variables: one for the options in
the control and one for the selected value.
“Returning the indexes of selected rows in a data table” on page 404
Related reference
selectFromListItem

Navigating among Web pages with navigation rules


A JSF Handler can control the navigation on a Web site, forwarding the user from
one page to another and passing data between pages. EGL works closely with
JavaServer Faces (JSF) navigation functionality to control page navigation in this
way.

EGL provides two ways to navigate to another page: forward to URL and forward
to label, the default. When using forward to URL, you specify an absolute or
relative URL to the target page; when using forward to label, you specify a
navigation rule that in turn points to the target page. When navigating among pages
in an EGL applications, use forward to label; when navigating to a Web page in a
different application, use forward to URL.

The JSF servlet responds to a forward statement by issuing either a forward or a


redirect. A JSF redirect prompts the user’s Web browser to load a different target
page; the effect is the same as if the user had typed the new URL into the
408 EGL Programmer’s Guide
browser’s address bar, including the loss of any request information that was
passed to the first page. A JSF forward, not to be confused with an EGL forward
statement, loads the new page in the browser without indicating to the browser
that the location has changed. In the case of the JSF forward, the browser believes
that it is still at the original page location, though it is displaying the new target
page. In this case, the request information is available to the new target page.
However, the browser and servlet are out of sync, because the browser is not
viewing the same page that it requested from the servlet. This mismatch can cause
problems; for example, relative links to files such as images and stylesheets must
be relative to the original page, rather than the forwarded target page, because the
browser will interpret the links relative to the original page.

In the functions defined in the onConstructionFunction, onPreRenderFunction, or


onPostRenderFunction properties of a JSF Handler, you can use forward to URL
but not forward to label.

Forwarding to a label

When navigating from page to page within an EGL application, use forward to
label. To forward the user from one page to another, you must know the name of
the JSF navigation rule that points to the target page. By default, the name of the
navigation rule that points to a page is the same as the name of the JSF Handler
that manages that page.

For example, a page named myPage.jsp might have a JSF Handler named myPage
in a file named myPage.egl. By default, the navigation rule for this page is myPage.
When you know the navigation rule of the target page, you can use the EGL
forward statement to send the user’s Web browser to that target page. In this case,
to forward to the page myPage.jsp, use the following code:
forward to label "myPage";

To find the navigation rule that points to a page, look in the faces-config.xml file,
which is in the WebContent/WEB-INF folder of your EGL Web project. This file lists
the rules and the pages to which those rules lead. The previous example used a
navigation rule that looks like this:
<navigation-case>
<from-outcome>myPage</from-outcome>
<to-view-id>/myPage.jsp</to-view-id>
</navigation-case>

The navigation rule contains two strings: a label for the rule and a relative link to
the target page. In this case, the label is myPage and the link refers to a page named
myPage.jsp in the same directory as the page that used the navigation rule. Note
the beginning slash before the file name of the page, which is a requirement for the
navigation rule. This navigation rule will result in a JSF forward as described
above.

To navigate to a page in a different EGL Web project, use a relative URL reference.
For example, to link from the page myProject01/myPage01.jsp to a file named
myPage02.jsp in a project named myProject02, use the following navigation rule:
<navigation-case>
<from-outcome>myPage02</from-outcome>
<to-view-id>/../myProject02/myPage02.jsp</to-view-id>
<redirect/>
</navigation-case>

Building EGL JSF Web applications 409


The <redirect/> tag is required for a navigation rule pointing to a target page in a
different project. JSF uses a redirect rather than a forward when navigating from a
page in one project to a page in another project.

Forwarding to a URL

You can also use forward to send the user to another Web page by specifying the
complete URL of the page:
forward to URL "http://www.ibm.com";

You can also specify a relative URL:


forward to URL "../myPage02.jsp";

Finally, you can specify a URL relative to the context root, or the directory that
contains all of the projects on the server:
forward to URL "/myProject02/myPage02.jsp";

When forwarding to another page controlled by an EGL JSF Handler, be sure to


use the correct extension of .faces or .jsp, as explained in “Running a Web page
on a server” on page 448.
Related reference
JSF Handler part
forward considerations for JSF
“Forwarding data between Web pages”
You can use the forward statement to pass data from one Web page to another
when you transfer control.

Forwarding data between Web pages


You can use the forward statement to pass data from one Web page to another
when you transfer control.

See “Navigating among Web pages with navigation rules” on page 408 for
information on forwarding to a different Web page.

Follow these steps to pass data between two Web pages:


1. In the page that will receive the data, set the functions defined in the JSF
Handler properties onConstructionFunction, onPreRenderFunction, and
onPostRenderFunction to receive the parameters, just like any other function
would receive parameters.
For example, the following JSF Handler is set to receive an integer and a
character parameter:
handler myPage type JSFHandler
{onPreRenderFunction = onPreRender,
view = "myPage.jsp"}

function onPreRender(myIntVariable int, myCharVariable char(100))


end

end
If you define more than one of these JSF Handler properties, the specified
functions must have matching parameters because all functions receive the
passed data. However, you can leave the parameters out of the functions if you
do not plan to use the passed data in that function.
2. In the page that forwards the data, use a forward statement and include the
data in the same order as the functions that will accept it:
410 EGL Programmer’s Guide
myInteger int = 5;
myChar char(100) = "Hello";
forward myInteger, myChar to "myPage";
The variables must be separated by commas, and their types must be
compatible with the types defined in the functions of the target page.
Related reference
“Navigating among Web pages with navigation rules” on page 408
A JSF Handler can control the navigation on a Web site, forwarding the user
from one page to another and passing data between pages. EGL works closely
with JavaServer Faces (JSF) navigation functionality to control page navigation
in this way.
“Executing commands when a page loads”
A JSF Handler can include functions that run automatically when the page
loads.
JSF Handler part
forward

Executing commands when a page loads


A JSF Handler can include functions that run automatically when the page loads.

The JSF Handler properties onPreRenderFunction, onPostRenderFunction, and


onConstructionFunction allow you to specify functions that run at different points
in the page’s life cycle.

When these functions run depends on the value of the scope property of the page.
When the user visits an EGL-controlled Web page for the first time, EGL loads the
JSF Handler, which is represented at run time by a page bean. If the scope of the
page is set to session (the default), the bean remains active during the user’s
session, even if the user browses away from the page. If the user returns to the
page, the bean is still available. If the scope of the page is set to request, the bean
does not remain active when the user browses away from the page. In this case,
any data stored in the bean is lost, and the bean must be loaded again if the user
returns to the page.
v The function that is specified in the onConstructionFunction property runs
when the page bean is loaded. Therefore, for pages set to session scope, this
function runs only the first time that the user visits the page. For pages set to
request scope, this function runs each time the user visits the page, because the
bean is recreated each time, except when the page is redisplayed due to a JSF
validation error.
However, if the cancelOnPageTransition property of the JSF Handler is set to
yes, the page bean is removed from the session when the user moves to another
page, even if the scope property is set to session. In this case, the
onConstructionFunction runs again when the user returns to the page because
the page bean must be reloaded.
This function is useful for one-time initialization tasks. You should not use
onConstructionFunction to retrieve session variables or other data that may
change and need to be loaded again when the page is refreshed. Use
onPreRenderFunction instead. See onConstructionFunction for more information
on this property.
v The function that is specified in the onPreRenderFunction property is not
affected by the scope of the page. This function runs each time the server begins
rendering the page, whether the bean was in the user’s session or not. In this
way, the onPreRenderFunction runs the first time the page bean is loaded,

Building EGL JSF Web applications 411


whenever the user refreshes the page, whenever another page directs the user to
this page, and whenever the page is redisplayed due to a JSF validation error.
v The function that is specified in the onPostRenderFunction property is similar
to the onPreRenderFunction, but it runs every time the server finishes rendering
the page. This function runs the first time the page bean is loaded, whenever the
user refreshes the page, whenever another page directs the user to this page, and
whenever the page is redisplayed due to a JSF validation error.

If you specify more than one of these properties, be aware of the following:
v The function that is specified in the onConstructionFunction property runs
before the function that is specified in the onPreRenderFunction property if
both are defined.
v If the functions accept parameters, the parameters must match. Alternatively,
you can define parameters in one function but not in another.
v You can specify the same function for more than one of these properties, but
this means that the function might run more than once.

The following example of a JSF Handler illustrates the use of two of these
functions:
1. In an EGL Web project, create a new Web page named loadTest.jsp.
2. Open the JSF Handler of the new page by right-clicking the open page in the
editor and then clicking Edit Page Code.
3. Change the code in the JSF Handler to match this example:
package jsfhandlers;

handler loadTest type JSFHandler


{onConstructionFunction = onConstruction,
onPreRenderFunction = onPreRender,
scope = session,
view = "loadTest.jsp"}

numberOfLoads int;
messageString string;

function onConstruction()
numberOfLoads = 0;
end

function onPreRender(incomingNumber int)


numberOfLoads = incomingNumber + 1;
messageString = "You have viewed this page "
+ numberOfLoads + " times.";
end

function forwardBack()
forward numberOfLoads to "loadTest";
end

end
4. Save the JSF Handler and close it.
5. On the loadTest.jsp page, add an Output field from the Enhanced Faces
Components drawer of the Palette view.
6. Next to the output field, add a Button - Command from the Enhanced Faces
Components drawer of the Palette view.
7. From the Page Data view, drag messageString directly onto the output field.
Now the variable in the JSF Handler is bound to the output field on the page.

412 EGL Programmer’s Guide


8. From the Page Data view, drag forwardBack() directly onto the command
button. Now the button is bound to the function in the JSF Handler.
9. Save the page and generate the project.
10. Run the page on a server.
The first time that you run this page, it displays ″You have viewed this page 1
times.″ In this case, the function specified in the onConstructionFunction property
runs first and sets the numberOfLoads variable to zero. Then, the function specified
in the onPreRenderFunction property runs, sets the variable to 1, and sets the
message string variable to ″You have viewed this page 1 times.″ Each subsequent
time you reload the page, the variable will increase by one, demonstrating that the
onPreRenderFunction function is running each time, but the
onConstructionFunction function is not.

If you try the example with scope set to request, the variable will never exceed 1
because the onConstructionFunction function sets the variable to zero each time
you refresh the page. Remember to save your changes to the JSF Handler, generate,
and republish the project to the server.

These functions have the following limitations:


v The functions specified in the onConstructionFunction and
onPreRenderFunction properties cannot access the JSF component tree as
explained in “Accessing the JSF component tree with the source assistant” on
page 454. The function specified in the onPostRenderFunction property can
access the JSF component tree. However, because this function is called after the
page is rendered and sent to the browser, the changes to the page will not be
visible to the user until the page is refreshed.
v The functions specified in the onConstructionFunction and
onPreRenderFunction properties cannot set the error message for a component
with sysLib.setError(). However, these functions can use
sysLib.setErrorForComponentID(). The function specified in the
onPostRenderFunction can use sysLib.setError().
v These functions can use a forward to URL statement, but not forward to label.

For more information, see the topics dedicated to these properties.


Related reference
onPreRenderFunction
onPostRenderFunction
onConstructionFunction

Providing type-ahead support for input controls


JSF text input controls can use the JSF type-ahead feature to anticipate what a user
might be typing into the input control. Input controls with type-ahead present a
list of options based on the first few characters that the user types into the control.
Then, the user can select one of these options or continue typing different text:

Building EGL JSF Web applications 413


As the user continues to type, the type-ahead feature filters the options to match
the new values that the user has typed into the field:

EGL can obtain the options for the type-ahead input field in one of three ways:
v EGL can compare what the user has typed with the values in the validValues
property for the variable bound to the control. In this case, the type-ahead
feature presents all of the values in the list of valid values that start with the
same characters as the user has typed.
v EGL can compare what the user has typed with the values in a DataTable part
specified in a variable’s validatorDataTable property. This method works just
like the validValues method.
v You can define a custom function to assemble an array of options to present to
the user. Typically, type-ahead presents options that have the same starting
characters as the characters that the user has already typed in, but in this case,
the function can return an arbitrary array of options.

The steps for using type-ahead depend on which of these methods you use to
obtain the list of options.

Using options from a Data Table or from a list of valid values

The simplest way to provide options for the type-ahead function is to associate the
variable bound to the field with a list of options, either in a Data Table or in a list
of valid values.
1. In a JSF Handler part, create a character or numeric variable to represent the
value typed in the input field on the page:
state STRING;
2. On the variable, set the typeahead property to YES:
state STRING {typeahead = YES};
3. Associate the variable with a list of options, using either the validValues or
validatorDataTable properties:
v If you use validValues, specify the options as the values of the property:

414 EGL Programmer’s Guide


state STRING {typeahead = YES,
validValues = ["AK","AL","AR","AZ",
"NC","NY","NH","NJ",
"NM","NE","NV","ND"]};

In this example, the valid values are the abbreviations of U.S. states
beginning with the letters ″A″ and ″N.″ When the user types the letter ″A″
into the input control, type-ahead will provide the abbreviations beginning
with ″A″, and likewise with the letter ″N″ and the abbreviations beginning
with ″N.″
When using type-ahead with a list of valid values, the valid values cannot
contain a range.
v If you use a Data Table, set the validatorDataTable property on the variable
to the name of the Data Table. You may need to bring the Data Table part
into scope with an import statement.
state string {typeahead = YES,
ValidatorDataTable = data.stateAbbrevs};

The matching Data Table might look like this example, providing the same
information as in the validValues example above:
package data;

dataTable stateAbbrevs type MatchValidTable {shared = no, resident = no}

3 abbrev char(2);

{contents = [
["AK"],["AL"],["AR"],["AZ"],
["NC"],["NY"],["NH"],["NJ"],
["NM"],["NE"],["NV"],["ND"]
]}

end

Data Tables used with type-ahead must be of the type MatchValidTable.


4. On the Web page, drag the variable from the Page Data view onto the Web
page. The Insert Record window opens.
5. In the Insert Record window, click Updating an existing record.
6. Ensure that the Control type for the variable is set to Input field. Type-ahead
can be used only on input controls.
7. Click Finish. An input control is created on the page that is bound to the
variable in the JSF Handler and is configured to use type-ahead.

Using options from a custom function

For more control over the options presented in type-ahead, you can create a
function that dynamically determines the options at run time.
1. In a JSF Handler or a Library part, create the function that determines the
type-ahead options. This function must accept exactly one parameter: a
STRING, representing the text that the user has typed into the input control.
Also, the function must return an array of STRING, representing the
type-ahead options presented in the input control.
// Return any state names for which
//the key is a substring of the full state name.
function getStateChoices( key string in ) returns( string[] )
results string[0];
key_upper string = strlib.upperCase( key );

Building EGL JSF Web applications 415


value string;

// Search for values with the same starting characters.


for ( i int from 1 to syslib.size( states ) )

// Compare each value in the data table to the key.


value = strlib.upperCase( states.fullname[i] );
if ( strlib.indexOf( value, key_upper ) == 1 )
// This value starts with the same characters as the key.
// Add it to the list of options.
results.appendElement( states.fullname[i] );
end

end

return( results );

end

This function compares the text that the user has typed into the input control,
represented by the variable key, with the values in a Data Table. The code if (
strlib.indexOf( value, key_upper ) == 1 ) determines if the value in the
Data Table starts with the characters that the user has typed, and if so, the code
results.appendElement( states.fullname[i] ); adds the value in the Data
Table to the array of options for type-ahead.
Although this function uses information from a Data Table like the following
example, the function could retrieve data from any source, such as a database
or record variable.
package data;

dataTable states type MatchValidTable


{shared = no, resident = no}

3 fullname char(20);
{contents = [
["ALASKA"],
["ALABAMA"],
["ARKANSAS"],
["ARIZONA"],
["NORTH CAROLINA"],
["NORTH DAKOTA"],
["NEBRASKA"],
["NEW HAMPSHIRE"],
["NEW JERSEY"],
["NEW MEXICO"],
["NEVADA"],
["NEW YORK"]
]}

end
2. In a JSF Handler part, create a character or numeric variable to represent the
value typed in the input field on the page:
state STRING;
3. On the variable, set the typeaheadFunction property to the name of the
function:
state STRING {typeaheadFunction = getStateChoices};
4. On the Web page, drag the variable from the Page Data view onto the Web
page. The Insert Record window opens.
5. In the Insert Record window, click Updating an existing record.

416 EGL Programmer’s Guide


6. Ensure that the Control type for the variable is set to Input field. Type-ahead
can be used only on input controls.
7. Click Finish. An input control is created on the page that is bound to the
variable in the JSF Handler and is configured to use type-ahead.

Setting options for type-ahead

You can customize the appearance and behavior of the type-ahead functionality on
the page. To set these options, follow these steps:
1. On the Web page, click the type-ahead icon to select it. The type-ahead icon is
located immediately to the right of the input control on which type-ahead is
enabled.
2. With the type-ahead icon selected, open the Properties view.

3. In the Properties view, set the options for the type-ahead feature. You can set
the size of the type-ahead field, how long the control should wait before
providing options, and how the input control should behave while waiting for
EGL to return the options. For more information on the options associated with
type-ahead, see Typeahead Complete Component.
Related reference
validValues
validatorDataTable
typeahead
typeaheadFunction

Retrieving the value of a clicked row in a data table


The getClickedRowValue snippet in the EGL drawer of the Snippets view is a
function that retrieves the hyperlinked value of a clicked row in a data table.

This snippet must be placed in an EGL JSF Handler part. This snippet has the
following prerequisites:
1. The JSP page has a data table.
2. The names of the JSP identifiers have not been changed from the default.
3. The page is defined as request in scope in faces-config.xml, not session.
To insert and configure this snippet, follow these directions:
1. In a JSF Handler, define a character or string variable to receive the clicked
value.
2. Place the cursor on a blank line in the JSF Handler where it is legal to add a
function. (This snippet includes an entire EGL function.)

Building EGL JSF Web applications 417


3. In the EGL drawer of the Snippets view, double-click the Get clicked row
value snippet. The Insert Template window opens. For more information, see
Inserting EGL code snippets.
4. In the Insert Template window, type the name of the variable as the value of
the receivingVar variable.
5. Click Insert.
6. From the Enhanced Faces Components drawer in the Palette view, add a
command hyperlink to a field in the data table.
7. For the target of the command hyperlink, specify the name of the JSP page. The
hyperlink links to its own page.
8. Add a parameter to the hyperlink and give that parameter the same name as
the variable in the JSF Handler that receives the clicked value.
9. On the All tab of the Properties view, set the action property to the getVal()
function.

The code that is inserted by this snippet follows:


function getVal()
javaLib.store((objId)"context",
"javax.faces.context.FacesContext",
"getCurrentInstance");
javaLib.store((objId)"root",
(objId)"context", "getViewRoot");
javaLib.store((objId)"parm",
(objId)"root",
"findComponent",
"form1:table1:param1");
recVar = javaLib.invoke((objId)"parm",
"getValue");
end
Related concepts
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can
be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.
Related tasks
“Inserting code snippets into EGL and JSP files” on page 165

Setting the focus to a form field


The Set cursor focus snippet in the EGL drawer of the Snippets view is a
JavaScript function that sets the cursor focus to a specified form field on a Web
page. It must be placed within a <script> tag in a JSP page.

To insert and configure this snippet:


1. Add a <script> tag within the <head> tag of the JSP file as in this example:
<script type="text/javascript">
<!-- snippet code goes here -->

</script>
2. From the EGL drawer of the Snippets view, drag the Set cursor focus snippet
to a blank line within the <script> tag you just added. For more information,
see Inserting code snippets into EGL and JSP files. This snippet goes into the code
of the JSP file, not the code of the JSF Handler part.
3. In the snippet code, replace both instances of [n] with the number of the form
field which will receive focus. The form fields are numbered beginning with
zero. For example, use [3] to set focus to the fourth field on the page.

418 EGL Programmer’s Guide


4. In the snippet code, replace both instances of form1 to the value of the ID
attribute of the form to which you want to set focus.
5. In the <body> tag of the JSP page, add the attribute onload="setFocus();" as in
the following example:
<body onload="setfocus();">
6. Save the file.

The code inserted by this snippet is as follows:


function setFocus() {
document.getElementById('form1').elements[n].select();
document.getElementById('form1').elements[n].focus();
}
Related concepts
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can
be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.
Related tasks
“Inserting code snippets into EGL and JSP files” on page 165

Displaying error messages on Web pages


JSF Web pages can include error messages to provide feedback, usually to notify
the user of a problem on the page. With the sysLib.setError and
sysLib.setErrorForComponentID system functions, you can set the value of these
error message components from the page’s JSF Handler.

JSF pages use two types of error message components:


v The display error component displays a message that relates to a specific input
component on the page. For this reason, this type of component must specify the
ID of an input component on the page. The display error component is
represented by an <h:message> JSF tag, and the ID of the input component for
which it provides feedback is specified in its for attribute.
v The display errors component can behave in one of two ways:
– It combines all of the error messages from the display error components on
the page and adds any error messages not associated with a specific
component.
– It displays only the error messages not associated with a specific component.

A JSF Handler can set the value of error message components in these ways:
v The sysLib.setError system function sets the message of a display error
component, given the name of a variable that is bound to an input component
on the page. In other words, you pass the name of an EGL variable in the JSF
Handler to the function, and JSF finds the display error component that is
associated with an input component on the page, which in turn to that specified
EGL variable.
v The sysLib.setErrorForComponentID function sets the message of a display
error component, given the ID of an input component on the page. JSF shows
the error message in the display error component associated with the specified
input component.

Follow these steps to display an error message on a Web page with EGL:

Building EGL JSF Web applications 419


1. As described in “Creating a resource bundle” on page 430, create a resource
bundle to hold the error messages. In short, you will create a file named in
the following format:
prefix_locale.properties
prefix
The prefix of the resource bundle file name is arbitrary, but the prefix
must be the same for each resource bundle in the application.
locale
The locale of the resource bundle, such as en_US. The locale identifies the
language of the strings in the bundle and, optionally, more specific
information about the specialization of the language, such as the dialect,
variety, or geographic location. For more information on locales, see
“Locales for resource bundles” on page 431.

For example, a resource bundle that contains English as it is spoken in the


United States might be named resourceBundle_en_US.properties.
Then, add messages to the file in the format keyname=messageText, such as
this:
error01=The specified value is too short.
Optionally, you can include inserts in the message. Inserts are represented by
an integer in braces and will be replaced with a value you specify when you
display the error message. Error messages can contain several inserts per
message, numbered such as {0}, {1}, and {2}.
With one insert, the error message in the resource bundle might look like this:
error02=The specified value is shorter than five characters: {0}
2. On a Web page in an EGL Web project, create an input component, such as an
input text component. You can use JSF display errors only with input
components.
3. Bind the input component to a variable in the JSF Handler associated with the
page.
4. Optionally, set the ID of the component to a meaningful mnemonic by clicking
the component to select it and typing the ID in the Id field of the Properties
view.
5. From the Palette view, drag a Display Error component onto the page. You
should put the display error component near the input component so it will
be clear which component is associated with the error message.
6. Click the display error component to select it.
7. In the Properties view, under Display error message for the component, set
the Id field to the ID of the input component.
At this point, the code of the Web page shows that the error message is
associated with the input component. In the following example, note that the
for attribute of the display error component is set to the value of the input
component’s id attribute:
<h:inputText id="inputComponent"
styleClass="inputText"
value="#{errorMessageTest.inputString}"
binding="#{errorMessageTest.inputString_Ref}">
</h:inputText>

<h:message id="message1"
styleClass="message"
for="inputComponent">
</h:message>

420 EGL Programmer’s Guide


8. Save the page.
9. In the JSF Handler associated with the page, set the msgResource JSF Handler
property to the prefix of the resource bundle (that is, the file name excluding
the extension and the locale code):
handler errorMessageTest type JSFHandler
{view = "errorMessageTest.jsp",
msgResource = "resourceBundle"}

In this case, the resource bundle is named resourceBundle_en_US.properties


and so the msgResource property is set to resourceBundle.
10. Use the sysLib.setError or sysLib.setErrorForComponentID system function
to set the error message, using one of the following methods:
v If you want to use a string specified in the JSF Handler as the text of the
error message, pass these three parameters in order:
a. The unquoted name of the EGL variable in the JSF Handler. For a field
within a record, specify the record name, a period, and the field name,
as in myRecord.myField.
b. An empty string. You pass an empty string as the second parameter
because this parameter is used as the key of a message in an external
error message file.
c. The text of the error message as a string.
Following is an example of this method:
SysLib.setError(inputString, "",
"This is the text of the error message.");
v If you want to use an error message in a resource bundle with zero or one
inserts, pass these three parameters in order:
a. The unquoted name of the EGL variable in the JSF Handler. For a field
within a record, specify the record name, a period, and the field name,
as in myRecord.myField.
b. The quoted key of the message in the resource bundle.
c. If the message expects an insert, the value to be used in that insert. This
parameter must be compatible with the STRING type.
For example, if you want to issue an error related to the variable
inputString, using an error message with the key error02 and the same
variable as an insert value, you would use this EGL code:
SysLib.setError(inputString, "error02", inputString);

This example assumes a resource bundle with a message definition similar


to this example:
error02=The specified value is shorter than five characters: {0}
v If you want to use an error message in a resource bundle with two or more
inserts, you must use sysLib.getMessage in coordination with
sysLib.setError, because sysLib.setError supports error messages with only
zero or one insert:
a. Set the userMessageFile build descriptor option to the prefix of the
resource bundle file name, the same value as you set in the
msgResource JSF Handler property.
b. Use sysLib.getMessage to put the inserts into the message and create a
string containing the complete message:
errorMessageString string =
sysLib.getMessage("error03", [inputString, "five"]);

Building EGL JSF Web applications 421


c. Pass the error message string to sysLib.setError:
SysLib.setError(inputString, "", errorMessageString);

This example assumes an error message in the resource bundle with two
inserts, as in this example:
error03=The string {0} is too short.
It must be at least {1} characters long.
v In most cases, you will use sysLib.setError to set the error message, since it
is usually more convenient to use the EGL variable name as the reference
point for the error message. However, if you know the ID of the input
component with which you want to associate the error message, you can
use sysLib.setErrorForComponentID in a way similar to sysLib.setError,
except that sysLib.setErrorForComponentID takes the quoted identifier of
the input component, consisting of the ID of the form on the page, a colon,
and the ID of the input component, rather than the name of the EGL
variable:
SysLib.setErrorForComponentId("form1:inputComponent",
"error01", inputString);

This example assumes an input component on the page with the ID


inputComponent and a display error component associated with it. It also
assumes a message in the resource bundle with a key error01, similar to
the previous examples.
v If you want to display the error message on the display errors component,
rather than a display error component associated with a specific input
component, pass the error message to sysLib.setError without specifying a
variable name:
SysLib.setError("The string is too short.");

For example, the following JSF Handler tests a value typed into an input
component on a Web page to see if the value is long enough. If the value is too
short, the JSF Handler displays an error message.
handler errorMessageTest type JSFHandler
{view = "errorMessageTest2.jsp",
msgResource = "resourceBundle"}

inputString string;

function validateString()
if (StrLib.characterLen(inputString) < 5)
SysLib.setError(inputString, "error02", inputString);
end
end

end

This example assumes that the inputString variable is bound to an input


component on the associated Web page which is associated with an error message
component, as explained above. Also, it assumes a resource bundle named
resourceBundle_locale.properties, where locale is the locale code of the language
you are using. The example uses a message in that resource bundle file similar to
the following:
error02=The specified value is shorter than five characters: {0}

JSF can also set the values of error message components as part of user input
validation. See Display Errors.
Related reference
422 EGL Programmer’s Guide
setError()
setErrorForComponentID()
msgResource

Updating a row in a relational table


The database update snippet in the EGL drawer of the Snippets view is a function
that updates a single row of a relational table when passed a record from a JSF
Handler. This snippet is intended to be placed in an EGL library.

To insert and configure this snippet:


1. In the EGL editor, place the cursor where you want the snippet to go. Because
this snippet is a complete EGL function, the cursor must be placed where a
function is legal.
2. In the EGL drawer of the Snippets view, double-click the database update
snippet. The Insert Template window opens.
3. In the Insert Template window, set the value of TableName to the name of the
table you are updating.
4. Set the value of KeyColumn to the primary key column of the table.
5. Click Insert.
6. Save the file.

This snippet inserts the following code:


Function updateRec(EGL_RecordNameNew EGL_RecordName)
//Function name - call this function passing
//the EGL_RecordName Record as a parameter
EGL_RecordNameOld EGL_RecordName; //A copy of the Record,
//used to lock the table row, and obtain the existing row values
//prior to update
try
EGL_RecordNameOld.Table_Key_column_ID
= EGL_RecordNameNew.Table_Key_column_ID;
get EGL_RecordNameOld forUpdate; //Get the existing row.
//Note that if you had custom processing to do,
//you would insert after this call
move EGL_RecordNameNew to EGL_RecordNameOld byName;
//Move the updated values to the copy-row
replace EGL_RecordNameOld; //And replace the row in the database.
sysLib.commit(); //Commit your changes to the Database
onException (ex AnyException) //If the update fails...
sysLib.rollback(); //cancel all database updates
//(assuming this is permitted by your database)
// and call a custom error handling routine or something
end
end
Related concepts
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can
be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.
Related tasks
“Inserting code snippets into EGL and JSP files” on page 165

Building EGL JSF Web applications 423


Storing data in the user’s session
Web applications are considered stateless because they do not automatically save
information about a user’s interaction with the application. If the application needs
to remember details about the user’s actions, it must explicitly store that
information somewhere.

Web applications often store these details in the user’s session object, an area of
memory on the server that stores temporary information about one user’s
transactions and interaction with the Web application. The data in the session
object is not as stable as data stored in a database because the session object is lost
if the session ends. Still, putting data in the session object is useful in the short
term if done efficiently.

When a user visits an EGL-controlled Web page, the server loads the page’s JSF
Handler, represented at run time as a page bean, stores that bean in the session
object as a session variable, and uses that bean to provide the logic for the page. If
the scope property of the JSF Handler is set to session and its
cancelOnPageTransition property is set to no, the bean remains in the session
object until the session ends or the bean times out. In this way, variables in the
Handler can retain their values during the session, even if the user moves to
another page.

However, page beans can take up large amounts of memory. A much more efficient
way to use the session object (and, in turn, server resources) is to store the user’s
information in your own smaller session variables and then remove the beans from
the session object by setting the scope of the JSF Handlers to request or
cancelOnPageTransition to yes. In this way, you retain only the data the
application needs, not all the variables in its Handlers.

Setting and retrieving session variables

To set a session variable, pass a string identifier and an EGL variable to the session
object:
myVar string = "Hello";
J2EELib.setSessionAttr("mySessionVar", myVar);

To retrieve the value later, use the J2EELib.getSessionAttr system function with
the same identifier and a new variable:
myVarFromSession string;
J2EELib.getSessionAttr("mySessionVar", myVarFromSession);

A more complete example of two JSF Handlers that set and retrieve a session
variable follows. The first Handler sets the session variable:
package jsfhandlers;

handler sessionPageOne type JSFHandler


{scope = request,
view = "sessionPageOne.jsp"}

userRecord sessionRecord;

function storeAndForward()
J2EELib.setSessionAttr("mySessionRecord",
userRecord);
forward to "sessionPageTwo";
end

424 EGL Programmer’s Guide


end

record sessionRecord type BasicRecord


userName string;
idNumber int;
end

This example assumes a Web page named sessionPageOne.jsp with two input
fields bound to the fields in the record, along with a command button bound to
the storeAndForward function. When the user clicks the button bound to the
storeAndForward function, the record is added to the user’s session variable, and
the user is forwarded to another page, represented by the following JSF Handler:
package jsfhandlers;

handler sessionPageTwo type JSFHandler


{view = "sessionPageTwo.jsp",
onPreRenderFunction = onPreRender}

submittedRecord sessionRecord;

function onPreRender()
J2EELib.getSessionAttr("mySessionRecord",
submittedRecord);
end
end

Like the previous Handler, this example assumes that you have bound the fields in
the record to output variables on the sessionPageTwo.jsp page. This Handler
retrieves the data from the session variable and assigns it to a variable for
temporary use within the JSF Handler.

Clearing session variables

You can remove a single session variable from the session object by passing the
string identifier of the variable to the J2EELib.clearSessionAttr function:
J2EELib.clearSessionAttr("mySessionRecord");

Also, you can remove all EGL-controlled session variables from the user’s session
object with the J2EELib.clearEGLSessionAttrs function.

For more information on session-related functions, see ″EGL library j2eeLib″ in the
EGL Language Reference.
Related reference
EGL library j2eeLib

Testing browsers for a session variable


The Auto redirect snippet in the JSP drawer of the Snippets view tests for the
presence of a session variable. If the session variable is not present, the customized
code forwards control to a different Web page.

The snippet must be placed within the <head> tag of a JSP page after the
<pageEncoding> tag.

To insert and configure this snippet:


1. From the EGL drawer of the Snippets view, drag the Auto redirect snippet to a
blank line in the JSP file within the <head> tag of the page. This snippet goes

Building EGL JSF Web applications 425


into the code of the JSP file, not the code of the JSF Handler part. For more
information, see Inserting code snippets into EGL and JSP files. The Insert
Template window opens.
2. In the Insert Template window, set the SessionAttribute variable to the name
of the session variable that is being tested. The default value is UserID. See
“Storing data in the user’s session” on page 424.
3. Set the ApplicationName variable to the name of your project or application.
The default value is EGLWeb.
4. Set the PageName variable to the name of the page that the browser will be
redirected to if the session variable is absent. The default value is Login.jsp.
5. When you have customized the values in the Insert Template window, click
Insert.
6. Save the file.

The code inserted by this snippet is as follows:


<%
if ((session.getAttribute("userID") == null ))
{
String redirectURL =
"http://localhost:9080/EGLWeb/faces/Login.jsp";
response.sendRedirect(redirectURL);
}
%>
Related concepts
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can
be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.
Related tasks
“Inserting code snippets into EGL and JSP files” on page 165
“Storing data in the user’s session” on page 424

Localizing text in Web applications


You can localize your Web application so that the Web pages will display in
different languages. To localize a Web application, you must create a resource bundle
for each language that you want to support. These resource bundles contain strings
to be presented on the Web pages at run time. Each resource bundle is specific to a
human language, so that when you switch to a different resource bundle, the
strings on the Web pages switch to a different language.

You can use translatable strings as the text on Web pages. The sections below cover
some different uses of these strings on web pages. Also, you can use translatable
strings as the error messages for Web pages; see “Displaying error messages on
Web pages” on page 419.

Using translatable strings as output fields

To use a translatable string as the value of a JSF field, such as an output field, you
cannot assign the key of the translatable string to an EGL variable bound to the
field. To use a translatable string as the value of a JSF field, you cannot bind that
field to an EGL variable at all. Instead, you must bind the field to the translatable
string directly, as in these steps:

426 EGL Programmer’s Guide


1. On a JSP file in your EGL Web project, drag onto the page a JSF output
component, such as an output field, from the Enhanced Faces Components
drawer of the Palette view .
2. Click the field to select it.
3. In the Properties view, find the Value field. This field shows the text for the
component.
4. Next to the Value field, click the Select Page Data Object button. The Select
Page Data Object window opens. Typically, you select a variable from your
JSF Handler from this window, but in this case you will use a string from a
resource bundle instead.
5. Go to the String Resource tab.
6. Click Add Properties File.
7. In the Choose/Create Properties File window, select the resource bundle file
that you want to use on the Existing File tab, or go to the New File tab to
create a new resource bundle. In either case, adhere to the naming and
placement conventions explained in “Creating a resource bundle” on page
430.
8. After you have selected or created a resource bundle file, enter a mnemonic to
represent the file in the File identifier field. By default, this mnemonic is
labels, but if you change it, it must match the mnemonic set in the EGL Page
Designer preferences as explained in “Setting preferences for Web projects” on
page 465.
9. Click OK to close the Choose/Create Properties File window. The table on the
String Resource tab shows the strings from the file. You can use the strings
that are already there or add new strings with the Add Resource button.
10. Select the string that you want to use on the field and click OK. The field
shows the key of the translatable string. When you run the page, the server
will use the string as the value of the field.

Using translatable strings in EGL properties

You can also use translatable strings as the values of certain EGL properties, most
notably DisplayName:
1. In the jsfhandlers package of your project’s Java Resources folder, create a
resource bundle to hold the strings that you want to use in the application. See
“Creating a resource bundle” on page 430. For example, if you are using
American English, you might create a resource bundle named
myBundle_en_US.properties.
2. In the resource bundle, add keys and string values for the text that you want to
use on the Web pages, as in this example:
myString01=Hello there!
myString02=Welcome to my Web page.
3. Set your workbench preferences to use a default mnemonic to represent the
resource bundle:
a. Click Window → Preferences.
b. In the Preferences window, expand EGL and click Page Designer.
c. In the Loadbundle variable field, type a mnemonic for the translatable
strings. By default, this mnemonic is labels, but if you change it, it must
match the mnemonic that is used in the File identifier field in the
Choose/Create Properties File window as explained earlier.
d. Click OK.

Building EGL JSF Web applications 427


4. In the JSF Handler for the Web page, set the DisplayName or Help properties
of a variable to the key that represents the text that you want to use on the
Web page:
myFieldString string {DisplayUse = button,
DisplayName = "%myString01",
Action = "DoSomething"};
Note the percent sign (%) in the value of DisplayName. This symbol indicates
that the value comes from the given key in the resource bundle.
5. On the JSP that is associated with the JSF Handler, drag the variable onto the
page. For example, if you drag the variable in the previous example onto a
page, the code created in the JSP is as follows:
<hx:commandExButton id="buttonMyFieldString1"
styleClass="commandExButton" type="submit"
value="#{labels.myString01}"
actionListener="#{testResourceBundle._commandActionListener}"
action="DoSomething"></hx:commandExButton>

Note that the value of the button is not the name of the variable or the value of
the variable, but a string from the resource bundle, composed of the mnemonic
that you entered in the preferences plus the key that you used in the JSF
Handler.
An alternate method for using the translatable strings on the page is to define a
JSF Handler part without an associated page and then allow EGL to create the
page based on the variables in the Handler. See ″Creating a page from an
existing JSF Handler part″ in “Creating a Web page” on page 392. If you use
this method, you can also use a translatable string for the title property of the
JSF Handler, and when EGL creates the page, that string will appear
prominently at the top of the page.
6. In the code of the JSP, add the following line of code, directly below the code
<f:view>:
<f:loadBundle basename="myBundle" var="labels"/>
7. Set the values of the basename and var attributes to the prefix of your resource
bundle and the mnemonic, respectively. This example assumes that your
resource bundles are named myBundle_locale.properties and that you used
the default mnemonic labels.
This code specifies that the translatable strings represented on the page as
labels.keyname are found in the resource bundle files named with the prefix
myBundle. The basename attribute of this tag specifies the prefix of the resource
bundle file name, and the var attribute specifies the start of the translatable
string used in the code.

Using translatable strings for different languages at run time

To use translatable strings for different languages at run time:


1. Create one resource bundle for each language that your application supports.
The file name of each resource bundle in the application must have the same
prefix. If the name of your first resource bundle is myBundle_en_US.properties,
the names of the other resource bundles must begin with myBundle.
2. In the Project Explorer view, double-click the file faces-config.xml to open it.
This file is found in the folder WebContent/WEB-INF.
3. Within the <application> tag of the faces-config.xml file, add a
<locale-config> tag:

428 EGL Programmer’s Guide


<faces-config>
<application>
<locale-config>

</locale-config>
...
</application
</faces-config>
4. Within the <locale-config> tag, add a <default-locale> tag that contains the
locale of the default resource bundle. For example, if you want your application
to appear in German if the user does not specify a locale or specifies a locale
that you application does not support, add the following code within the
<locale-config> tag:
<default-locale>de</default-locale>
It is good practice to specify a default locale, but it is not required.
5. Following the <default-locale> tag, add a <supported-locale> tag for each
locale that your application supports. For example, if your application supports
American English, add the following code within the <locale-config> tag:
<supported-locale>en_US</supported-locale>
Following is an example from an application that supports several locales:
<faces-config>
<application>
<locale-config>
<default-locale>de</default-locale>
<supported-locale>en_US</supported-locale>
<supported-locale>es</supported-locale>
<supported-locale>de</supported-locale>
<supported-locale>fr_FR</supported-locale>
<supported-locale>it_IT</supported-locale>
<supported-locale>pt_br</supported-locale>
</locale-config>
...
</application>
</faces-config>

If you define a default locale, you must also define that locale as a supported
locale.

Note: Each locale that is defined in this file must have a matching resource
bundle defined for that locale.
6. Save and close the file.
7. Test your application with your Web browser set to different languages to see
the different strings.
Related concepts
“Locales for resource bundles” on page 431
Related tasks
“Customizing runtime messages” on page 152
“Creating a resource bundle” on page 430
Related reference
displayName
help

Building EGL JSF Web applications 429


Creating a resource bundle
A resource bundle contains a series of strings to be presented at run time. With
resource bundles, you can localize your applications by including a different
resource bundle for each language that you want to support.

Each resource bundle must define a string for each key that is used in the
application. If a Web page lists a key and the resource bundle for the current user’s
language does not define a string for that key, a fatal error will be generated.

To create a resource bundle:


1. In the Project Explorer view, right-click the folder in which you want to create
the resource bundle. This folder must be within the Java Resources folder of an
EGL Web project.
2. From the menu, click New → Other. The New window opens.
3. In the New window, expand General and click File.
4. Click Next.
5. In the File name field, type a name for the new resource bundle. The file name
of the resource bundle must be in this format:
prefix_locale.properties
prefix
The prefix of the resource bundle file name is arbitrary, but the prefix must
be the same for each resource bundle in the application.
locale
The locale of the resource bundle, such as en_US. The locale identifies the
language of the strings in the bundle and, optionally, more specific
information about the specialization of the language, such as the dialect,
variety, or geographic location. For more information on locales, see
“Locales for resource bundles” on page 431.

For example, a resource bundle that contains English as it is spoken in the


United States might be named resourceBundle_en_US.properties.
6. Click Finish.
The new file is created in the folder that you right-clicked, and the new file
opens in the editor.
7. Add strings to the new resource bundle in the following format:
keyname=stringtext
keyname
The key name of the string. This key is placed in the Web pages to indicate
which text from the resource bundle to insert. For example, a key named
WelcomeText might indicate introductory text to be shown at the top of a
page.
stringtext
The text that is associated with the key.
8. Save and close the file.

You can create as many resource bundles for your application as you want, but
each resource bundle must have a different locale and the same prefix.
Related concepts
“Locales for resource bundles” on page 431
Related tasks

430 EGL Programmer’s Guide


“Customizing runtime messages” on page 152
“Localizing text in Web applications” on page 426

Locales for resource bundles


Each resource bundle has a different locale. The locale indicates the specific human
language of the strings in the resource bundle. The locale is indicated by the end of
the file name, before the .properties extension.

Locales consist of one to three identifiers. Each additional identifier after the first
identifier enables you to indicate a more specific language by specifying the
dialect, variety, or geographic location of the language. The identifiers are
separated with an underscore character.

The simplest locales indicate a human language with a single identifier. This
identifier is the language code of the language that is used in the resource bundle.
For example, the language code en indicates English, and es indicates Spanish. An
English resource bundle might be named resourceBundle_en.properties. The
language code is part of the Java specification.

A more complex locale includes a language code followed by a country code. The
country code indicates a country where the dialect of the language is spoken. For
example, the country code US indicates the United States, and GB indicates Great
Britain. In this way, an American English resource bundle might be named
resourceBundle_en_US.properties, while a British English resource bundle might
be named resourceBundle_en_GB.properties. The country code is part of the Java
specification.

The most complex locale includes a language code, followed by a country code,
followed by a variant code. The variant code defines a more specific dialect or
variety of the language in the resource bundle. For example, you could use the
variant codes A and B to distinguish between two different varieties of Norwegian
spoken in Norway. These two resource bundles might be named
resourceBundle_no_NO_A.properties and resourceBundle_no_NO_B.properties.
Alternately, you could define a standard type of Norwegian as the locale no_NO and
define a variant as no_NO_B. The variant code is not part of the Java specification.

If the user requests a locale that exactly matches a locale in the application, the
resource bundle that represents that locale is the source of the strings that are used
in the application. If the user requests a locale that is more specific than any of the
locales in the application, the application uses a resource bundle with a more
general locale. For example, if the user requests the locale no_NO_B, but the only
available Norwegian locale is no_NO, the locale no_NO is used.

It is good programming practice to include a default resource bundle. The default


resource bundle is used if the user requests no locale or a locale that is more
general than any supported by the application. The default resource bundle has no
locale. If no default resource bundle is specified, or if no locale can be loaded for
the Web page, the page uses the string values that are specified on the page at
definition time.
Related tasks
“Creating a resource bundle” on page 430
“Customizing runtime messages” on page 152
“Localizing text in Web applications” on page 426

Building EGL JSF Web applications 431


Updating portions of a Web page with AJAX requests
Asynchronous JavaScript and XML (AJAX) is a development technique that you
can use to create Web pages that relay information to and from a server only for
the portions of pages that users edit, while still displaying the rest of the page.
This technique can make Web applications faster and more efficient than if an
entire page had to reload after each user action. You can set up an EGL-controlled
JSP file to call the JSF Handler’s onPreRenderFunction and provide a limited
update to the page.

Setting up a JSP file and a JSF Handler to use AJAX requests involves these general
steps:
1. Create the page and JSF Handler.
2. Design the page and populate the page with JSF controls that are bound to
variables and functions in the JSF Handler.
3. Indicate the area of the page that you want to change as a result of the AJAX
request. No other part of the page will be affected.
4. On the page, indicate the user event that will trigger the AJAX request, such as
selecting or moving away from a particular text control.
5. Define the request to send from the page to the JSF Handler, including the type
of request (refresh, submit, or external) and any parameters to include with the
request.
6. Write code in the JSF Handler to process the request.

The following is the life cycle of a typical AJAX page in EGL:


1. The servlet renders the complete page, running the functions indicated by the
onConstructionFunction, onPreRenderFunction, and onPostRenderFunction
JSF Handler properties, as applicable.
2. The servlet sends the page to the browser.
3. The user begins to fill out the input fields on the page.
4. The user triggers the AJAX request.
5. The browser sends the request to the servlet, including the parameters specified
in the request.
6. The servlet calls the function in the JSF Handler indicated by the
onPreRenderFunction property, providing this function with the parameters in
the request.
7. The onPreRenderFunction function runs, updating controls in the area on the
page specified by the AJAX request.
8. The servlet renders the portion of the page specified by the AJAX request and
updates this portion of the page in the browser.
9. The cycle of AJAX requests continues until the user goes to another page, either
by clicking a link or by triggering a forward statement in the JSF Handler.

There are three types of AJAX requests available to Web pages in EGL:
Refresh
This type of request prompts the servlet to update the values of the
controls in a specified area of the page; however, it does not provide
information on the state of the page to the JSF Handler. In other words, if
the user changes the value of input controls on the page, the JSF Handler
is not aware of the changes; the variables in the JSF Handler are not

432 EGL Programmer’s Guide


updated to match the page controls to which the variables are bound. This
limitation reduces the amount of data sent in the request, making the
request more modular and efficient.
If the JSF Handler needs information from the page to complete the refresh
request, you can add one or more parameters to the request. The JSF
Handler receives these parameters along with the request, but as before,
the variables in the JSF Handler are not updated to the new values of the
controls to which the variables are bound. For more information, see
“Updating a page with a refresh request” on page 436.
Submit
This type of request prompts the servlet to update the values of the
controls in a specified area of the page, as well as to update the values of
the variables in the JSF Handler. Unlike what happens in the refresh
request, the submit request causes all of the variables in the JSF Handler to
be set to the current values of the components to which the variables are
bound. Therefore, it is not necessary to pass parameters with a Submit
request, because all of the variables are updated to match the current state
of the page. For more information, see “Updating a page with a submit
request” on page 439.
External
This type of request prompts the servlet to update the content in a
specified area of the page with content from a different page. For more
information, see “Updating a page with a portion of another page” on
page 442.

The J2EELib.getQueryParameter() system function retrieves the parameters from


the AJAX request, if there are any. You can also use this function to detect whether
the onPreRenderFunction function has been called as the result of an AJAX refresh
or submit request by checking the value of the parameter $$ajaxmode. Any value
other than NULL indicates that the function has been called as the result of an
AJAX refresh or submit request:
if (J2EELib.getQueryParmeter("$$ajaxmode") == null)
//Not the result of an AJAX refresh or submit request
//May be the result of an AJAX external request or
else
//The result of an AJAX request.
end

Example

This example uses an AJAX refresh request to perform simple mathematical


operations like a calculator. The page shows two input controls and a combo box
with mathematical operations. The AJAX request, triggered by the combo box,
passes the selected operation and the two input controls to the
onPreRenderFunction of the JSF Handler, which performs the mathematical
operation and updates an output control showing the answer.

The page might look like this example:

Building EGL JSF Web applications 433


The following is the code of the JSP file:
<html>
<head>
<title>calculatorPage</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="theme/stylesheet.css"
title="Style">
</head>
<f:view>
<body>
<hx:scriptCollector id="scriptCollector1"
preRender="#{calculatorPage._preRender}"
postRender="#{calculatorPage._postRender}">

<h:form id="form1" styleClass="form">


<TABLE>
<TBODY>
<tr>
<td align="left">Field1:</td>
<td style="width:5px"></td>
<td>
<h:inputText id="input1" value="#{calculatorPage.field1}"
binding="#{calculatorPage.field1_Ref}" styleClass="inputText">
</h:inputText>
</td>
</tr>
<tr>
<td align="left">Field2:</td>
<td style="width:5px"></td>
<td>
<h:inputText id="input2" value="#{calculatorPage.field2}"
binding="#{calculatorPage.field2_Ref}" styleClass="inputText">
</h:inputText>
</td>
</tr>
<tr>
<td align="left">Operation:</td>
<td style="width:5px"></td>
<td>
<h:selectOneMenu id="operationComboBox"
styleClass="selectOneMenu" value="#{calculatorPage.operation}">
<f:selectItem itemValue="add" itemLabel="add" />

434 EGL Programmer’s Guide


<f:selectItem itemValue="subtract" itemLabel="subtract" />
<f:selectItem itemValue="multiply" itemLabel="multiply" />
<f:selectItem itemValue="divide" itemLabel="divide" />
</h:selectOneMenu>
<hx:behavior event="onblur"
target="operationComboBox" behaviorAction="get"
targetAction="updatablePanel"></hx:behavior></td>
</tr>
<tr>
<td align="left">Output:</td>
<td style="width:5px"></td>
<td>
<h:panelGroup id="updatablePanel" styleClass="panelGroup">
<h:outputText id="output" value="#{calculatorPage.output}"
binding="#{calculatorPage.output_Ref}" styleClass="outputText">
</h:outputText>
</h:panelGroup>
<hx:ajaxRefreshRequest id="ajaxRefreshRequest1"
target="updatablePanel" params="input1;input2;operationComboBox">
</hx:ajaxRefreshRequest>
</td>
</tr>

</TBODY>
</TABLE>
</h:form>
</hx:scriptCollector>
</body>
</f:view>
</html>

The following is the code of the JSF Handler that goes with this page:
package jsfhandlers;

handler calculatorPage type JSFHandler


{onPreRenderFunction = onPreRender,
view = "calculatorPage.jsp"}

field1 float;
field2 float;
operation string;
output string;

function onPreRender()

if (J2EELib.getQueryParameter("$$ajaxmode") == null)
output = "Enter values and an operation.";
else
calculateAnswer();
end

end

function calculateAnswer()
param1 float = J2EELib.getQueryParameter("input1");
param2 float = J2EELib.getQueryParameter("input2");

case (J2EELib.getQueryParameter("operationComboBox"))
when ("add")
output = param1 + param2;
when ("subtract")
output = param1 - param2;
when ("multiply")
output = param1 * param2;
when ("divide")

Building EGL JSF Web applications 435


output = param1 / param2;
end
end
end
Related tasks
“Updating a page with a refresh request”
“Updating a page with a submit request” on page 439
“Updating a page with a portion of another page” on page 442
Related reference
getQueryParameter()

Updating a page with a refresh request


The refresh type of AJAX request prompts the servlet to update the values of the
controls in a specified area of the page. However, the refresh request does not
update the variables in the JSF Handler to match the controls on the page. In this
way, this type of request is intended to be modular and efficient.

With this type of request, you specify an area of the page to be updated, an event
to trigger the request, and optionally any parameters to be passed along with the
request. Then, you configure the JSF Handler’s onPreRenderFunction to update
the specified part of the page.

Follow these steps to add an AJAX refresh request to a Web page. The following
steps assume that you have a JSF Handler with variables bound to controls on a
Web page:
1. On the Web page, indicate the area of the page that you want to update with
the AJAX request by creating a JSF panel control on the page.
AJAX requests in EGL can update only the parts of the page within a JSF panel
control. JSF panel controls serve mainly as containers and organizers for other
JSF controls. The Panel - Group Box control, found in the Enhanced Faces
Components drawer of the Palette view, is a good control to use because it is
only a container and is not visible on the page.
2. Set the ID attribute of the panel control to a value that is unique on the page.
You will need to specify this ID in the AJAX request.
3. Place the JSF controls that you want to update inside the panel control and
make sure that the controls are bound to EGL variables.
The code of the panel control might look like the following example. In this
case, only a single output control is within the panel.
<h:panelGrid id="updatablePanel" styleclass="panelGrid">
<h:outputText id="textToUpdate" value="#{myPage.message}"
binding="#{myPage.message_Ref}" styleClass="outputText" />
</h:panelGrid>
4. Set the ID attributes of any controls on the page that you want to pass as
parameters in the request. These controls do not need to be within the panel
control, but their ID attributes must be unique on the page, and they must be
input controls.
5. Specify the user event that will trigger the AJAX request.
Do this by adding a JSF behavior to an input control on the page and then
selecting an event to trigger the request. The control containing the behavior
does not need to be within the panel control, but only input controls can
trigger requests.

436 EGL Programmer’s Guide


For example, you can make the AJAX request occur when the user moves the
focus into a particular control. In this case, you use the onFocus event. To
perform the request when the user moves focus away from a particular control,
you use the onBlur event. Other commonly used events include onClick,
onMouseOver, and onSelect.
a. On the Web page, select the input control that you want to use as the
trigger.
b. With the control selected, open the Quick Edit view.
c. In the Quick Edit view, select the event, such as onBlur, from the left side of
the view.
d. Select the Use pre-defined behavior check box.
e. In the Action list, select Invoke Ajax behavior on the specified tag.
f. In the Target list, select the ID of the panel you want to update.
Now the behavior to trigger the AJAX request is attached to the control. For
example, if you attach a behavior to an input text control and set it to use the
onBlur event, the code on the page might look like this:
<h:inputText id="nameText" value="#{myPage.name}"
binding="#{myPage.name_Ref}" styleClass="inputText" >
<hx:behavior event="onblur" id="behavior1"
behaviorAction="get" targetAction="updatablePanel">
</hx:behavior>
</h:inputText>

The behavior might look like this example:

6. Create the request by specifying the panel to update and the parameters for the
request:
a. On the Web page, select the panel control.
b. With the panel selected, open the Properties view.
c. On the properties view, go to the Ajax tab under the type of panel control.
d. On the Ajax tab, select the Allow Ajax updates check box.
e. Click Refresh as the type of request.
f. Under the types of requests, click the button labeled Click to edit Ajax
request properties.

Building EGL JSF Web applications 437


g. In the Target list, select the ID attribute of the panel you want to update.
h. Add parameters to the request by clicking one of the Add Parameter
buttons:
The parameters in the table labeled Parameter values sent from the
browser refer to the value of input controls on the page. For example, if
you want to pass the current value of an input control on the page as a
parameter, add that input control’s ID here.
The parameters in the table labeled Parameter values calculated on the
server refer either to literal values you type here or to the value of variables
in the JSF Handler.
For example, if you choose to pass the value of an input control on the page,
the new request might look like this:
<hx:ajaxRefreshRequest id="ajaxRefreshRequest1"
target="updatablePanel" params="nameText">
</hx:ajaxRefreshRequest>

In the editor, the AJAX request might look like this example:

7. In the JSF Handler for the page, configure the onPreRenderFunction to accept
the request.
Because the onPreRenderFunction runs when the page first loads as well as on
every AJAX request, you might want to detect which case has caused the
function to run. You can do this by testing for the value of the parameter
$$ajaxmode. When the function runs as the result of a normal page loading
operation, this parameter has a null value; when the function runs as the result
of an AJAX request, the parameter will contain a value.
function onPreRender()

if (J2EELib.getQueryParameter("$$ajaxmode") == NULL)
//The page is loading for the first time.
//Perform page loading operations here.
else
//The page is loading as the result of an AJAX request.
//Perform AJAX updating operations here.
end

end

438 EGL Programmer’s Guide


8. Once you have determined that the onPreRenderFunction has been invoked as
the result of an AJAX request, you can update the controls on the page by
setting the values of the variables bound to those controls. You can update only
the controls within the panel in the request.
You can retrieve the parameters passed with the request by using the
J2EELib.getQueryParameter() system function. For example, if you passed the
value of a text control with the ID nameText, you can retrieve the value of that
parameter with the following code:
outputText = "Hello "::J2EELib.GetQueryParameter("nameText")::"!";

For an example of an AJAX refresh request, see “Updating portions of a Web page
with AJAX requests” on page 432.
Related tasks
“Updating portions of a Web page with AJAX requests” on page 432
Asynchronous JavaScript and XML (AJAX) is a development technique that you
can use to create Web pages that relay information to and from a server only
for the portions of pages that users edit, while still displaying the rest of the
page. This technique can make Web applications faster and more efficient than
if an entire page had to reload after each user action. You can set up an
EGL-controlled JSP file to call the JSF Handler’s onPreRenderFunction and
provide a limited update to the page.
“Updating a page with a submit request”
“Updating a page with a portion of another page” on page 442

Updating a page with a submit request


The submit type of AJAX request works in a way that is similar to the action that
occurs when a user clicks a button on an EGL-controlled Web page: control passes
to the JSF Handler and all the variables in the JSF Handler are updated to match
the values of the JSF controls. Unlike a refresh request, there is no need to pass
parameters because all of the variables in the JSF Handler are updated with the
current values of the control. However, like a refresh request, only the controls
within a JSF panel control are updated.

With this type of request, you specify an area of the page to be updated and an
event to trigger the request. Then, you configure the JSF Handler’s
onPreRenderFunction to update the specified part of the page.

Follow these steps to add an AJAX submit request to a Web page. The following
steps assume that you have a JSF Handler with variables bound to controls on a
Web page:
1. On the Web page, indicate the area of the page that you want to update with
the AJAX request by creating a JSF panel control on the page.
AJAX requests in EGL can update only the parts of the page within a JSF panel
control. JSF panel controls serve mainly as containers and organizers for other
JSF controls. The Panel - Group Box control, found in the Enhanced Faces
Components drawer of the Palette view, is a good control to use because it is
only a container and is not visible on the page.
2. Set the ID attribute of the panel control to a value that is unique on the page.
You will need to specify this ID in the AJAX request.
3. Place the JSF controls that you want to update inside the panel control and
make sure that the controls are bound to EGL variables.
The code of the panel control might look like the following example. In this
case, only a single output control is within the panel.
Building EGL JSF Web applications 439
<h:panelGrid id="updatablePanel" styleclass="panelGrid">
<h:outputText id="textToUpdate" value="#{myPage.message}"
binding="#{myPage.message_Ref}" styleClass="outputText" />
</h:panelGrid>
4. Specify the user event that will trigger the AJAX request.
Do this by adding a JSF behavior to an input control on the page and then
selecting an event to trigger the request. The control containing the behavior
does not need to be within the panel control, but only input controls can
trigger requests.
For example, you can make the AJAX request occur when the user moves the
focus into a particular control. In this case, you use the onFocus event. To
perform the request when the user moves focus away from a particular control,
you use the onBlur event. Other commonly used events include onClick,
onMouseOver, and onSelect.
a. On the Web page, select the input control that you want to use as the
trigger.
b. With the control selected, open the Quick Edit view.
c. In the Quick Edit view, select the event, such as onBlur, from the left side of
the view.
d. Select the Use pre-defined behavior check box.
e. In the Action list, select Invoke Ajax behavior on the specified tag.
f. In the Target list, select the ID of the panel you want to update.
Now the behavior to trigger the AJAX request is attached to the control. For
example, if you attach a behavior to an input text control and set it to use the
onBlur event, the code on the page might look like this:
<h:inputText id="nameText" value="#{myPage.name}"
binding="#{myPage.name_Ref}" styleClass="inputText" >
<hx:behavior event="onblur" id="behavior1"
behaviorAction="get" targetAction="updatablePanel">
</hx:behavior>
</h:inputText>

The behavior might look like this example:

5. Create the request by specifying the panel to update:


a. On the Web page, select the panel control.
440 EGL Programmer’s Guide
b. With the panel selected, open the Properties view.
c. On the Properties view, go to the Ajax tab under the type of panel control.
d. On the Ajax tab, select the Allow Ajax updates check box.
e. Click Submit as the type of request.
The Properties view looks like this example:

f. Under the types of requests in the Properties view, click the button labeled
Click to edit Ajax request properties.
g. In the Target list, select the ID attribute of the panel you want to update.
For example, the new request might look like this:
<hx:ajaxRefreshSubmit id="ajaxRefreshSubmit1"
target="updatablePanel">
</hx:ajaxRefreshSubmit>
6. In the JSF Handler for the page, configure the onPreRenderFunction to accept
the request.
Because the onPreRenderFunction runs when the page first loads as well as on
every AJAX request, you might want to detect which case has caused the
function to run. You can do this by testing for the value of the parameter
$$ajaxmode. When the function runs as the result of a normal page loading
operation, this parameter has a null value; when the function runs as the result
of an AJAX request, the parameter will contain a value.
function onPreRender()

if (J2EELib.getQueryParameter("$$ajaxmode") == NULL)
//The page is loading for the first time.
//Perform page loading operations here.
else
//The page is loading as the result of an AJAX request.

Building EGL JSF Web applications 441


//Perform AJAX updating operations here.
end

end
7. Once you have determined that the onPreRenderFunction has been called as
the result of an AJAX request, you can update the controls on the page by
setting the values of the variables bound to those controls. You can update only
the controls within the panel in the request.
Related tasks
“Updating portions of a Web page with AJAX requests” on page 432
Asynchronous JavaScript and XML (AJAX) is a development technique that you
can use to create Web pages that relay information to and from a server only
for the portions of pages that users edit, while still displaying the rest of the
page. This technique can make Web applications faster and more efficient than
if an entire page had to reload after each user action. You can set up an
EGL-controlled JSP file to call the JSF Handler’s onPreRenderFunction and
provide a limited update to the page.
“Updating a page with a refresh request” on page 436
“Updating a page with a portion of another page”

Updating a page with a portion of another page


The external type of AJAX request prompts the servlet to replace a specified area of
one page with a specified area of a second page. Like the refresh type of request,
you can pass parameters to the second page. The onPreRenderFunction function
can receive these parameters with the J2EELib.getQueryParameter system
function.

With this type of request, you specify an area of the first page to be updated, an
event to trigger the request, and optionally any parameters to be passed along with
the request. Unlike the other types of request, the external AJAX request goes to
another page, so the request must specify the page to send the request to and the
control from that page to use in place of the first page.

Using this type of AJAX request involves creating two pages:


v A source page from which the content will be taken
v A target page into which the content will be placed
Follow these steps to add an AJAX external request to a Web page:
1. Create a source page to hold the content that you want to use on another page:
a. Create a JSP file and JSF Handler as you would ordinarily create an
EGL-controlled Web page.
b. On this page, add a panel control and give it an ID unique on the page.
c. Add the content into the panel control. The request will instruct the servlet
to take the content from this panel and use it on another page.
d. In the JSF Handler for the page, configure the onPreRenderFunction to
accept the request.
Because the onPreRenderFunction runs when the page first loads as well as
on every AJAX request, you might want to detect which case has caused the
function to run. You can do this by testing for the value of the parameter
$$ajaxmode. When the function runs as the result of a normal page loading
operation, this parameter has a null value; when the function runs as the
result of an AJAX request, the parameter will contain a value.

442 EGL Programmer’s Guide


function onPreRender()

if (J2EELib.getQueryParameter("$$ajaxmode") == NULL)
//The page is loading for the first time.
//Perform page loading operations here.
else
//The page is loading as the result of an AJAX request.
//Perform AJAX updating operations here.
end

end
e. Once you have determined that the onPreRenderFunction has been
invoked as the result of an AJAX request, you can update the controls on
the page by setting the values of the variables bound to those controls. You
can update only the controls within the panel in the request.
You can retrieve the parameters passed with the request by using the
J2EELib.getQueryParameter() system function. For example, if you passed
the value of a text control with the ID nameText, you can retrieve the value
of that parameter with the following code:
outputText = "Hello "::J2EELib.GetQueryParameter("nameText")::"!";
2. Create the target page into which the content will be placed:
a. Create a JSP file and JSF Handler as you would ordinarily create an
EGL-controlled Web page.
b. On this page, add a panel control and give it an ID unique on the page. The
contents of this panel will be replaced with the panel on the source page.
c. Optionally, add JSF controls to the panel. The panel can be blank or
populated with controls when the AJAX request replaces it with the panel
on the source page.
3. Specify the user event that will trigger the AJAX request.
Do this by adding a JSF behavior to an input control on the page and then
selecting an event to trigger the request. The control containing the behavior
does not need to be within the panel control, but only input controls can
trigger requests.
For example, you can make the AJAX request occur when the user moves the
focus into a particular control. In this case, you use the onFocus event. To
perform the request when the user moves focus away from a particular control,
you use the onBlur event. Other commonly used events include onClick,
onMouseOver, and onSelect.
a. On the Web page, select the input control that you want to use as the
trigger.
b. With the control selected, open the Quick Edit view.
c. In the Quick Edit view, select the event, such as onBlur, from the left side of
the view.
d. Select the Use pre-defined behavior check box.
e. In the Action list, select Invoke Ajax behavior on the specified tag.
f. In the Target list, select the ID of the panel you want to update.
Now the behavior to trigger the AJAX request is attached to the control. For
example, if you attach a behavior to an input text control and set it to use the
onBlur event, the code on the page might look like this:

Building EGL JSF Web applications 443


<h:inputText id="nameText" value="#{myPage.name}"
binding="#{myPage.name_Ref}" styleClass="inputText" >
<hx:behavior event="onblur" id="behavior1"
behaviorAction="get" targetAction="updatablePanel">
</hx:behavior>
</h:inputText>

The behavior might look like this example:

4. Create the request by specifying the panel to update and the parameters for the
request:
a. On the target page, select the panel control.
b. With the panel selected, open the Properties view.
c. On the properties view, go to the Ajax tab under the type of panel control.
d. On the Ajax tab, select the Allow Ajax updates check box.
e. Click External as the type of request.
f. Under the types of requests, click the button labeled Click to edit Ajax
request properties.
g. In the Target list, select the ID attribute of the panel on the target page you
want to update.
h. In the URL field, enter the relative path to the source page. Be sure to use
the correct extension of .faces or .jsp for the target page, as explained in
“Running a Web page on a server” on page 448.
i. In the Source field, enter the ID of the panel control on the source page. The
contents of this panel will replace the contents of the panel on the target
page.
If you leave this field blank, the request will retrieve the entire source page
(that is, everything within the <body> tag), not just the panel control.
j. Add parameters to the request by clicking one of the Add Parameter
buttons:
The parameters in the table labeled Parameter values sent from the browser
refer to the value of input controls on the target page. For example, if you
want to pass the current value of an input control on the page as a
parameter, add that input control’s ID here.

444 EGL Programmer’s Guide


The parameters in the table labeled Parameter values calculated on the
server refer either to literal values you type here or to the value of variables
in the source page’s JSF Handler.
For example, if you choose to pass the value of an input control on the page,
the new request might look like this:
<hx:ajaxExternalRequest id="ajaxExternalRequest1"
target="sourcePanel" params="nameText"
href="sourcePage.faces" soure="replacePanel">
</hx:ajaxExternalRequest>

Now when the request is triggered on the target page, the servlet will pass the
AJAX external request to the source page, along with any parameters. The servlet
invokes the onPreRenderFunction function on the source page and when that
function has finished, it removes the panel from the source page and inserts it into
the target page.

Example

The following example shows two pages that work together with an AJAX external
request as explained in this topic. The target page includes a group of check boxes
that allow the user to select a value. The AJAX request passes this value to the
source page, which renders a replacement panel based on the value of the
message.

The page and its request look like this example:

The following is the code of the target page, named targetPage.jsp:


<html>
<head>
<title>targetPage</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="theme/stylesheet.css"
title="Style">
</head>
<f:view>
<body>
<hx:scriptCollector id="scriptCollector1">

Building EGL JSF Web applications 445


<h:form id="form1" styleClass="form">

<h:panelGroup id="targetPanel" styleClass="panelGroup">

<h:outputText id="promptMessage" styleClass="outputText"


value="What is your favorite type of friut?">
</h:outputText>

<h:selectOneRadio disabledClass="selectOneRadio_Disabled"
enabledClass="selectOneRadio_Enabled" id="fruitName"
styleClass="selectOneRadio">
<f:selectItem itemValue="bananas" itemLabel="bananas" />
<f:selectItem itemValue="apples" itemLabel="apples" />
<f:selectItem itemValue="grapes" itemLabel="grapes" />
</h:selectOneRadio>

<hx:behavior event="onchange" target="fruitName"


behaviorAction="get" targetAction="targetPanel">
</hx:behavior>

</h:panelGroup>

<hx:ajaxExternalRequest id="ajaxExternalRequest1"
target="targetPanel" href="sourcePage.faces"
source="sourcePanel" params="fruitName">
</hx:ajaxExternalRequest>

</h:form>
</hx:scriptCollector>
</body>
</f:view>
</html>

The following are some technical details about the target page:
v The tag <h:panelGroup> is the JSF panel control that will be updated. It has the
ID attribute targetPanel.
v The tag <h:outputText> is a JSF output text control that displays a static
message as a prompt.
v The tag <h:selectOneRadio> is a JSF check box group control that offers three
options. This check box group has the ID attribute fruitName, which will be the
parameter passed along with the request.
v The tag <hx:behavior> specifies the event that triggers the AJAX request. The
behavior’s attributes point to the ID of the panel control and the radio button
group. In this case, the event is onchange, which means that the AJAX request is
triggered when the selection in the radio button group changes.
v The tag <hx:ajaxExternalRequest> defines the AJAX request itself. This tag’s
target attribute points to the panel control, indicating that this request will run
when the panel’s event is triggered. The other attributes of the request point to
the location of the source page, the ID of the panel to retrieve from the source
page, and the parameter to pass with the request. In this case, the request
includes the selection in the check box group as a parameter.

The following is the JSF Handler that would go with this page, named
targetPage.egl:
package jsfhandlers;

handler targetPage type JSFHandler


{view = "targetPage.jsp"}
end

446 EGL Programmer’s Guide


No special code is required in the JSF Handler for the target page. Because this
example uses an external request, the request goes to the source page, so that
page’s JSF Handler will process the request.

Following is the code of the source page, named sourcePage.jsp:


<html>
<head>
<title>sourcePage</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="theme/stylesheet.css"
title="Style">
</head>
<f:view>
<body>
<hx:scriptCollector id="scriptCollector1"
preRender="#{sourcePage._preRender}" postRender="#{sourcePage._postRender}">

<h:panelGroup id="sourcePanel" styleClass="panelGroup">


<h:outputText id="text1" styleClass="outputText"
value="#{sourcePage.message}" binding="#{sourcePage.message_Ref}">
</h:outputText>
</h:panelGroup>

</hx:scriptCollector>
</body>
</f:view>
</html>

This page contains a panel control that will be used to replace the panel on the
target page. In this case, the panel contains a single output field that is bound to a
variable in the page’s JSF Handler. The page looks like this:

Following is the JSF Handler that would go with this page, named sourcePage.egl:
package jsfhandlers;

handler sourcePage type JSFHandler


{onPreRenderFunction = onPreRender,

Building EGL JSF Web applications 447


view = "sourcePage.jsp"}

message string = "No value set";

function onPreRender()
if (J2EELib.getQueryParameter("fruitName") != null)
case (J2EELib.getQueryParameter("fruitName"))
when ("bananas")
message = "Bananas are a yellow tropical fruit.";
when ("grapes")
message = "Grapes grow on vines and can be made into wine.";
when ("apples")
message = "Apples grow on trees in many parts of the world";
end
end
end
end

This JSF Handler’s onPreRenderFunction function first detects whether the


function has been called as the result of an AJAX request. If so, the JSF Handler
updates the text control on the page to show a message based on the value of the
parameter passed along with the request. The request then uses the contents of the
panel on the source page to replace the contents of the panel on the target page.
Related tasks
“Updating portions of a Web page with AJAX requests” on page 432
Asynchronous JavaScript and XML (AJAX) is a development technique that you
can use to create Web pages that relay information to and from a server only
for the portions of pages that users edit, while still displaying the rest of the
page. This technique can make Web applications faster and more efficient than
if an entire page had to reload after each user action. You can set up an
EGL-controlled JSP file to call the JSF Handler’s onPreRenderFunction and
provide a limited update to the page.
“Updating a page with a submit request” on page 439
“Updating a page with a refresh request” on page 436

Running a Web page on a server


When you are working with a Web page in EGL, you can run the page on a server
to see how it will look when deployed.

This task has the following prerequisites:


v An EGL Web project with at least one Web page.
v A server defined in the workbench. See Creating a server.

To run a Web page on a server in the workbench:


1. Save any unsaved files and generate the project. Note that in past versions of
EGL, JSF Handlers were generated automatically when you saved the file, but
now you can choose whether to generate Handlers automatically or not. See
“Setting generation preferences” on page 180.
2. If the server is already running, publish the new versions of your files to the
server by right-clicking the server in the Servers view and then clicking
Publish.
If the server is not already running, publishing will happen automatically when
you run the page. Depending on the server and its settings, it might publish
automatically when you save changes to the Web project; in this case, wait until
the server’s status is listed as Synchronized.

448 EGL Programmer’s Guide


3. In the Project Explorer view, right-click the JSP file (not the EGL source file
with the JSF Handler) and then click Run As → Run on Server. If you have not
yet defined a default server for the project, the Run On Server window opens.
4. In the Run On Server window, select a server to use.
5. If you want to use this server each time your run a page, select the Set server
as project default check box.
6. Click Finish. The server starts, if necessary, and the page opens in the internal
Web browser of the workbench. As long as the server is running, you can copy
the URL from the internal Web browser and paste it into the address field of
any external Web browser on your system to view the page in a different
browser.

The URL of the Web page is set by the JavaServer Faces (JSF), which controls the
run-time display of the JSP files. For example, if you run a Web page named
myPage.jsp in a project named myProject, the internal Web browser might open to
the following URL:
http://hostname:portnumber/myProject/faces/myPage.jsp

You may also see this URL:


http://hostname:portnumber/myProject/myPage.faces

In each case, hostname refers to the name of your local server, such as localhost,
and portnumber refers to the port of that server. Note that in the first case, JSF adds
the /faces prefix to the URL. In the other case, it adds the .faces extension to the
file name, replacing the actual .jsp extension. These URLs are equivalent and refer
to the same JSP file and JSF Handler part.

However, conflicts between these two different URLs can cause links to break
when you test Web pages in the workbench. If the page opens as
myProject/myPage.faces, relative links to a page named myProject/
myOtherPage.jsp will not work because JSF sets the location for the target page as
myProject/myOtherPage.faces and myProject/faces/myOtherPage.jsp. In this case,
you must either change the link to myProject/faces/myOtherPage.jsp or
myProject/myOtherPage.faces, or open the original page as myProject/faces/
myPage.jsp.

Using the i5/OS integrated Web application server


EGL supports development for the i5/OS integrated Web application server, a
minimal footprint, easy to configure, secure environment for hosting dynamic Web
applications on i5/OS.

The i5/OS integrated Web application server offers an economical alternative to


WAS or Tomcat for the i5/OS environment and allows users to install applications
(WAR or WAB) and configure database connections.

You can deploy the following kinds of EGL applications on the i5/OS integrated
Web application server:
v The application has to be a JSF handler program with or without database
access.
v The application can access the rununit.properties file generated from the project
build descriptor. The properties file contains key-value properties such as
database connection and EGL environment variables, which can be used to affect
the runtime behaviors of the deployed application.

Building EGL JSF Web applications 449


v If the application needs to perform database access, define a Connection ID for
each data source. The Connection ID for the datasource can be configured as
follows:
– You must configure the server instance. The Connection ID can be configured
via the i5/OS integrated Web Application server Admin UI under Resource
Management → Manage Database Connection link. Alternatively, the
Connection ID can be defined manually from a database.properties file in the
conf/override folder in your installation directory.
– If the application does not use the sqlLib.connect() function to dynamically
connect to a datasource (Connection ID), you can specify a datasource
(Connection ID) to be used by the application during generation in the EGL
sqlDB build descriptor option. The option is generated as a property in the
rununit.properties file used at runtime.

The following limitations apply:


v RBD does not support i5/OS integrated Web application server as a Targeted
Runtime when creating an EGL Web project via the New Project wizard.
v Test your Web application with WAS or Tomcat before deploying it.
v EGL Web Services support is not available for this environment
v EGL debug support is not available for this environment.
v EGL support has been tested and verified with i5/OS (V5R4 and V6R1)
integrated Web application server. Other runtime platforms have not been
verified.

Example
The following scenario shows how to deploy a typical JSF handler application to
the i5/OS integrated Web application server.

Create a server instance in i5/OS if one is not available. This example uses the
name EGLi501 for the server instance:
1. Access the remote i5/OS Admin Console GUI from a browser. Authorization
may be required for the access.
2. The IBM Web Administration for i5/OS screen is displayed.
3. Select Create Application Server from Common Tasks and Wizards. Click
Next.
4. On the Select Application Server Version and Type screen, select i5/OS
integrated Web application server. Click Next.
5. On the Specify Application Server Name screen, enter an Application Server
Name such as EGLi501. Click Next.
6. On the Specify Internal Ports screen, click Next to accept the default port
numbers.
7. On the Create a New HTTP Server screen, note the port number to invoke the
server instance during an application test. Click Next to accept the default
values.
8. On the Specify User ID screen, click Next to accept the default port numbers.
9. On the Sample Application screen, click Next.
10. On the Summary screen, click Finish.

If the applications to be installed on the server perform database I/O, define a


connection ID for each database by following these steps:
1. From the i5/OS Admin Console GUI, select the server instance where you want
to install the application (EGLi501 in this example).
450 EGL Programmer’s Guide
2. Select Manage Database Connections under Resource Configuration.
3. On the Manage Database Connections screen, click Create.
4. On the Specify Database Connection Type screen, select the appropriate
connection type from the Database connection type pull-down menu. Enter a
unique identifier (or *Default) for Connection ID. Your application must use
the Connection ID as the datasource when accessing information from the
database. Click Next.
5. On the Specify Database Connection Information screen, provide the following
information:
v The appropriate value for Database location (LOCAL is the default).
v A library name for the DB2 database for Schema name.
v The Connection User ID and Password if required.
Click Next.
6. On the JNDI Name screen, click Next to accept the default name.
7. On the Summary screen, click Finish.
8. The Manage Database Connections screen displays the database connection you
just created, which you can edit or delete.

Copy the WAR file to the i5/OS environment by following these steps:
1. Map a network drive on your local system to access the remote i5/OS system:
>> net use z: \\lp11ut8.rchland.ibm.com\root
2. Create a directory in i5/OS to store the WAR file. For example, make a folder
in the network drive z:
>> md eglwars
3. Copy the local WAR file to the remote i5/OS system:
>> copy d:\genout\EglWebProj.war z:\eglwars

Use the following steps to install an application WAR or WAB file to the server
instance:
1. On the Manage All Servers screen, select the server instance (EGLi501 in this
example), and click Manage Details.
2. On the Manage Integrated Web Application Server screen, click Manage
Installed Applications.
3. On the Manage Installed Applications screen, click Install.
4. On the Install New Application screen, enter the path name of the application
WAR or WAB file, or click Browse to navigate to the file. Click Next.
5. On the Provide options to perform the install screen, click Next to accept the
default values.
6. On the Context Root Port Mapping screen, click Next to accept the default
values.
7. On the Summary screen, click Finish.

Test a JSF handler with the Web Application Server by entering the URL for the JSF
application into a browser in the following form:
http://hostName:portNum/contextRoot/pageName.faces
hostName
The host name for the i5/OS system.
portNum
The port ID for the server instance.

Building EGL JSF Web applications 451


contextRoot
The context root of the installed application.
pageName
The name of the JSF page to be displayed.

The following considerations apply to running test cases in the browser:


v If you use the Firefox browser, some of the JSF data table frames might be
missing on the test pages.
v Do not use JSF prefix servlet mapping in the URL, as in the following:
http://.../faces/MyPage.jsp // do not use
Instead use JSF suffix servlet mapping, as in the following example:
http://.../MyPage.faces // do this instead
Related concepts
“Building EGL JSF Web applications” on page 389
In an EGL JSF Web application, EGL logic parts control Web pages, enabling
you to put data on Web pages, get data from user input on Web pages, and
forward users from page to page.

Using JEE container-managed security


To secure a JSF Web applications, you can use container-managed security, which is
handled by a JEE-compliant Web application server. This topic gives a few details,
including sample login and error JSPs, as well as a list of EGL security-related
functions.

You also may want to review the documentation for your Web application server.

Assigning roles and constraints in web.xml

In JEE security, permission to access Web resources is based on a security role such
as clerk or manager. Each role is a developer-assigned status and is stored in the JEE
deployment descriptor (web.xml) that accompanies the application code. Also
stored in web.xml is a set of constraints that define which Web pages are available
to the users who are ultimately assigned to a given role.

To customize web.xml, do as follows:


1. In your Web project, right click the deployment descriptor and click the Pages
tab
2. In the Login box, specify the authentication method (for example, Form, which
involves use of login and error pages), and specify the related detail (for
example, references to the specific login and error pages)

Creating login and error pages

If you are using the Form authentication method, you can customize the following
JSP pages:
v Sample login JSP
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

452 EGL Programmer’s Guide


<title>Insert title here</title>
</head>
<H1>Login Page</H1>
<body>
<form method="POST" action="j_security_check">
User Name : <input type="text" name="j_username"/>
Password : <input type="password" name="j_password"/>
<input type="submit" value="Login"/>
</form>
</body>
</html>
v Sample error JSP
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<H1>Login Error Page</H1>
<body>
Status = Login Error !!!
</body>
</html>

Assigning users and groups in application.xml

A deployer (usually a system administrator) associates each security role with


specific users and groups. The deployer makes that association by customizing the
EAR project deployment description (application.xml), usually by working at the
Security tab for that file.

Handling issues specific to WebSphere Application Server 6.1

This section mentions issues that are specific to WebSphere Application Server 6.1.
For a more detailed review, see IBM WebSphere Application Server V6.1 Security
Handbook, which is an IBM Redbook (SG24-6316-01) that can be accessed at
http://www.redbooks.ibm.com/abstracts/sg246316.html.

To configure container-managed security in WebSphere Application Server, do as


follows:
1. Open the Administrative Console
2. Click “Security”, then “Secure administration, applications, and infrastructure”
3. Select both “Enable administrative security” and “Enable application security”
4. Choose a realm (for example, LDAP) to use as your user registry and configure
that realm
5. Apply and save your changes

If you are accessing Web Application Server from an Eclipse-based product, do as


follows in Eclipse:
1. Create a new server from the Servers view or open an existing one.
2. In the Security section, select ″Security is enabled on this server″ and fill in the
user ID and password fields. If you have trouble running JEE security, try
changing the server connection type from RMI to SOAP.

Using system functions that support JEE security

Building EGL JSF Web applications 453


The following security-related functions, from the system library J2EELib, are
available in any JSF handler, regardless of the authentication type.
v getAuthenticationType returns the JEE authentication method. If no such
authentication is in use, this function returns an empty string.
The authentication methods used most often are FORM (in which case the user
can log out without ending the browser session); or the more secure
CLIENT_CERT (for client certification, in which case authentication data is
encrypted and, as an option, the server may need to review a security certificate
before deciding whether to accept the data).
v getRemoteUser returns the user’s login ID, if any. If no JEE authentication
method is in use, this function returns an empty string.
v isUserInRole returns a Boolean that indicates whether the user is included in a
specified role. If no authentication is in use, this function returns an empty
string.
A runtime knowledge of a user’s role lets the application direct processing in
accordance with authorization rules.
Related concepts
“Accessing an LDAP-compliant server” on page 190
EGL provides a code sample that you can customize to retrieve security or
other details from a server accessed by way of Lightweight Directory Access
Protocol (LDAP).
Related reference
getAuthenticationType()
getRemoteUser()
isUserInRole()

Accessing the JSF component tree with the source assistant


You can use EGL code to call Java functions that are recognized by JavaServer
Faces (JSF) controls. In this way, you can change the appearance and behavior of
these controls from a JSF Handler. The following example includes EGL code to
access a JSF control:
package jsfhandlers;

import com.ibm.egl.jsf.*;

handler myPage type JSFHandler


{view = "myPage.jsp",
viewRootVar = myViewRoot}

myViewRoot UIViewRoot;
myInputVar string = "Hello";

function changeColor()
myInputField HtmlInputText;
myInputField = viewRoot.findComponent("form1:text1");
myInputField.setStyle("color : red");
end

end

This example assumes an input control on the JSP named text1 that is bound to
the myInputVar variable and a command button on the JSP that is bound to the
changeColor function.

To access a JSF control from a JSF Handler:

454 EGL Programmer’s Guide


1. Make sure that your EGL Web project has support for the JSF component
interface. See “Adding JSF component interface support to an EGL Web
project” on page 464.
2. Create a Web page and add one or more JSF controls to it.
3. Optionally, you might want to change the ID attribute of the JSF controls so
they will be easier to identify. You can change the ID attribute by selecting the
control and typing a meaningful mnemonic that is unique within the page in
the ID field in the Properties view.
4. In the JSF Handler of the page, add the following code. If you create the Faces
JSP file after you add support for the JSF component interface to the project,
this code is added to the JSF Handler’s file automatically.
v Add the following import statement:
import com.ibm.egl.jsf.*
The packages that are imported by this statement contain a group of
ExternalType parts which provide access to Java code in the JSF controls. You
do not need to edit these parts.
v Within the JSF Handler of the page, declare a variable of the type
UIViewRoot, as in this example:
myViewRoot UIViewRoot;
v Specify the name of the UIViewRoot variable in the viewRootVar JSF
Handler property:
handler myPage type JSFHandler
{view = "myPage.jsp",
viewRootVar = myViewRoot}
5. On a blank line inside a function in the JSF Handler, press Ctrl+Shift+Z. The
EGL Source Assistant window opens, displaying the JSF controls on the page.
6. In the EGL Source Assistant window, select the JSF control you want to access.
You can use the IDs or control types to find the control you want, or you can
hover the mouse over the controls to see their attributes.
7. Click OK.
The EGL source assistant adds two lines of EGL code to the JSF Handler:
v The first line of code defines an EGL variable of the ExternalType part that
matches the JSF control that you selected. In the previous example, a variable
of the type HtmlInputText is defined to access a JSF input text control, using
this code:
myInputField HtmlInputText;
v The second line of code associates that variable with the JSF control. In the
above example, the variable is associated with a JSF input text control named
text1, which is located within a form named form1, using this code:
myInputField = myViewRoot.findComponent("form1:text1");
8. Use the variable to change the JSF control. For example, the following code
uses the setStyle function to change the text in an input control to the color
red:
myInputField.setStyle("color : red");
When this code runs, the style of the input control is changed. In this example,
the HTML code displayed by the browser looks like this:
<input id="form1:text1" type="text" name="form1:text1" style="color : red" />
The related topics in this section give some other examples of operations that
you can perform on JSF controls in this way. To see the full list of operations
you can call on a given control, refer to the functions of the ExternalType parts
in the com.ibm.egl.jsf package.

Building EGL JSF Web applications 455


Following are some notes about accessing JSF controls with EGL code:
v For the complete list of JSF functions that are accessible in EGL, open the file
FacesHtmlComponent.egl in the package com.ibm.egl.jsf. This file is added to
your project when you add support for the JSF component interface. The
functions are briefly explained in comments to this file. For more detailed
information, see the documentation for Faces controls.
v When passing a parameter to one of these functions, be sure to pass the correct
data type. Because many of the parameters passed to these functions are
inserted into HTML attributes, they must be passed as EGL string variables,
even if the name of the function suggests that the parameter is a numerical or
boolean value.
For example, the setWidth function sets the width of a control in pixels, or in a
percentage of its original size if the percent (%) symbol is appended. Because
this parameter is a measurement, it might seem to take a numeric data type as a
parameter. However, this function must receive a string. To set the width of a
control to 300 pixels, you must pass a string variable with the value ″300″.
v Because many of the functions set or return information from HTML attributes,
you should be aware of the HTML attributes that are connected to the functions
that you are using. You might change an HTML attribute that is needed for the
page to work correctly. For example, if you change the style class of a control as
in Changing the style class of a JSF control, that new style class of the control must
be available to the page in a CSS file or style tag, or else the control might not
display properly. Be sure to test any changes that you make to Web pages. The
comments in the FacesHtmlComponent.egl file note the functions that change
HTML attributes directly.
v In most cases, the changes that you make to the JSF controls are not cumulative.
For example, if you set a control’s text to red with the code
myComponent.setStyle("color: red"); and then set the same control’s text to
bold with the code myComponent.setStyle("font-weight: bold");, the text will
be bold but not red, because the change to bold overwrites the change to red.
To add several changes to a JSF control, retrieve the current state of the control
and append the new data, paying attention to how the list of changes is
delimited. For example, use the following code to change a control’s text to bold
and red, without overwriting any previous changes to that control’s style:
myStyleString string;
myStyleString = myComponent.getStyle() + "; color: red; font-weight: bold";
myComponent.setStyle(myStyleString);
v You cannot access JSF controls in this way in the onConstructionFunction and
onPreRenderFunction functions in the Handler. The function specified in the
onPostRenderFunction property can access the JSF component tree. However,
because this function is called after the page is rendered and sent to the browser,
the changes to the page will not be visible to the user until the page is refreshed.

There are many different changes that you can make to JSF controls. See the
related tasks for some examples.
Related tasks
“Changing the target of a JSF link” on page 457
“Changing the style of a JSF control” on page 458
“Changing the style class of a JSF control” on page 459
“Setting event handlers for a JSF control” on page 460
“Setting the size of a JSF image” on page 461
“Enabling or disabling JSF controls” on page 462

456 EGL Programmer’s Guide


“Setting JSF data table properties” on page 463
Related reference
Component tree access
viewRootVar

Changing the target of a JSF link


You can change the target attribute of a JavaServer Faces (JSF) link from a JSF
Handler. For example, you can set the target attribute of a link to _blank to make
that link open in a new browser window.

This task has the following prerequisites:


v Your EGL Web project must have support for the JSF component interface. See
“Adding JSF component interface support to an EGL Web project” on page 464.
v The JSF Handler that is associated with the Web page must have the following
import statement:
import com.ibm.egl.jsf.*
v You must declare a variable of the type UIViewRoot within the JSF Handler.
v You must specify the name of the of the UIViewRoot variable in the
viewRootVar JSF Handler property.
For more information on these prerequisites, see “Accessing the JSF component
tree with the source assistant” on page 454.

To change the target attribute of a JSF link from a JSF Handler:


1. On a blank line inside a function in the JSF Handler, press Ctrl+Shift+Z. The
EGL Source Assistant window opens, displaying the JSF controls on the page.
2. In the EGL Source Assistant window, select the JSF control that you want to
access.
3. Click OK.
The EGL source assistant adds two lines of EGL code to the JSF Handler. The
first line defines an EGL variable of the type that matches the JSF link that you
selected. The second line associates that variable with the JSF link. For example,
the code might look like this:
linkEx1 HtmlOutputLink;
linkEx1 = myViewRoot.findComponent("form1:linkEx1");
4. Using the EGL variable that is created by the source assistant, change the target
of the link with the setTarget() function. For example, to make the link open
in a new window, add this code:
linkEx1.setTarget("_blank");
Related tasks
“Adding JSF component interface support to an EGL Web project” on page 464
“Changing the style class of a JSF control” on page 459
“Changing the style of a JSF control” on page 458
“Enabling or disabling JSF controls” on page 462
“Setting the size of a JSF image” on page 461
“Setting event handlers for a JSF control” on page 460
“Setting JSF data table properties” on page 463
Related reference
Component tree access
viewRootVar

Building EGL JSF Web applications 457


Changing the style of a JSF control
You can change the appearance of a JavaServer Faces (JSF) control with EGL code,
such as changing the text color. To make a larger change in the control’s
appearance by changing its style class, see Changing the style class of a JSF control.

This task has the following prerequisites:


v Your EGL Web project must have support for the JSF component interface. See
“Adding JSF component interface support to an EGL Web project” on page 464.
v The JSF Handler that is associated with the Web page must have the following
import statement:
import com.ibm.egl.jsf.*
v You must declare a variable of the type UIViewRoot within the JSF Handler.
v You must specify the name of the of the UIViewRoot variable in the
viewRootVar JSF Handler property.
For more information on these prerequisites, see “Accessing the JSF component
tree with the source assistant” on page 454.

Follow these steps to change the style of a JSF control from an EGL JSF Handler:
1. On a blank line inside a function in the JSF Handler, press Ctrl+Shift+Z. The
EGL Source Assistant window opens, displaying the JSF controls on the page.
2. In the EGL Source Assistant window, select the JSF control that you want to
access.
3. Click OK.
The EGL source assistant adds two lines of EGL code to the JSF Handler. The
first line defines an EGL variable of the type that matches the JSF control that
you selected. The second line associates that variable with the JSF control. For
example, the code to access a JSF input text control might look like this:
text1 HtmlInputText;
text1 = myViewRoot.findComponent("form1:text1");
4. Using the EGL variable that the source assistant created, change the style of the
JSF control with the setStyle function. For example, to change the text in a text
control to red, add this code:
text1.setStyle("color : red");
When this code runs, the style attribute of the input control is changed. In this
example, the HTML code displayed by the browser looks like this:
<input id="form1:text1" type="text" name="form1:text1" style="color : red" />
The new style attribute overwrites any previous style attribute. To make more
than one change to the style of a control, separate changes with semicolons (;).
For example, to change the color to red and the size to 20 points, use this code:
text1.setStyle("color : red; font-size: 20pt");

Some examples of other changes you can make to the style of a control follow. Not
all styles are compatible with all JSF controls.
text1.setStyle("font-size : 20pt");
Sets the size of the font in the control to 20 points.
text1.setStyle("text-align: center");
Centers the text within the control.
text1.setStyle("border-style : solid; border-color : red");
Adds a red border composed of a solid line around the control.

458 EGL Programmer’s Guide


text1.setStyle("font-weight : bold");
Makes the text within the control bold.
text1.setStyle("height : 50px");
Makes the control 50 pixels tall.
Related tasks
“Adding JSF component interface support to an EGL Web project” on page 464
“Accessing the JSF component tree with the source assistant” on page 454
“Changing the style class of a JSF control”
“Changing the target of a JSF link” on page 457
“Enabling or disabling JSF controls” on page 462
“Setting the size of a JSF image” on page 461
“Setting event handlers for a JSF control” on page 460
“Setting JSF data table properties” on page 463
Related reference
Component tree access
viewRootVar

Changing the style class of a JSF control


Like many elements on a Web page, JSF controls can be assigned a style class with
the class attribute. A style class, not to be confused with a Java class, is a group of
zero to many commands that describes the appearance of an element on a Web
page. Style classes are defined with the Cascading Style Sheets language, a
language that can control many different aspects of the appearance of a Web page.

You can change the style class of a JSF control on a Faces JSP file from one class to
another. To make smaller changes to a JSF control’s style, such as changing the text
color, see “Changing the style of a JSF control” on page 458.

This task has the following prerequisites:


v Your EGL Web project must have support for the JSF component interface. See
“Adding JSF component interface support to an EGL Web project” on page 464.
v The JSF Handler that is associated with the Web page must have the following
import statement:
import com.ibm.egl.jsf.*
v You must declare a variable of the type UIViewRoot within the JSF Handler.
v You must specify the name of the of the UIViewRoot variable in the
viewRootVar JSF Handler property.
For more information on these prerequisites, see “Accessing the JSF component
tree with the source assistant” on page 454.

To change the style class of a JSF control from an EGL JSF Handler:
1. On a blank line inside a function in the Handler, press Ctrl+Shift+Z. The EGL
Source Assistant window opens, displaying the JSF controls on the page.
2. In the EGL Source Assistant window, select the JSF control you want to access.
3. Click OK.
The EGL source assistant adds two lines of EGL code to the JSF Handler. The
first line defines an EGL variable of the type that matches the JSF control that
you selected. The second line associates that variable with the JSF control. For
example, the code to access a JSF input text control might look like this:

Building EGL JSF Web applications 459


text1 HtmlInputText;
text1 = myViewRoot.findComponent("form1:text1");
4. Using the EGL variable that the source assistant created, set the style class of
the JSF control with the setStyleClass function. For example, to set a text
control to a style class named errorField, add this code:
text1.setStyleClass("errorField");
When this code runs, the style class of the input control is changed. In this
example, the HTML code displayed by the browser looks like this:
<input id="form1:text1" type="text" name="form1:text1" class="errorField" />
Related tasks
“Adding JSF component interface support to an EGL Web project” on page 464
“Accessing the JSF component tree with the source assistant” on page 454
“Changing the style of a JSF control” on page 458
“Changing the target of a JSF link” on page 457
“Enabling or disabling JSF controls” on page 462
“Setting the size of a JSF image” on page 461
“Setting event handlers for a JSF control”
“Setting JSF data table properties” on page 463
Related reference
Component tree access
viewRootVar

Setting event handlers for a JSF control


You can assign a JavaScript function to a JavaServer Faces (JSF) control to serve as
an event handler, or you can remove an event handler from a control. In this
context, an event handler is a JavaScript function that is called when a specific event
happens on the page. For example, you can assign a function to a text input
control using the onClick event handler. When the control is clicked in the
browser, the function defined as the onClick event handler runs.

The JavaScript function that is used as an event handler must be available to the
page, either in a <script> tag on the page itself or in a script file that is linked to
the page. You cannot use an EGL function as an event handler for a JSF control.

This task has the following prerequisites:


v Your EGL Web project must have support for the JSF component interface. See
“Adding JSF component interface support to an EGL Web project” on page 464.
v The JSF Handler that is associated with the Web page must have the following
import statement:
import com.ibm.egl.jsf.*
v You must declare a variable of the type UIViewRoot within the JSF Handler.
v You must specify the name of the of the UIViewRoot variable in the
viewRootVar JSF Handler property.
For more information on these prerequisites, see “Accessing the JSF component
tree with the source assistant” on page 454.

Follow these steps to assign or remove an event handler from a JSF control:
1. On a blank line inside a function in the JSF Handler, press Ctrl+Shift+Z. The
EGL Source Assistant window opens, displaying the JSF controls on the page.

460 EGL Programmer’s Guide


2. In the EGL Source Assistant window, select the JSF image control that you want
to access.
3. Click OK.
The EGL source assistant adds two lines of EGL code to the JSF Handler. The
first line defines an EGL variable of the type that matches the JSF control that
you selected. The second line associates that variable with the JSF control. For
example, the code to access a JSF input text control might look like this:
text1 HtmlInputText;
text1 = myViewRoot.findComponent("form1:text1");
4. Using the EGL variable that the source assistant created, assign or remove the
event handlers. For example, to assign the JavaScript function myFunction() as
the onClick event handler for the text control, add this code:
text1.setOnclick("myFunction");
To remove an event handler from a JSF control, assign it a blank string as an
event handler:
text1.setOnclick("");
Related tasks
“Adding JSF component interface support to an EGL Web project” on page 464
“Accessing the JSF component tree with the source assistant” on page 454
“Changing the style class of a JSF control” on page 459
“Changing the style of a JSF control” on page 458
“Changing the target of a JSF link” on page 457
“Enabling or disabling JSF controls” on page 462
“Setting the size of a JSF image”
“Setting JSF data table properties” on page 463
Related reference
Component tree access
viewRootVar

Setting the size of a JSF image


You can change the size of a JavaServer Faces (JSF) image on a Faces JSP page with
EGL code. You must use a Faces image control; an EGL JSF Handler cannot
directly change ordinary HTML image tags.

This task has the following prerequisites:


v Your EGL Web project must have support for the JSF component interface. See
“Adding JSF component interface support to an EGL Web project” on page 464.
v The JSF Handler that is associated with the Web page must have the following
import statement:
import com.ibm.egl.jsf.*
v You must declare a variable of the type UIViewRoot within the JSF Handler.
v You must specify the name of the of the UIViewRoot variable in the
viewRootVar JSF Handler property.
For more information on these prerequisites, see “Accessing the JSF component
tree with the source assistant” on page 454.

Follow these steps to change the size of a JSF image control with an EGL JSF
Handler:

Building EGL JSF Web applications 461


1. On a blank line inside a function in the JSF Handler, press Ctrl+Shift+Z. The
EGL Source Assistant window opens, displaying the JSF controls on the page.
2. In the EGL Source Assistant window, select the JSF image control that you want
to access.
3. Click OK.
The EGL source assistant adds two lines of EGL code to the JSF Handler. The
first line defines an EGL variable of the type that matches the JSF control that
you selected. The second line associates that variable with the JSF control. For
example, the code to access a JSF image control might look like this:
imageEx1 HtmlGraphicImageEx;
imageEx1 = myViewRoot.findComponent("imageEx1");
4. Using the EGL variable that the source assistant created, change the size of the
JSF image control with the setHeight and setWidth functions, passing each
function a string or literal that specifies the measurement in pixels. For
example, to make the image 300 pixels wide and 200 pixels tall, add this code:
imageEx1.setWidth("300");
imageEx1.setHeight("300");
Related tasks
“Adding JSF component interface support to an EGL Web project” on page 464
“Accessing the JSF component tree with the source assistant” on page 454
“Changing the style class of a JSF control” on page 459
“Changing the style of a JSF control” on page 458
“Changing the target of a JSF link” on page 457
“Enabling or disabling JSF controls”
“Setting event handlers for a JSF control” on page 460
“Setting JSF data table properties” on page 463
Related reference
Component tree access
viewRootVar

Enabling or disabling JSF controls


You can enable or disable JSF input controls and command buttons with EGL code.
A disabled control cannot be edited or changed on the Web page.

This task has the following prerequisites:


v Your EGL Web project must have support for the JSF component interface. See
“Adding JSF component interface support to an EGL Web project” on page 464.
v The JSF Handler that is associated with the Web page must have the following
import statement:
import com.ibm.egl.jsf.*
v You must declare a variable of the type UIViewRoot within the JSF Handler.
v You must specify the name of the of the UIViewRoot variable in the
viewRootVar JSF Handler property.
For more information on these prerequisites, see “Accessing the JSF component
tree with the source assistant” on page 454.

To enable or disable a JSF control with an EGL JSF Handler:


1. On a blank line inside a function in the JSF Handler, press Ctrl+Shift+Z. The
EGL Source Assistant window opens, displaying the JSF controls on the page.

462 EGL Programmer’s Guide


2. In the EGL Source Assistant window, select the JSF control that you want to
access.
3. Click OK.
The EGL source assistant adds two lines of EGL code to the JSF Handler. The
first line defines an EGL variable of the type that matches the JSF control that
you selected. The second line associates that variable with the JSF control. For
example, the code to access a JSF input text control might look like this:
text1 HtmlInputText;
text1 = myViewRoot.findComponent("form1:text1");
4. Using the EGL variable that the source assistant created, enable or disable the
JSF control with the setDisabled function. For example, to enable a text control,
add this code:
text1.setDisabled(no);
To disable the text control, add this code:
text1.setDisabled(yes);
Related tasks
“Adding JSF component interface support to an EGL Web project” on page 464
“Accessing the JSF component tree with the source assistant” on page 454
“Changing the style class of a JSF control” on page 459
“Changing the style of a JSF control” on page 458
“Changing the target of a JSF link” on page 457
“Setting the size of a JSF image” on page 461
“Setting event handlers for a JSF control” on page 460
“Setting JSF data table properties”
Related reference
Component tree access
viewRootVar

Setting JSF data table properties


You can change some of the properties of a JavaServer Faces (JSF) data table on a
Faces JSP page with EGL code.

This task has the following prerequisites:


v Your EGL Web project must have support for the JSF component interface. See
“Adding JSF component interface support to an EGL Web project” on page 464.
v The JSF Handler that is associated with the Web page must have the following
import statement:
import com.ibm.egl.jsf.*
v You must declare a variable of the type UIViewRoot within the JSF Handler.
v You must specify the name of the of the UIViewRoot variable in the
viewRootVar JSF Handler property.
For more information on these prerequisites, see “Accessing the JSF component
tree with the source assistant” on page 454.

To change the properties of a JSF data table control:


1. On a blank line inside a function in the JSF Handler, press Ctrl+Shift+Z. The
EGL Source Assistant window opens, displaying the JSF controls on the page.
2. In the EGL Source Assistant window, select the JSF data table control that you
want to access.

Building EGL JSF Web applications 463


3. Click OK.
The EGL source assistant adds two lines of EGL code to the JSF Handler. The
first line defines an EGL variable of the type that matches the JSF control that
you selected. The second line associates that variable with the JSF control. For
example, the code to access a JSF input text control might look like this:
table1 HtmlDataTable;
table1 = viewRoot.findComponent("table1");
4. Using the EGL variable that the source assistant created, change the properties
of the data table. For example, to change the rowClasses property of the table
to the style class MyRowClass1, add this code:
table1.setRowClasses("MyRowClass1");
To make the rows of the data table alternate between the two style classes
MyRowClass1 and MyRowClass2, add this code:
table1.setRowClasses("MyRowClass1, MyRowClass2");
Related tasks
“Adding JSF component interface support to an EGL Web project”
“Accessing the JSF component tree with the source assistant” on page 454
“Changing the style class of a JSF control” on page 459
“Changing the style of a JSF control” on page 458
“Changing the target of a JSF link” on page 457
“Enabling or disabling JSF controls” on page 462
“Setting the size of a JSF image” on page 461
“Setting event handlers for a JSF control” on page 460
Related reference
Component tree access
viewRootVar

Adding JSF component interface support to an EGL Web project


Before you can access JavaServer Faces (JSF) components in a Faces JSP file from
EGL code, your EGL Web project must contain the packages that enable you to
access the JSF component tree. You can add these packages when you create an
EGL Web project, or you can add them to an existing EGL Web project by
following these steps:
1. In the Project Explorer view, right-click the EGL Web project and then click
Properties.
2. In the Properties window, click Project Facets.
3. Click Add/Remove Project Facets.
4. Select the EGL support with JSF Component Interfaces check box. If this
check box is already selected, the project already has support for the JSF
component interface.
5. Click Finish.
6. Click OK.

Adding support for the JSF component interface adds a package named
com.ibm.egl.jsf to your project. As explained in “Accessing the JSF component
tree with the source assistant” on page 454, this package contains ExternalType
parts that you can use to access JSF components on the page.

You cannot remove support for the JSF component interface from a project.

464 EGL Programmer’s Guide


Related tasks
“Creating an EGL Web project” on page 73
This topic covers how to create an EGL Web project.
“Accessing the JSF component tree with the source assistant” on page 454
Related reference
Component tree access

Setting preferences for Web projects


These preferences control defaults for EGL Web projects and JSF Handler parts.

To specify preferences for Web projects and JSF Handler parts, follow these steps:
1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL and click Page Designer.
3. In the JSFHandler Package field, specify the location of JSF Handler parts in
your EGL Web projects.
4. In the Loadbundle variable field, set the name of the variable to use to
represent resource bundles in your pages. The default value is labels, but you
can change this value as explained in “Localizing text in Web applications” on
page 426.
5. Set preferences for refactoring EGL Web projects and JSF Handler parts in the
check boxes at the bottom of the page. These check boxes tell EGL to delete the
JSP file that is associated with a JSF Handler if you delete the JSF Handler, and
vice versa. You can also delete the generated output when you delete a JSF
Handler.
6. Click Apply to save the changes and remain in the Preferences window. Click
OK to save the changes and exit the window.
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related Reference
JSF Handler part

Building EGL JSF Web applications 465


466 EGL Programmer’s Guide
Building EGL portlet applications
A portal page combines a number of independent windows, or portlets, under the
control of a portal server.

In an EGL portlet application, the EGL logic parts control portlets. These parts
allow you to put data in a Portal and get input from users. EGL portlet
development follows the EGL Web application programming model, and differs
only in the ways noted in this section.

Portlet overview
WebSphere Portal Server is a content aggregator. It uses programs called portlet to
process user requests and generate dynamic content. The portal acts as a container
for the portlets, managing the lifecycle of, and providing various services to, the
portlets and combining their output into a single Web page.

Each page of a portal is divided into “windows” that display the dynamic content
generated by a single portlet. Portlet windows have two user modifiable
properties, mode and window state.

Portlet mode

A portlet mode is an indication of the function that the portlet will perform to
produce specific content or perform a certain task. Common portlet modes are
View, Edit, and Help.

All portlets are required to provide View mode support. In this mode, portlets
generate their normal dynamic content. For example, you can have a portlet that
displays the local weather in the portlet window.

Portlet can also be displayed in Edit mode. In our weather portlet example, if we
had displayed the portlet in Edit mode, it would wait for the user to enter the
local zip code in order to customize the weather display. Each user is able to
provide this customization data, which means that the portlet will display different
data depending on who is logged in. Edit mode support is optional.

Help mode causes the portlet to display information on the use of the portlet. The
help can be a single screen displaying help for the entire portlet, or may be more
context specific. Help mode support is optional.

Window state

The window state of a portlet is an indicator of the amount of page real estate that
the portlet will occupy. Portlets can have three possible states: normal, maximized,
and minimized.

The normal window state indicates that the portlet may be sharing the page with
any either any number of other portlets. Because the portlet window might be
small, the portlet author might want to limit the amount of page space that the
portlet requires. For instance, in the example weather portlet, we can choose to
limit its display to the temperature and a graphic that indicates the current
weather conditions.

© Copyright IBM Corp. 1996, 2008 467


A maximized window state can show that the portlet will either be the only one
that is portlet displayed or that it will be given more space than the other portlets
on the page. If we designate the weather portlet as maximized then it could
display a local forecast information for multiple days.

When minimized, the portlet should display little or no information. The container
might choose not to render the portlet at all, which means that it is not likely a
minimized portlet will display during page rendering.

Prerequisites
To use EGL portlets, you must have the following products installed:
v Rational Application Developer with the Portal tool feature installed
v IBM WebSphere Portal Server V6.0 or later
Related concepts
“Elements of a Portlet Application”
“Managing Portlet Sessions” on page 469
“Inter-Portlet Communication” on page 470
“J2EELib” on page 471
Related tasks
“Creating a Web Page” on page 471
“Adding a Portlet to the Application” on page 472
“Adding Support for Additional Portlet Modes” on page 473
Related reference
EGL library portalLib

Elements of a Portlet Application


A portlet application is a Web application that can contain multiple portlets. The
portlets that are within the application can interact with each other when placed
on the same Portal page. As with other EGL based Web applications, portlet
applications are composed of JSP files that are backed by JSF Handler parts and
other configuration files. For more information regarding EGL Web application
development, see “Building EGL JSF Web applications” on page 389.

JSF Handler part


JSF Handlers for portlet applications are developed in exactly the same way as
handlers for other Web applications. In standard Web applications, the JSF Handler
part backs a JSP that represents an entire Web page. In a portlet application, there
is at least one JSF Handler and a corresponding JSP file for each supported mode
of each portlet in the application.

When you use the New EGL Portlet wizard to create a portlet named MyPortlet,
and specify that it will support view and edit modes, the wizard will create two
JSF Handlers called MyPortletView and MyPortletEdit

Java Server Pages (JSP) files

Java Server Pages in a portlet application represent a fragment of a portal page.


Unlike JSPs for standard Web applications where each JSP represents an entire Web

468 EGL Programmer’s Guide


page, each portlet JSP represents only the fragment of the portal page that is
confined to the individual portlet window.

It is the responsibility of the portlet container to combine these fragments into a


valid web page. For this reason, you must not add HTML markup head and body
tags to your portlet JSPs.

Window state

The portlet deployment descriptor provides configuration and deployment


information for your portlet application. The portlet deployment descriptor is
visible in your EGL portlet project in two places:
v As the portlet.xml file located in the project’s Web Content/WEB-INF folder
v As the Portlet Deployment Descriptor file located in the root of the project, only
visible in the Project Explorer view.
These references point to the same file.
Related concepts
“Building EGL portlet applications” on page 467
A portal page combines a number of independent windows, or portlets, under
the control of a portal server.
“Managing Portlet Sessions”
“Inter-Portlet Communication” on page 470
“J2EELib” on page 471
Related tasks
“Creating a Web Page” on page 471
“Adding a Portlet to the Application” on page 472
“Adding Support for Additional Portlet Modes” on page 473
Related reference
EGL library portalLib

Managing Portlet Sessions


Portlets commonly collect state information that you must save between requests
from a client. A way to manage this information is to save it as a session attribute.
Portlet sessions are similar to Web application sessions, and managing their
attributes is the conceptual equivalent.

Portlet sessions do have one major difference. Unlike Web application sessions, a
Portlet session has scope. A session attribute that is placed in the portlet scope is
easily accessible only to the portlet that added it.

When you add an attribute to the session, you must specify the level of access to
the attribute within the portlet application. Do this through the scope parameter of
the portalLib.setPortletSessionAttr() function. This parameter takes an enumerated
value of type SessionScopeKind. For example, to add a session attribute that is
only accessible to the declaring portlet, use the following function call in the JSF
Handler:
portalLib.setPortletSessionAttr(“myKey”, “myValue”, SessionScopeKind.portletScope);
Related concepts

Building EGL portlet applications 469


“Building EGL portlet applications” on page 467
A portal page combines a number of independent windows, or portlets, under
the control of a portal server.
“Elements of a Portlet Application” on page 468
“Inter-Portlet Communication”
“J2EELib” on page 471
Related tasks
“Creating a Web Page” on page 471
“Adding a Portlet to the Application” on page 472
“Adding Support for Additional Portlet Modes” on page 473
Related reference
EGL library portalLib

Inter-Portlet Communication
One of the most useful features of a portlet is that it can communicate with other
portlets. Although the standard portlet API does not define a communication
mechanism, you can use the PortletSession as a “scratchpad” for passing
information. The PortletSession is the mechanism that the portal uses for
identifying and storing transient information about a user across multiple browser
requests. One portlet in an application can write to the PortletSession, and the
other portlets in the application can read the values and use them.

The portlet request lifecycle makes communication of this sort possible. When user
interaction occurs on a portal page, the following sequence of events happens:
1. The portlet where the event occurred processes the event first. This portlet can
add attributes to the application scope of the session. The attribute will then be
accessible to all portlets in the application.
2. After the portlet finishes responding to the event, each portlet on the page,
including the one that handled the event, renders itself. While rendering, all
portlets can access the application scope attribute and use it to appropriately
respond to the user action.
Related concepts
“Building EGL portlet applications” on page 467
A portal page combines a number of independent windows, or portlets, under
the control of a portal server.
“Elements of a Portlet Application” on page 468
“Managing Portlet Sessions” on page 469
“J2EELib” on page 471
Related tasks
“Creating a Web Page” on page 471
“Adding a Portlet to the Application” on page 472
“Adding Support for Additional Portlet Modes” on page 473
Related reference
EGL library portalLib

470 EGL Programmer’s Guide


J2EELib
J2EELib provides a number of functions that are useful to Web application
developers. You can accomplish most functions found in J2EELib with the
corresponding functions in PortalLi.b, however, portalLib does not provide
functions for setting request attributes for a portlet. Most JSF applications should
not need request attributes, but if you can use the J2EELib functions
getRequestAttr() and setRequestAttr() within a portlet.
Related concepts
“Building EGL portlet applications” on page 467
A portal page combines a number of independent windows, or portlets, under
the control of a portal server.
“Elements of a Portlet Application” on page 468
“Managing Portlet Sessions” on page 469
“Inter-Portlet Communication” on page 470
Related tasks
“Creating a Web Page”
“Adding a Portlet to the Application” on page 472
“Adding Support for Additional Portlet Modes” on page 473
Related reference
EGL library portalLib

Creating a Web Page


Each mode of a portlet can be composed of multiple JSPs and JSF Handler parts.
Each mode has an initial JSP that is specified as a parameter in the portlet.xml file
for the application.

To add additional pages to the portlet:


1. In the Project Explorer view, select EGL portlet project.
2. Click File → New → Other. The New window opens.
3. Expand Web and click Web page, not JSP.
4. Click Next.
5. In the File Name field, enter the name of the new Web page. The
accompanying JSF handler will have the same name with an *.egl extension. It
is a good practice to append the file name with the name of the mode to which
the content belongs.
6. In the Folder field, select the location for the new Web page. The location must
be in the Web Content folder of the EGL Portlet project. The accompanying JSF
handler will be put into the project’s jsfhandlers package unless you specified a
different package in the workbench preferences.
7. Make sure that the template you use for the Web page is the Portlet JSP
template. This template is creates a JSP fragment, rather than an entire Web
page.
8. Click Finish.

The new Web page and its JSF Handler part are created in your Web project.
Additionally, EGL creates a navigation rule in the JSF configuration file that allows
you to forward users to this page.

Building EGL portlet applications 471


After the page has been created, you can use the EGL forward statement to
navigate from the main page to the newly created page.
Related concepts
“Building EGL portlet applications” on page 467
A portal page combines a number of independent windows, or portlets, under
the control of a portal server.
“Elements of a Portlet Application” on page 468
“Managing Portlet Sessions” on page 469
“Inter-Portlet Communication” on page 470
“J2EELib” on page 471
Related tasks
“Adding a Portlet to the Application”
“Adding Support for Additional Portlet Modes” on page 473
Related reference
EGL library portalLib

Adding a Portlet to the Application


A portlet application can be composed of multiple portlets in a portlet project. The
EGL Portlet Project wizard can be used to create the initial portlet in an
application. Use the New EGL Portlet wizard to add portlets to the project.
1. In the Project Explorer view, select the your EGL portlet project.
2. Click File → New → Other → EGL → EGL Portlet.
3. In the Portlet name field, enter the name of the new portlet.
4. In the Content types and modes table, check the modes you want the portlet
to support.
5. Click Finish.

The new portlet will be created in the target project. The faces-config.xml and
portlet.xml files will be updated to support the new portlet. A JSP and
corresponding JSF Handler will be created for each supported portlet mode.
Related concepts
“Building EGL portlet applications” on page 467
A portal page combines a number of independent windows, or portlets, under
the control of a portal server.
“Elements of a Portlet Application” on page 468
“Managing Portlet Sessions” on page 469
“Inter-Portlet Communication” on page 470
“J2EELib” on page 471
Related tasks
“Creating a Web Page” on page 471
“Adding Support for Additional Portlet Modes” on page 473
Related reference
EGL library portalLib

472 EGL Programmer’s Guide


Adding Support for Additional Portlet Modes
Typically, you define portlet modes when the New EGL Portlet Project or New
EGL Portlet wizards; however, you can still add modes after the portlet has been
created.

To add portlet modes to an existing portlet:


1. Create a new Web Page to represent the initial content of the mode as
described in the section Creating a Web Page.
2. Right click on the portlet.xml file and select Open With → JSR 168 Portlet
Deployment Descriptor Editor.
3. Select the Portlets tab at the bottom of the editor.
4. In the Portlets list, select the portlet to which you will be adding the mode.
5. Find the Supported Modes section. Select text/html and click the Edit.
6. Under Portlet modes, click Add. The cursor will become active in the Portlet
modes list. Type the name of the mode ytaht you want to add. Valid values for
WebSphere Portal Server 6.0 are:
v view
v edit
v help
v config
v edit_defaults
7. Click OK.
8. Find the Initialization section. This section contains initialization parameters
that are read when the portlet is loaded by the portlet container. EGL based JSF
portlets use initialization parameters to specify which JSP file to display as the
initial content for each supported portlet mode. Click Add.
In the Value field, enter the path to the JSP to be used for this mode. This
value should be relative to the context root of the web application. In the Name
field, you will enter a predefined parameter name indicating the mode this JSP
will support. Valid values are:
v com.ibm.faces.portlet.page.view
v com.ibm.faces.portlet.page.edit
v com.ibm.faces.portlet.page.config
v com.ibm.faces.portlet.page.help
9. Click OK.
Related concepts
“Building EGL portlet applications” on page 467
A portal page combines a number of independent windows, or portlets, under
the control of a portal server.
“Elements of a Portlet Application” on page 468
“Managing Portlet Sessions” on page 469
“Inter-Portlet Communication” on page 470
“J2EELib” on page 471
Related tasks
“Creating a Web Page” on page 471
“Adding a Portlet to the Application” on page 472
Related reference

Building EGL portlet applications 473


EGL library portalLib

474 EGL Programmer’s Guide


Overview of service-oriented architecture (SOA)
SOA is a way of organizing software. The technology is based on services, which
are customized units of software that run in a network. A service
v Handles a business process such as calculating an insurance quote or
distributing email, or handles a relatively technical task such as accessing a
database, or provides business data and the technical details needed to construct
a graphical interface
v Can access another service and, with the appropriate runtime technology, can
access a traditional program and respond to different kinds of requesters—for
example, to Web applications
v Is relatively independent of other software so that changes to a requester require
few or no changes to the service, while changes to the internal logic of a service
require few or no changes to the requester

The relative independence of the service and other software is called loose coupling.
The flexibility offered by loose coupling protects your company from excessive
costs when business or technical requirements change.

A service can handle interactions within your company, as well as between your
company and its suppliers, partners, and customers. The location of service
requesters can extend worldwide, depending on security issues and on the runtime
software used to access a particular service.

The requesting code usually has no details on the service location. Like the
requester, the service can be almost anywhere. The location is set when the service
is deployed. At run time, a requester or network may be able to redirect a request
to a service at a different location.

SOA implies a style of development, with concern for the business as a whole and
with an increased focus on modularity and reuse. From the point of view of a
developer, a change to a service orientation is a change in emphasis, and many
aspects of the development task are unaffected.

Structure of a service-oriented application

A service-oriented application is an application composed largely of services.


Often, the invoked services are in a hierarchy.

© Copyright IBM Corp. 1996, 2008 475


Web
application

Service-oriented application

Integration
service

Business Business
service service

Data-access Data-access Data-access


service service service

Databases

The topmost level contains one or more integration services, each of which controls
a flow of activities such as processing an applicant’s request for insurance
coverage. Each integration service invokes one or more business services.

The second level is composed of services that each fulfill a relatively low-level
business task. For example, an integration service might invoke a series of business
services to verify the details provided by an insurance-policy applicant. If the
business services return values that are judged to mean ″issue a policy,″ the
integration service invokes yet another business service, which calculates a quote
and returns the quote to the software (for example, a Web application) that
invoked the service-oriented application.

The third level consists of data-access services, each of which handles the relatively
technical task of reading from and writing to data-storage areas such as databases
and message queues. A data-access service is most often invoked from the business
layer, but the easy access of services means, for example, that the Web application
can access a data-access service to assign initial values in a form.

Great complexity is possible. Some integration services, for example, provide


different operations to different requesters, and some invoke other integration
services and are said to be composed of those services. Many applications,
however, fulfill the three-level model described here.

Business Implications of SOA

SOA has several important implications for business. First, to the extent that loose
coupling is in effect, changes made to the service logic won’t force significant
changes to requesters of that software. When each component is a relatively

476 EGL Programmer’s Guide


standalone unit, your company can respond to business or technological changes
more quickly and with less expense and confusion. Often, a service can even be
redeployed to another machine without changing logic or recompiling the code. A
further implication is that your company can develop services for different
platforms and with different implementation languages, letting the organization
use the best available technologies.

In general, a company’s ability to respond quickly and well to change is known as


agility. The main promise of service-oriented architecture is that a well-crafted SOA
will increase agility over time. SOA also has an important effect on how people
work together. Aside from the most technical services, a well-written service is
coarse-grained, meaning that the area of concern is broad enough so business
people can understand the purpose of the service even if they know little about
software. To the extent that a collection of coarse-grained services handles your
company’s business procedures, the firm’s business analysts and software
professionals can share information knowledgeably, can include end users in early
deliberations about the purpose and scope of each service, and can understand all
the implications of changing a business procedure. Ease of human communication
is an important benefit of SOA and suggests that the architecture will become the
primary organizing principle for business.

Last, well-designed services are more likely to be reusable. Your company benefits
from reuse in at least two ways: first, by avoiding the expense of developing new
software, and second, by increasing the reliability of the software inventory over
time. The firm can do less extensive testing if an existing service is placed in a new
application, in comparison to the testing required to deploy software that was
written from scratch.

Notice

The preceding overview of service-oriented architecture is largely from SOA for the
Business Developer (http://www.mc-store.com/5079.html), published by MC Press.
Related concepts
“Elements of a service-oriented application” on page 478
The major elements of an EGL service-oriented application are the service part,
interface part, and deployment descriptor file. In general, each of these files and
parts has a role in both services and service requesters.
“Types of services” on page 481
You can generate your service parts as EGL services, as SOAP (Web) services,
or as REST services. An EGL-based requester can access EGL services; or SOAP
(Web) services, which may be written in a language other than EGL; or native
services, which currently include service programs on IBM i. The only
EGL-application that can access a REST service is a Rich UI application, and the
accessed service in that case may be written in EGL or another language.
Related tasks
“Adding service client binding information from a WSDL file” on page 489
Service client binding information tells how the EGL runtime connects to a
service being invoked by your EGL code. This topic concerns SOAP (Web)
service invocation.
“Calling a remote service” on page 485
You can call remote services from your EGL logic parts.
“Calling a local service” on page 483
You can call an EGL or native service that is local to your application without
exposing that service as a Web service.

Overview of service-oriented architecture (SOA) 477


“Exposing a service to other applications” on page 493
Your EGL application can act as a service by exposing its functions to other
applications.
“Setting preferences for service generation” on page 498
You can set defaults for how your services are generated.
Related reference
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.

Elements of a service-oriented application


The major elements of an EGL service-oriented application are the service part,
interface part, and deployment descriptor file. In general, each of these files and
parts has a role in both services and service requesters.

Service part

The service part is a logic part that exposes functions to other applications. In EGL
terms, a service works much like a library:
v Services are groups of functions. Fundamentally, the functions in a service are no
different than those in a library: they receive parameters, return parameters,
perform logic, and access data.
v Services can encapsulate functions that you want to reuse in other parts of your
application.
v Services can have private functions, functions that can be called only by other
functions in the same service.
v Services are generatable parts. You can have only one service part in a file, and
that file can contain no other generatable parts.

However, services differ from libraries in several ways:


v Services can expose their functions to a wide range of applications, not just EGL
applications. EGL services can use standards like the Web Services Definition
Language to expose their functions in a way that many other types of
applications can understand and use.
v Services are stateless, meaning that they do not remember interactions with a
client or change after an interaction with a client. Each time a service is used, it
is as though that service is being used for the first time. In other words, the
global memory of a service is re-initialized every time it is used, while a library
can remember changes in its global memory as long as its run unit is running.
v Requesters can call the functions in a service but cannot reference its variables.

Her is a example of a simple service part:


Service calculatorService

function addIntegers(intOne int in, intTwo int in)


returns (int)
return (intOne + intTwo);
end

function subtractIntegers(intOne int in, intTwo int in)


returns (int)

478 EGL Programmer’s Guide


return (intOne - intTwo);
end

end

Interface part

An interface part contains function prototypes, or summaries of functions. In this


case, the prototypes summarize functions in a service part. A function prototype
lists the function or method name, its arguments, and its return value, but no
internal logic. See ″Function prototypes″ in the EGL Language Reference for more
information on prototypes.

An interface part is designed to be implemented by one or more service parts. When


a service part implements an interface part, that service part must define each
function that is prototyped in the interface part. Also, the function definitions in
the service part must match the prototypes, using the same name, parameters, and
return value.

Interface parts are rarely required, but they can be helpful in the service
development process:
v The interface enables you to plan the service ahead of time, and EGL warns you
if the service deviates from the interface.
v Interfaces provide a concise summary of a service, explaining what the service
can do without providing all of the details of implementing the service.
v Interfaces can be useful in accessing a service remotely.
v Interfaces can serve as requirements for development or compliance.

This is an example of a simple interface part:


interface calculatorInterface

function addIntegers(intOne int in, intTwo int in)


returns (int);
function subtractIntegers(intOne int in, intTwo int in)
returns (int);

end

To make a service implement an interface, add the implements keyword after the
service name, followed by the interface name. Separate additional interfaces with
commas. Like any type of part, the interface part must be in scope for the service
part to implement it.
import interfaces.calculatorInterface;

Service calculatorService implements calculatorInterface

function addIntegers(intOne int in, intTwo int in)


returns (int)
return (intOne + intTwo);
end

function subtractIntegers(intOne int in, intTwo int in)


returns (int)
return (intOne - intTwo);
end

end

Overview of service-oriented architecture (SOA) 479


Deployment descriptor file

The EGL deployment descriptor file (extension .egldd; not to be confused with JEE
deployment descriptor files) contains information that describes either how a
service part from your application is exposed to other applications or how an
external service will be used in your application. Therefore, there are two major
items in the deployment descriptor file:
v Service client bindings represent services from other applications that you want to
use in your application’s logic parts. The service client binding information often
includes a WSDL file that describes the external service and the name of an EGL
part in your project that will represent the service within your application.
v Web service deployment information lists service parts in your application that you
want to expose to other applications. The information in the deployment
descriptor includes details about how the service will be deployed and made
available to other applications.

The EGL deployment descriptor is distinct from JEE deployment descriptors. For
information on JEE deployment descriptors, see Defining JEE enterprise
applications (EARs).

Web Services Description Language (WSDL) file

Web Services Description Language (WSDL) files are a standard way of


communicating information about Web (SOAP) services, but not about REST
services. For a review of the difference between Web (SOAP) services and REST
services, see Overview of service access.

You might encounter WSDL files in your EGL applications in two areas:
v When acting as a requester of a service, you can create parts and binding
information directly from the WSDL file of the particular service. See “Adding
service client binding information from a WSDL file” on page 489 for more
information.
v When you generate a service part as a Web service, EGL creates a WSDL file that
other services can use to invoke your service. In this case, treat the WSDL file as
you treat any generated output, because it will be overwritten each time you
generate the deployment descriptor file.

For more information on Web Services Description Language (WSDL), see Web
Services Description Language (WSDL).
Related concepts
“Types of services” on page 481
You can generate your service parts as EGL services, as SOAP (Web) services,
or as REST services. An EGL-based requester can access EGL services; or SOAP
(Web) services, which may be written in a language other than EGL; or native
services, which currently include service programs on IBM i. The only
EGL-application that can access a REST service is a Rich UI application, and the
accessed service in that case may be written in EGL or another language.
“Overview of service-oriented architecture (SOA)” on page 475
Overview of service access
Related tasks

480 EGL Programmer’s Guide


“Adding service client binding information from a WSDL file” on page 489
Service client binding information tells how the EGL runtime connects to a
service being invoked by your EGL code. This topic concerns SOAP (Web)
service invocation.
“Calling a remote service” on page 485
You can call remote services from your EGL logic parts.
“Calling a local service” on page 483
You can call an EGL or native service that is local to your application without
exposing that service as a Web service.
“Exposing a service to other applications” on page 493
Your EGL application can act as a service by exposing its functions to other
applications.
“Setting preferences for service generation” on page 498
You can set defaults for how your services are generated.
Related reference
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.
Interface part
Interface parts provide access to a remote service, such as a Web service.
Parts
Function prototypes

Types of services
You can generate your service parts as EGL services, as SOAP (Web) services, or as
REST services. An EGL-based requester can access EGL services; or SOAP (Web)
services, which may be written in a language other than EGL; or native services,
which currently include service programs on IBM i. The only EGL-application that
can access a REST service is a Rich UI application, and the accessed service in that
case may be written in EGL or another language.

For details on the distinction between SOAP (Web) services and REST services, see
Overview of service access.

Services and requesters

EGL services are based on the Service part, a logic part similar to a library. A
Service part can contain other parts, but only the Service part can be exposed to a
requester. After you have written the Service part, you expose it by adding
deployment information in the EGL deployment descriptor file. For details, see
“Exposing a service to other applications” on page 493.

Any EGL logic part, including a Service part, can behave as a requester. When
coding a requester, do as follows:
v Add a service client binding in the deployment descriptor, and in this way
provide the details necessary to access the service. The service client binding has
a binding key–essentially, a name–along with service-access details that are
associated with that key.
v Create a variable based on the Service part or on an equivalent Interface part.
v Relate the variable to the service client binding. You must set the complex
property @BindService in the variable declaration; but if you fail to specify a

Overview of service-oriented architecture (SOA) 481


binding key when you code that property, the system assumes that the binding
key is the name of the part on which the variable is based.

For further details, see “Calling a remote service” on page 485.

Binding requesters to services

EGL provides different ways to bind requesters to services:


v In the case of an EGL binding, binary data is transferred in a format that is
specific to EGL. The benefit of an EGL binding is that the connection is relatively
fast because binary data is exchanged. The cost is that non-EGL code cannot
access the service.
v In the case of a SOAP (Web) binding, data in transferred in a specific and widely
used text-based format called SOAP. Even if a service written in EGL is
deployed as a Web service, other EGL code can still access the service directly,
without using the extra runtime processing required to access a Web service.
v In the case of a REST binding, data can be transferred across the Web, but not in
the SOAP format.
v In the case of a Native binding, data is transferred in a binary format that
provides access to a System i® service program. Two kinds of access are
supported:
– If you are accessing that program from EGL-generated COBOL code that is on
the same System i machine, use the protocol SYSTEM-I.LOCAL. In this case,
the service code is included in the EGL-generated code. You cannot change
the binding detail at run time.
– If you are accessing that program from EGL code on a Java platform, use the
protocol JAVA400.
When your code accesses a System i service program, the following rules apply:
– Parameters must be of fixed length. For example, non-structured records are
not supported, nor is a value of type STRING. Also, dynamic arrays are not
supported.
– The service can return an integer or no value at all. If the native service
returns an integer, you can invoke a service operation named theOperation in
either of two ways, as suggested here:
theService myEGLInterfacePart {@BindService{}};
myStatus INT;

// either of the next invocations is valid if an integer is returned


theService.theOperation();
myStatus = theService.theOperation();
– A failure to access the native service or a non-zero return code throws the
exception ServiceInvocationException, as described in the EGL Language
Reference appendix EGL core Exception records.
Related concepts
“Overview of service-oriented architecture (SOA)” on page 475
Overview of service access
Accessing IBM i programs as Web services
“Elements of a service-oriented application” on page 478
The major elements of an EGL service-oriented application are the service part,
interface part, and deployment descriptor file. In general, each of these files and
parts has a role in both services and service requesters.
Related tasks

482 EGL Programmer’s Guide


“Calling a remote service” on page 485
You can call remote services from your EGL logic parts.
“Calling a local service”
You can call an EGL or native service that is local to your application without
exposing that service as a Web service.
“Exposing a service to other applications” on page 493
Your EGL application can act as a service by exposing its functions to other
applications.
Accessing a service in EGL Rich UI

Calling a local service


You can call an EGL or native service that is local to your application without
exposing that service as a Web service.

In this context, a local service is either an EGL service part (in your project or in a
project that is in your project’s build path) or is a System i service program being
accessed from an EGL-generated COBOL program that runs on the same machine.
For other cases, see “Calling a remote service” on page 485.

Calling a local service involves these general steps:


1. For an EGL service, create the service part. For a native service, create an
interface part that represents the functions being made available from the
System i program. (You can also use an interface part to interact with the EGL
service part.)
2. Add a client binding to the deployment descriptor.
3. Create a program or other logic part to act as the requester.
4. In the requester, create a variable based on the service or interface part and
bind that variable to the service.
5. Use the variable to access the service.
1. In the case of an EGL service, create a service part with the functions that you
want to expose to the requester; and then generate the service. A simple
example of a service part follows:
service CalculatorService

function addIntegers(intOne int in, intTwo int in)


returns (int)
return (intOne + intTwo);
end

function subtractIntegers(intOne int in, intTwo int in)


returns (int)
return (intOne - intTwo);
end

end
2. Create a client binding in the deployment descriptor file. The client binding
information tells EGL where to find the service at run time.
a. Open the client project’s deployment descriptor file. If the project does not
have a deployment descriptor file, create a new one and add it as the value
of the deploymentDescriptor build descriptor option. For more information,
see “Creating a deployment descriptor” on page 94.
b. On the Service Client Bindings page of the deployment descriptor editor,
under the heading Service Client Bindings, click Add. The Add a Service
Binding window opens.

Overview of service-oriented architecture (SOA) 483


c. In the Add a Service Binding window, click EGL Binding or Native
Binding and then click Next.
d. For EGL Binding:
1) Next to the EGL Binding Name field, click Browse.
2) In the EGL Interface Selection window, select the service part that you
want to access (or an interface part that identifies the functions of
interest) and click OK.
The Service Name field is populated with the fully qualified name of
the part, and the EGL Binding Name field is populated with the default
name for the client binding. You can change the name. In this case, the
default name is be the same as the service part, or CalculatorService.
3) Under Choose protocol type, provide the required details, as described
in the EGL Generation Guide.For details on those settings, see the EGL
Generation Guide section on Deployment descriptor options for service
clients.
If you have the service part in your workspace, you can create the binding
information directly from that part. Right-click the part and then click EGL
Services → Create EGL Service Client Binding. Then, choose a deployment
descriptor file and fill in the protocol and attribute information.
e. For Native Binding:
1) Next to the Native Binding Name field, click Browse.
2) Select the protocol SYSTEM-I LOCAL; or a predefined shareable
protocol based on SYSTEM-I LOCAL. The definition includes one and
only one of the following attributes: binddir, which is a fully qualified
binding directory such as LIBNAME/BIND_DIR_NAME, as used to
access the service program; or library, which is the library in which the
service program resides.
Note that this binding cannot be set at run time, only at development time.
f. Click Finish. You can update the binding information later by selecting the
client binding and editing the information under EGL Service Client
Binding Details.
g. Save, close, and generate the deployment descriptor.
Now the deployment descriptor has client binding information that points to
the local service.
3. Create a program or other logic part to act as the requester.
4. In the requester, create a variable based on the service or interface part. The
part must be in scope.
import services.CalculatorService;

program localClientProgram type BasicProgram

localEGLService CalculatorService;

function main()
end

end
5. Apply the @BindService complex property to the variable and set the
bindingKey property field to the name of the client binding. In the previous
examples, this binding was named CalculatorService.
import services.CalculatorService;

program localClientProgram type BasicProgram

484 EGL Programmer’s Guide


localEGLService CalculatorService
{@BindService{bindingKey = "CalculatorService"}};

function main()
end

end
6. After you have created a variable that represents a service and bound that
service to the service part using the client binding information, you can use the
service through the variable:
import services.CalculatorService;

program localClientProgram type BasicProgram

localEGLService CalculatorService
{@BindService{bindingKey = "CalculatorService"}};

function main()
SysLib.writeStderr("Calling local EGL service: ");
outputString string;
outputString = "5+5=";
outputString += localEGLService.addIntegers(5,5);
SysLib.writeStderr(outputString);
end

end
7. Save, generate, and run the program.
Related concepts
“Overview of service-oriented architecture (SOA)” on page 475
Related tasks
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.
“Creating a deployment descriptor” on page 94
The EGL deployment descriptor provides service-binding detail when you are
generating a service, as well as service-binding detail when you are generating
a logical unit (program, library, handler, or service) that invokes a service.
“Calling a remote service”
You can call remote services from your EGL logic parts.
“Creating a service-access variable and binding it to a service” on page 491
After you have created binding information for a service, you can use the
service in an EGL logic part with a variable that represents the service.
Related reference
Interface part
Interface parts provide access to a remote service, such as a Web service.
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.

Calling a remote service


You can call remote services from your EGL logic parts.

Overview of service-oriented architecture (SOA) 485


Fundamentally, calling a service is equivalent to calling a function in an EGL
library: you specify the name of the function in the service, pass any required
arguments, and receive any return variable. However, there are several additional
steps that you need to perform to make sure that EGL can find and use the
external service at run time.

Calling a remote service has the following general steps:


1. In your deployment descriptor file, you create service client binding
information that tells EGL where to find the service at run time.
2. You also need an interface part or service part that represents the external
service at design time:
v If you created the binding information from a WSDL file, EGL can create an
interface part automatically from the information in the WSDL file.
v If you are using an EGL service, you can copy an interface part or service
part from the other application.
v Alternatively, you can create your own interface part. In this case, it is up to
you to ensure that the function prototypes in the interface part accurately
represent the real functions in the service.
3. In a logic part, you create a variable that is based on the interface part or
service part, bind that variable to the service using the binding information,
and then use the service through the variable. See “Creating a service-access
variable and binding it to a service” on page 491 for more information.

To add the service client binding information for a remote service, do as follows:
1. Open the deployment descriptor in the deployment descriptor editor.
2. On the Service Client Bindings page of the deployment descriptor editor, under
the heading Service Client Bindings, click Add.
3. In the Add a Service Binding window, click SOAP (Web) Binding, REST (Web)
Binding,EGL Binding, or Native Binding and then click Next.
4. For SOAP (Web) Binding, follow the steps described in Adding service client
binding information from a WSDL file.
5. For REST (Web) Binding, you must be accessing the service from a Rich UI
application. Specify the following details, which are explained in Creating an
Interface part to access a REST service and Declaring an interface to access a REST
service:
v Specify the EGL binding name. In most cases, click Browse next to the EGL
Binding Name field name and retrieve an Interface or Service part. The
name will be the value of the property @BindService, property field
bindingKey, as used when you declare a variable to invoke the service.
v In the baseURI field, specify a string that identifies the first qualifiers in the
URI being used to access the service.
v In the Session Cookie ID field, specify a string that identifies the session
cookie provided to the EGL Rich UI Proxy from a service.
6. For EGL Binding, follow the steps described in Adding service client binding
information for an EGL service.
7. For Native Binding:
a. Next to the Native Binding Name field, click Browse. This name will be the
value of the bindingKey property field when you declare a variable to
invoke the service.

486 EGL Programmer’s Guide


b. Select the protocol JAVA400; or a predefined shareable protocol based on
JAVA400. For details on the required settings, see the EGL Generation Guide
section on Deployment descriptor options for service clients.
Note that the service parameters in this case must be of fixed length; not a
non-structured record or of type STRING.
8. Click Finish. You can update the binding information later by selecting the
client binding and editing the information under EGL Service Client Binding
Details.
Related concepts
“Overview of service-oriented architecture (SOA)” on page 475
Related tasks
“Adding Web service deployment information to the deployment descriptor”
on page 496
After you have coded a service part that you want to expose as a Web service,
you must add information to the deployment descriptor that tells EGL to
generate the necessary Web service wrapper.
“Adding service client binding information from a WSDL file” on page 489
Service client binding information tells how the EGL runtime connects to a
service being invoked by your EGL code. This topic concerns SOAP (Web)
service invocation.
“Adding service client binding information for an EGL service”
Service client binding information tells how the EGL runtime connects to a
service being invoked by your EGL code. This topic concerns EGL service
invocation, not Web service invocation.
Creating an Interface part to access a REST service
Declaring an interface to access a REST service
“Calling a local service” on page 483
You can call an EGL or native service that is local to your application without
exposing that service as a Web service.
Related reference
Interface part
Interface parts provide access to a remote service, such as a Web service.
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.

Adding service client binding information for an EGL service


Service client binding information tells how the EGL runtime connects to a service
being invoked by your EGL code. This topic concerns EGL service invocation, not
Web service invocation.

For details on adding binding information for a Web service, see “Adding service
client binding information from a WSDL file” on page 489.

Prerequisites
v An EGL project
v An EGL deployment descriptor
v An interface part or service part that represents the external service at design
time:

Overview of service-oriented architecture (SOA) 487


– If the EGL service part that you want to use is either in your project or in a
project in your project’s build path, you can use that part directly as a local
service. See “Calling a local service” on page 483 for more information.
– You can copy a service part or interface part from another EGL project to use
in your project.
– If you do not have access to the other project, you can create an interface part
with functions that match the functions in the service. In this case, it is up to
you to ensure that the function prototypes in the interface part accurately
represent the real functions in the service.

Adding the service client binding information

To add the service client binding information:


1. Open the deployment descriptor in the deployment descriptor editor.
2. On the Service Client Bindings tab, under the Service Client Bindings
heading, click Add.
3. In the Add a Service Binding window, click EGL Binding and then click Next.
4. On the Add an EGL Binding page, click the Browse button, which is next to
the EGL Binding Name field.
5. In the EGL Interface Selection window, select the interface part or service part
that you will use to represent the service and click OK.
6. You can accept the default value for the EGL Binding Name or type a different
name. This name will be the value of the bindingKey property field when you
use the service in your logic parts.
7. Choose a protocol type for the client binding:
v If you have already defined a shared protocol for the service, click Choose
from protocols and select the shared protocol from the list.
v Choose LOCAL for a service in the same project or within your project’s
build path.
v Otherwise, choose a specific protocol type and then fill in the information for
the binding in the Attributes list.
8. Click Finish. The new client binding is listed in the Service Bindings list. You
can update the binding information later by selecting the client binding and
editing the information under EGL Service Binding.

Now you can use the binding in your code as explained in “Creating a
service-access variable and binding it to a service” on page 491.

Alternately, if you have the service part in your workspace already, you can create
the binding information directly from that service part. Right-click the part and
then click EGL Services → Create EGL Service Client Binding. Then, choose a
deployment descriptor file and fill in the protocol and attribute information for the
binding as in the steps above.
Related tasks
“Overview of service-oriented architecture (SOA)” on page 475
“Creating a deployment descriptor” on page 94
The EGL deployment descriptor provides service-binding detail when you are
generating a service, as well as service-binding detail when you are generating
a logical unit (program, library, handler, or service) that invokes a service.

488 EGL Programmer’s Guide


“Adding service client binding information from a WSDL file”
Service client binding information tells how the EGL runtime connects to a
service being invoked by your EGL code. This topic concerns SOAP (Web)
service invocation.
“Calling a local service” on page 483
You can call an EGL or native service that is local to your application without
exposing that service as a Web service.
“Creating a service-access variable and binding it to a service” on page 491
After you have created binding information for a service, you can use the
service in an EGL logic part with a variable that represents the service.
Related reference
Interface part
Interface parts provide access to a remote service, such as a Web service.
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.

Adding service client binding information from a WSDL file


Service client binding information tells how the EGL runtime connects to a service
being invoked by your EGL code. This topic concerns SOAP (Web) service
invocation.

Prerequisites
v An EGL project or EGL Web project
v An EGL deployment descriptor
v A Web Services Description Language (WSDL) file that describes the service you
want to use, located somewhere in your workspace.

Adding the service client binding information


1. Open the EGL deployment descriptor in the deployment descriptor editor.
2. On the Service Client Bindings tab, under the Service Client Bindings
heading, click Add.
3. In the Add a Service Binding window, click Web Binding and then click Next.
4. Next to the WSDL File field, you can select the checkbox Choose WSDL file
from workspace and copy it to the current project if the WSDL file is not in
your EGL project but is elsewhere in your workspace. If that checkbox is
checked, the Browse mechanism lets you search throughout your Workspace.
If that checkbox is cleared, the Browse mechanism lets you search in the EGL
source folders of your project and in the EGL source folders of any project
listed in your project’s EGL build path. (You can access the build-path details
by right clicking your project; clicking Properties; and at the resulting dialog
box, clicking EGL Build Path.)
5. Under Interface Options, click Generate EGL Interface from WSDL file. This
choice represents the preferred method for creating an Interface part to
represent the service at development time.
You can also create your own Interface part and select it under Use existing
EGL interface. In this case, you must ensure that the function prototypes in
the Interface part accurately represent the functions in the service.
6. You can accept the default value for the Web Binding Name or type in a
different name. The name will be the value of the bindingKey property field
when you access the service.

Overview of service-oriented architecture (SOA) 489


7. In the WSDL URI field, you have the option of specifying a string that
overrides the URL specified in the WSDL file. If you know that the service is
available at a location other than the location specified in the WSDL file, such
as a different version of the service used for production or testing, you can
enter that location here and use that version of the service.
8. Click Next.
9. On the New EGL Interface page, select the Interface parts that you want to
create from the WSDL file.
10. Click Next.
11. On the next page, each Interface part has a tab that lists each function in the
selected Interface part. You can select or clear the check box for any of the
functions and in this way choose which functions are represented in the new
Interface part.
12. Set the location and name for the new interface part in the Source folder,
Package, and EGL source file name fields.
13. Click Finish.

Now you can create variables based on the interface part and use these variables to
access the service. See “Creating a service-access variable and binding it to a
service” on page 491.

Shortcut

You can add client binding information directly from a WSDL file in your project
with the following shortcut:
1. In the Project Explorer view, right-click the WSDL file and then click Create
EGL Interfaces and Web Client Binding.
2. On the New EGL Interface page, select the interfaces you want to use from
the WSDL file.
3. Click Next.
4. On the next page, each interface has a tab on which each function in the
selected interfaces is listed. You can select or clear the check box for any of the
functions to choose which functions will be in the new interface part.
5. Set the location and name for the new interface part in the Source folder,
Package, and EGL source file name fields.
6. Click Next.
7. In the EGL deployment descriptor file name field, select the name of the
deployment descriptor file to add information to.
8. If you want to update information already in a deployment descriptor file,
select the Update all existing bindings check box.
9. In the table of ports, select the ports that you want to generate into interfaces.
You can change the binding name, which is the label for the Web service
deployment listing in the deployment descriptor file.
10. Click Finish.
Related tasks
“Creating a deployment descriptor” on page 94
The EGL deployment descriptor provides service-binding detail when you are
generating a service, as well as service-binding detail when you are generating
a logical unit (program, library, handler, or service) that invokes a service.

490 EGL Programmer’s Guide


“Creating a service-access variable and binding it to a service”
After you have created binding information for a service, you can use the
service in an EGL logic part with a variable that represents the service.
“Calling a remote service” on page 485
You can call remote services from your EGL logic parts.
“Calling a local service” on page 483
You can call an EGL or native service that is local to your application without
exposing that service as a Web service.
Creating an Interface part to access a Web service in Rich UI
Declaring an interface to access a Web service in Rich UI
Related reference
Interface part
Interface parts provide access to a remote service, such as a Web service.
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.

Creating a service-access variable and binding it to a service


After you have created binding information for a service, you can use the service
in an EGL logic part with a variable that represents the service.

A service behaves much like a library in that they are both a group of functions
that are available for use by other logic parts. However, calling a service requires
more preparation than calling a library.

When you call a function within a library, you type the name of the library, a
period, and the name of the function, followed by any arguments the function
expects:
myInt int = MathLib.abs(-5);

A call to a function within a service looks the same because the call uses similar
syntax:
mySum int = Calculator.addIntegers(1, 2);

However, the call to a service is different because the code is not calling the service
directly (as the example above called MathLib.abs() directly), but instead is using
a variable that represents that service. In the previous example, Calculator is a
variable that is created from a Service part or Interface part and then linked, or
bound, to the service itself. The binding information in the deployment descriptor
file tells EGL how to bind that variable to the service at run time.

Prerequisites
v An EGL project
v Client binding information for a Web service or an EGL service.
v An Interface part or Service part.
v Any EGL logic part, such as a Program, Library, Service, or Handler

Binding a variable explicitly

To bind a variable to an external service, create a variable from an Interface or


Service part and then set the property field bindingKey to the name attribute of
the service binding information entry in the deployment descriptor file.

Overview of service-oriented architecture (SOA) 491


For example, assume that you created the following entry in the deployment
descriptor file while working through the topic “Adding service client binding
information from a WSDL file” on page 489:
<webBinding interface="interfaces.StockQuote"
name="quoteBinding"/>

This entry is named quoteBinding and refers to an Interface part or Service part in
the interfaces package named StockQuote.

You can use the service that this entry represents by creating a variable that is
based on the part listed in the entry and specifying the name of the entry in the
bindingKey property field:
myQuoteGenerator stockQuote {@BindService{bindingKey = "quoteBinding"}};

Then you can call the functions in the service through the variable:
myStockPrice float = myQuoteGenerator.getQuote("IBM");

If you do not specify a value in the bindingKey property field, EGL assumes that
the name of the entry in the deployment descriptor matches the name of the
Interface part or Service part. For example, assume the following entry in the
deployment descriptor file:
<webBinding interface="interfaces.CalculatorService"
name="CalculatorService"/>

In this case, you can omit the bindingKey property field, but the @BindService
complex property is still required:
myCalculator CalculatorService {@BindService};
mySum int = myCalculator.addIntegers(1, 1);

Binding a variable dynamically

Dynamic binding enables you to choose a service at run time, or to change the
service to which a variable is bound. To bind a variable dynamically, use functions
in the EGL library ServiceLib instead of the @BindService property. This option is
not available for local access of a native service on System i.

Suppose that you have created entries in the deployment descriptor file for two
slightly different service implementations:
<webBinding interface="interfaces.SpeechTranslator"
name="TranslateSpanish" port="SpanishPort"/>

<webBinding interface="interfaces.SpeechTranslator"
name="TranslateGerman" port="GermanPort"/>

You could create and bind two variables, one for each of these entries. An alternate
way is to create one variable based on the Interface part that the entries share, and
then use the ServiceLib.bindService() system function to bind the variable to the
service that you want to use.
1. Create a variable that is based on the Interface or Service part in the
deployment descriptor entry:
myTranslator SpeechTranslator;
2. Use the bindService() function to bind the variable to the service
implementation:
myTranslator = ServiceLib.bindService("TranslateSpanish");

492 EGL Programmer’s Guide


In this case, the myTranslator variable is now bound to the entry in the
deployment descriptor file named TranslateSpanish.
3. Use the variable to access the service:
mySpanishString string = myTranslator.translate
("This sentence is in Spanish");
4. Later, you can use bindService() again to bind the service to a different
implementation:
myTranslator = ServiceLib.bindService("TranslateGerman");
5. At this point, you can use the variable to access the alternate implementation of
the service:
myGermanString string = myTranslator.translate
("This sentence is in German");
Related tasks
“Adding service client binding information from a WSDL file” on page 489
Service client binding information tells how the EGL runtime connects to a
service being invoked by your EGL code. This topic concerns SOAP (Web)
service invocation.
“Adding service client binding information for an EGL service” on page 487
Service client binding information tells how the EGL runtime connects to a
service being invoked by your EGL code. This topic concerns EGL service
invocation, not Web service invocation.
“Calling a local service” on page 483
You can call an EGL or native service that is local to your application without
exposing that service as a Web service.
“Calling a remote service” on page 485
You can call remote services from your EGL logic parts.
Related reference
Interface part
Interface parts provide access to a remote service, such as a Web service.
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.

Exposing a service to other applications


Your EGL application can act as a service by exposing its functions to other
applications.

Creating an EGL service has these general steps:


1. Optionally, define one or more Interface parts. Interface parts contain function
prototypes, which list the function’s name, its parameters, and its return value,
but have no internal logic.
2. Code one or more EGL Service parts and any other parts they may need.
3. Add binding information for the service in the EGL deployment descriptor file.
4. Distribute the binding information for your service so other applications can
connect to your service.

Creating an interface (optional)


1. Create an EGL Interface part. You can put the Interface part in the same
package as your service or in another package; the scoping rules for interfaces
are the same as for any other part. See “Creating EGL source files” on page 90.

Overview of service-oriented architecture (SOA) 493


2. In the Interface part, write function prototypes that describe the functions your
service performs, including the name of the function, its parameters and their
types, and its return value, if any:
package interfaces;

interface calculatorInterface

function addIntegers(intOne int in, intTwo int in)


returns (int);

function subtractIntegers(intOne int in, intTwo int in)


returns (int);

end

Provide prototypes in the interface only for the functions that you intend to
expose to other applications. These functions are referred to as public. The
service can contain functions that are not described in the interface, and those
additional functions can optionally be defined as private. Only the service itself
can access its private functions, but any logic part or application can access the
public functions of the service. Functions in a service are public by default.

Coding a Service part

You code a Service part in much the same way as a Library part.
1. Create an EGL Service part. See “Creating EGL source files” on page 90.
2. If you want the Service part to use an interface, add an implements clause to
the service part:
package services;

service calculatorService implements interfaces.calculatorInterface

//Add functions here.

end

Alternately, you can select an interface to implement when you create the
service. In this case, EGL creates stub functions for the functions that are
defined in the interface.
When a service implements an interface, that service must define each function
that is listed in the interface, and the input and output parameters of those
functions must match those of the prototypes in the interface. EGL produces an
error if any function in a service does not match the prototype of the same
name in the interface, as well as if any function prototype in the interface is not
defined in the service. Also, a service can implement more than one interface.
In that case, the service must define each function that is prototyped in each
interface.
3. Write the code for the functions in the service, including any functions defined
in the interface and any private functions your services may need:
package services;

service calculatorService implements interfaces.calculatorInterface

function addIntegers(intOne int in, intTwo int in)


returns (int)
return(intOne + intTwo);
end

function subtractIntegers(intOne int in, intTwo int in)

494 EGL Programmer’s Guide


returns (int)
return(intOne - intTwo);
end

private function getAbsoluteValueInteger(intOne int in)


returns(int)
return(MathLib.abs(intOne));
end

end

Adding Web service deployment information

Now, EGL requesters can access your Service part directly. However, for non-EGL
requesters to access the service, you must expose your service as a SOAP or REST
service, which involves adding Web service deployment information to the
deployment descriptor file. See Adding Web service deployment information to the
deployment descriptor.

Distribute the binding information

After you have coded and deployed your service application, you must distribute
its information so client applications can use the service. For an EGL client
application to access your service, you need only distribute the binding
information that the client needs. For a non-EGL client application to access the
service, or for an EGL client application to access the service through a Web service
connection, you must distribute the WSDL file that is created when you generate
the project.
Related tasks
“Adding Web service deployment information to the deployment descriptor”
on page 496
After you have coded a service part that you want to expose as a Web service,
you must add information to the deployment descriptor that tells EGL to
generate the necessary Web service wrapper.
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.
“Creating a deployment descriptor” on page 94
The EGL deployment descriptor provides service-binding detail when you are
generating a service, as well as service-binding detail when you are generating
a logical unit (program, library, handler, or service) that invokes a service.
“Calling a remote service” on page 485
You can call remote services from your EGL logic parts.
“Calling a local service” on page 483
You can call an EGL or native service that is local to your application without
exposing that service as a Web service.
Related reference
Interface part
Interface parts provide access to a remote service, such as a Web service.
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.
Function prototypes

Overview of service-oriented architecture (SOA) 495


Adding Web service deployment information to the
deployment descriptor
After you have coded a service part that you want to expose as a Web service, you
must add information to the deployment descriptor that tells EGL to generate the
necessary Web service wrapper.

Prerequisites
v An EGL project
v A Service part
v An EGL deployment descriptor file

Adding the deployment information


1. Open the EGL deployment descriptor file and go to the Service Deployment
tab.
2. Click Add.
3. In the Add Web Services window, select the service parts to be exposed as a
Web service by moving them from the EGL service parts found list to the EGL
service parts to be generated as Web services list.
4. Click Finish. Each service part that you chose is listed on the Services
Deployment page.
5. Select a service part in the list on the left:
v In the Generate column, indicate whether you want EGL to generate the
Web service each time you generate the deployment descriptor; and if so,
whether you want the service generated as a SOAP (Web) service, a REST
(Web) service, or both. Avoid the overhead of generating the Web service if
you are not changing the service part when you generate the deployment
descriptor.
v To access the service logic, double-click an entry in the Implementation
column; or highlight the service-binding name and click Open.
6. Additional information varies by service type:
v For a SOAP (Web) service, indicate whether you want to identify the service
characteristics with an existing WSDL file. If you check Use Existing WSDL
file, you can specify the WSDL file and, within that file, the WSDL service
and port elements. If you intend to create the WSDL file later, specify a value
in the Style field; select document-wrapped unless the requesters need rpc.
If you intend to run the SOAP (Web) service on CICS, you also may need to
specify the access details under Platform-Specific Properties; specifically, the
access protocol, as well as the URI used to access the service.
In the CICS URI field, assign the low-level qualifier for the address used to
access the SOAP service. The full address is as follows:
http://domain:portNumber/URI
domain
The domain name; for example, www.example.com.
portNumber
The number of the server-machine port that receives the request.
URI
The qualifier you are specifying. By default, the value is as follows,
where serviceName is the name of the Service part:
services/serviceName

496 EGL Programmer’s Guide


v For a REST (Web) service, you can select or clear the Stateful checkbox to
indicate whether the service is providing access to a stateful host program on
IBM i. The issue is explained in Accessing IBM i programs as Web services.
Also, in the URI field, assign the low-level qualifier for the address used to
access the REST service. The full address is as follows:
http://domain:portNumber/contextRoot/restservices/URI
domain
The domain name; for example, www.example.com.
portNumber
The number of the server-machine port that receives the request.
contextRoot
A setting in the Web project. The default is the name of the Web project.
In relation to WebSphere Application Server, the value is in the JEE EAR
deployment descriptor (application.xml).
URI
The qualifier you are specifying.
7. Save the deployment descriptor, which in most cases causes an automatic
generation of output from that file.
Related concepts
“Elements of a service-oriented application” on page 478
The major elements of an EGL service-oriented application are the service part,
interface part, and deployment descriptor file. In general, each of these files and
parts has a role in both services and service requesters.
Accessing IBM i programs as Web services
“Overview of service-oriented architecture (SOA)” on page 475
Related tasks
“Exposing a service to other applications” on page 493
Your EGL application can act as a service by exposing its functions to other
applications.

Creating and using a shared protocol


Shared protocols are reusable definitions of a service connection that you can apply
to one or more of the entries in an EGL deployment descriptor file.

To create and use a shared protocol:


1. Open the EGL deployment descriptor file for your project. If your project does
not have a deployment descriptor file, see “Creating a deployment descriptor”
on page 94.
2. In the deployment descriptor editor, go to the Protocols tab.
3. Under Sharable Protocols, click Add. The Add Protocol window opens.
4. In the Protocol Name, enter a mnemonic for the new protocol.
5. Under Choose protocol type, select a type of protocol. Use Local for services in
the same project.
6. Under Attributes, set the options for the protocol. These options differ for each
type of protocol. See Deployment descriptor options for service clients.
7. Click Finish. The new protocol is listed under Sharable Protocols, and you can
use that protocol when you create a new service client binding or Web service
binding.
Related tasks

Overview of service-oriented architecture (SOA) 497


“Calling a remote service” on page 485
You can call remote services from your EGL logic parts.
“Calling a local service” on page 483
You can call an EGL or native service that is local to your application without
exposing that service as a Web service.
“Adding service client binding information from a WSDL file” on page 489
Service client binding information tells how the EGL runtime connects to a
service being invoked by your EGL code. This topic concerns SOAP (Web)
service invocation.

Setting preferences for service generation


You can set defaults for how your services are generated.
1. From the menu bar, click Window → Preferences. The Preferences window
opens.
2. In the left pane of the Preferences window, expand EGL and click Service.
3. In the right pane of the Preferences window, select the preferences for
generating Web services:
v Under WSDL Document Style/Encoding, select Document-Literal Wrapped
unless the requesters require RPC-Literal.
v Under WSDL Generation, enter the default host name and port to place in
WSDL files generated to describe EGL Web services.
You can restore the default settings by clicking Restore Defaults.
4. Click OK to save your changes.
Related concepts
“Overview of service-oriented architecture (SOA)” on page 475
Related tasks
“Setting general preferences” on page 173

498 EGL Programmer’s Guide


Building EGL Text User Interface applications
A Text UI application presents a text-based user interface similar to that of a 5250
or 3270 terminal.

You can use the EGL Text UI technology to create a very basic user interface, like
one you would find on a mainframe. This means you can generate programs for
both COBOL and Java that present an identical interface to the user.

Text UI interfaces are based on forms. A form contains fields that are displayed
together on a screen page or sent together to a printer. Properties determine how
each field is displayed or printed within the form.

Each EGL Form part must be part of a FormGroup.

Text UI programs carry on a conversation with the user. The EGL converse
statement gives control to the form; when the user presses a key, control returns to
the program and the program processes the information in the form.

Example
To create a simple Text UI program, first create a FormGroup in a new EGL source
file:
FormGroup myFormGroup

Form myTextForm type textForm {formSize=[10,80]}


msgField CHAR(80);
end
end

Next, in a new EGL source file, create a program with a use statement that
references the FormGroup:
Program HelloWorld type textUIprogram
{}
use myFormgroup;
myMessage char(25) = "myMessage";

function main()
while (ConverseVar.eventKey not pf3)
myTextForm.msgField = myMessage;
converse myTextForm;
if (ConverseVar.eventKey is pf3)
exit program;
end
if (ConverseVar.eventKey is pf1)
myMessage = "Hello World";
end
end
end
end

If you press the F1 key, the message changes from ″myMessage″ to ″Hello World″.
If you press the F3 key, the program exits.
Related concepts
“Elements of a text user interface application” on page 500
A Text UI application relies on Form parts to define a user interface.
© Copyright IBM Corp. 1996, 2008 499
Text UI
A text UI application presents a text-based user interface similar to that of a
5250 or 3270 terminal.
Related reference
FormGroup part
Form part
converse considerations for Text UI

Elements of a text user interface application


A Text UI application relies on Form parts to define a user interface.
Form parts
Form parts describe a set of fields on a user interface. A Form part can be
one of the following two types:
v A text form defines a layout that is displayed on a 3270 screen or in a
command window. Help forms, a subtype of text forms, display help
information to explain how the interface works.
v A print form defines a layout that is sent to a printer.
FormGroup parts
A FormGroup part contains one or more Form parts.
Related concepts
“Building EGL Text User Interface applications” on page 499
A Text UI application presents a text-based user interface similar to that of a
5250 or 3270 terminal.
Text UI
A text UI application presents a text-based user interface similar to that of a
5250 or 3270 terminal.
Related reference
FormGroup part
Form part

Building EGL Text User Interface applications with the Text Form
editor
With the EGL Text Form editor, you can edit a FormGroup part graphically. The
Text Form editor works with FormGroup parts, their form parts, and the fields in
those form parts in much the same way as other graphical editors work with files
such as Web pages and Web diagrams. At any time, you can click the Source tab at
the bottom of the editor and see the EGL source code that the editor is generating.

The Text Form editor has these parts:


v The editor itself, which displays the graphical representation of the form group
and that form group’s source code. You can switch between the graphical
representation and the source code by clicking the Design and Source tabs at
the bottom of the editor. Changes to the Source view or Design view are
reflected immediately in the other view.
v The Properties view, which displays the EGL properties of the form or field
currently selected in the editor.
v The Palette view, which displays the types of forms and fields that can be
created in the editor.

500 EGL Programmer’s Guide


v The Outline view, which displays a hierarchical view of the form group open in
the editor.

The Text Form editor has these features:


v The Text Form editor can edit the size and properties of a form group. To edit
the properties of a form group, open the form group in the Text Form editor and
change its properties in the Properties view. To resize a form group, open it in
the Text Form editor and choose a size in characters from the list at the top of
the editor.
v The Text Form editor can create, edit, and delete forms in a form group. To
create a form, click the appropriate type of form on the Palette view and draw a
rectangle that represents the size and location of the form in the editor. To edit a
form, click it to select it, and then use the Properties view to edit its properties.
You can also drag a form to move it, or resize it using the resize handles that are
on the border of a selected form. Many of the same options are available when
you right-click a form to open its menu. See “Creating a simple text or print
form” on page 502.
v The Text Form editor uses templates to create commonly used types of forms,
such as popup forms and popup menus. These forms have pre-made borders,
sections, and fields. “Creating a form from a template” on page 505.
v With the Text Form editor, you can create, edit, and delete fields in a form. To
create a field, click the appropriate type of field on the Palette view and draw a
rectangle that represents the size and location of the field in the editor. You can
add a field only within an existing form. To edit a field, click it to select it, and
then use the Properties view to edit its properties. You can also copy and paste a
field, drag a field to move it, or resize a field using the resize handles that are
on the border of a selected form. Many of the same options are available when
you right-click a field to open its menu. See“Creating a constant field” on page
502 or “Creating a variable field” on page 503.
v Filters can prevent forms from being shown in the Text Form editor, enabling
you to mimic the appearance of the form group at run time. To switch filters,
create a filters, or edit filters, use the Filters button at the top of the editor. See
“Filtering the editor” on page 509.
v You can customize the appearance of the Text Form editor by using the display
options at the top of the editor and by setting the editor preferences in the
Preferences window. For example, these options can display a grid over the form
group, increase or decrease the zoom level, and show or hide sample values in
fields. See“Display options for the EGL Text Form editor” on page 510 or
“Setting preferences for the Text Form editor” on page 510.
Related tasks
“Creating a simple text or print form” on page 502
“Setting preferences for the Text Form editor” on page 510
“Creating a form from a template” on page 505
The EGL Text Form editor uses templates to create commonly used types of
forms and fields. These templates are listed in the Templates drawer of the
Palette view.
“Setting preferences for the Text Form editor palette entries” on page 512
“Setting bidirectional text preferences for the Text Form editor” on page 511
Related reference
“Display options for the EGL Text Form editor” on page 510
FormGroup part
Form part

Building EGL Text User Interface applications 501


“Filtering the editor” on page 509

Creating a simple text or print form


To create a form in the EGL Text Form editor, follow these steps:
1. Open a form group in the Text Form editor.
2. On the Palette view, click either Text Form or Print Form.
3. On the form group in the editor, click and drag a rectangle that indicates the
size and shape of the form. The Create Form Part window opens.
4. In the Create Form Part Window, type a name for the form in the Enter part
name field. This name will be the name of the form part in the EGL source
code.
5. Click OK.
6. Click the form and edit its properties in the Properties view.
7. Add fields to the form as appropriate. See“Creating a constant field” and
“Creating a variable field” on page 503.

You can also create forms based on the templates in the Palette view. These
templates create forms with predefined appearances and fields. See “Creating a
form from a template” on page 505.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
“Display options for the EGL Text Form editor” on page 510
Related tasks
“Filtering the editor” on page 509
“Creating a popup form” on page 506
“Creating a popup menu” on page 507
“Creating a constant field”
“Creating a variable field” on page 503
“Creating a form from a template” on page 505
The EGL Text Form editor uses templates to create commonly used types of
forms and fields. These templates are listed in the Templates drawer of the
Palette view.
Related reference
Form part

Creating a constant field


Constant fields display a string of text that does not change in a form. Unlike
variable fields, constant fields cannot be accessed by EGL code. To insert a constant
field into a form, follow these steps:
1. Open a form group in the EGL Text Form editor.
2. If the form group has no forms, add a form to the form group. See “Creating a
simple text or print form.”
3. On the Palette view, click a type of constant field to add. The following types
of constant fields are available by default:

502 EGL Programmer’s Guide


Table 54. Constant fields that are available in the Palette view
Default Default Default
Field name Default color intensity highlighting protection
Title Blue Bold None Skip
Column Blue Bold None Skip
Heading
Label Cyan Normal None Skip
Instructions Cyan Normal None Skip
Help White Normal None Skip

These fields are samples of commonly used constant text fields in a text-based
interface. You can customize the individual fields after placing them on a form.
You can also customize the default color, intensity, and highlighting of the
fields that are available in the Palette view. See “Setting preferences for the Text
Form editor palette entries” on page 512.
4. Within a form in the editor, click and hold the mouse to draw a rectangle that
represents the size and location of the field. A preview box next to the mouse
cursor shows you the size of the field and its location relative to the form.

Note: You can add a field only within an existing form.


5. When the field is the correct size, release the mouse. The new field is created.
6. Type the text you that want to display in the field.
7. In the Properties view, set the properties for the new field.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
Related tasks
“Setting preferences for the Text Form editor palette entries” on page 512
“Creating a variable field”
Related reference
Form part

Creating a variable field


Variable fields can serve as input or output text in a form. Each variable field is
based on an EGL primitive or a DataItem part. Unlike constant fields, variable
fields can be accessed by EGL code. To insert a variable field into a form, follow
these steps:
1. Open a form group in the EGL Text Form editor.
2. If the form group has no forms, add a form to the form group. See “Creating
a simple text or print form” on page 502.
3. On the Palette view, click a type of variable field to add. The following types
of variable fields are available by default:
Table 55. Variable fields that are available in the Palette view
Default Default Default
Field name Default color intensity highlighting protection
Input Green Normal Underlined No
Output Green Normal None Skip
Message Red Bold None Skip

Building EGL Text User Interface applications 503


Table 55. Variable fields that are available in the Palette view (continued)
Default Default Default
Field name Default color intensity highlighting protection
Password Green Invisible None No

These fields are samples of commonly used variable text fields in a text-based
interface. You can customize the individual fields after placing them on a
form. You can also customize the default color, intensity, and highlighting of
the fields available in the Palette view. See “Setting preferences for the Text
Form editor palette entries” on page 512.
4. Within a form in the editor, click and hold the mouse to draw a rectangle that
represents the size and location of the field. A preview box next to the mouse
cursor shows you the size of the field and its location relative to the form.

Note: You can add a field only within an existing form.


5. When the field is the correct size, release the mouse. The New EGL Field
window opens.
6. In the New EGL Field window, type the name of the new field in the Name
field.
7. Do one of the following to select the type of field:
v To use a primitive type, click a primitive type from the Type list.
v To use a DataItem part, follow these steps:
a. Click dataItem from the Type list. The Select a DataItem Part window
opens.
b. In the Select a DataItem Part window, click a DataItem part from the list
or type the name of one.
c. Click OK.
8. As necessary, type values in the Dimensions field or fields to set the
dimensions of the new variable field.
9. If you want to make the field an array, select the Array check box.
10. If the Array check box is selected, click Next and continue following these
steps. Otherwise, click Finish and stop here. The new field is created and you
do not need to follow the rest of these steps, because they are applicable only
if you are creating an array.
11. On the Array Properties page of the New EGL Field window, type the size of
the array in the Array Size field.
12. Choose an orientation of Down or Across from the Index Orientation
buttons.
13. Under Layout, type the number of vertical and horizontal fields in the Fields
Down and Fields Across fields.
14. Under Spaces, type the amount of space between the array’s rows and
columns in the Lines between rows and Spaces between columns fields.
15. Click Finish. The new field is created in the form group.

After you have created the new field, click the field to select it and set the
properties for the field in the Properties view. For more information about
properties for form fields, see Form field properties. For more information about
properties for form fields, see ″Form field properties″ in the EGL Language
Reference. Be aware that display properties affect the way EGL displays the variable
on a printed form or on the screen, but not the way the variable is stored. For
example, setting the align property to right for a CHAR variable does not

504 EGL Programmer’s Guide


right-align the contents of the variable; EGL right-aligns the information on the
page or screen only. (For a shortcut to right-justify a variable, see “Right-justifying
a character variable” on page 146.)

Because variable fields have no default value, they can be invisible if they are not
highlighted. To mark each variable field with appropriate sample text, click the
Toggle Sample Values button at the top of the editor.

After you have created a variable field, you can double-click it in the editor to
open the Edit Type Properties window. From this window you can edit the field in
the following ways:
v Change the field’s name by typing a new name in the Field Name field.
v Select a new type of field from the Type list.
v Change the precision of the field by specifying a new number in the Precision
field.

When you are finished editing the field’s properties in the Edit Type Properties
window, click OK.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
Related tasks
“Setting preferences for the Text Form editor palette entries” on page 512
“Creating a constant field” on page 502
Related reference
Form part

Creating a form from a template


The EGL Text Form editor uses templates to create commonly used types of forms
and fields. These templates are listed in the Templates drawer of the Palette view.

The Text Form editor can create forms from templates. These forms have pre-made
borders, sections, and fields. To create a form from a template, see“Creating a
popup form” on page 506 or “Creating a popup menu” on page 507.

The Text Form editor can create a group of fields using an EGL record as a
template. To create fields representing data from an EGL record, see “Displaying a
record in a text or print form” on page 507.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
“Creating a form from a template”
The EGL Text Form editor uses templates to create commonly used types of
forms and fields. These templates are listed in the Templates drawer of the
Palette view.
Related tasks
“Setting preferences for the Text Form editor” on page 510
“Creating a simple text or print form” on page 502
“Creating a constant field” on page 502
“Creating a variable field” on page 503
“Creating a popup menu” on page 507

Building EGL Text User Interface applications 505


“Creating a popup form”
“Displaying a record in a text or print form” on page 507

Creating a popup form


A popup form is a special kind of form that can be added to a form group.
Fundamentally, a popup form is the same as an ordinary text form, but popup
forms are created with pre-made features like borders and sections. To create a
popup form in the EGL Text Form editor, follow these steps:
1. Open a form group in the Text Form editor.
2. On the Palette view, click Popup Form.
3. On the form group in the editor, click and drag a rectangle that indicates the
size and shape of the popup form. The Create Form Part window opens.
4. In the Create Form Part Window, type a name for the form in the Enter part
name field. This name will be the name of the form part in the EGL source
code.
5. Click OK. The New Popup Form Template window opens.
6. In the New Popup Form Template window, specify the characters to use for
the form’s borders in the Vertical Character and Horizontal Character fields.
7. Click a color for the border from the Color list.
8. Click an intensity for the border from the Intensity list.
9. Click a highlight value from the Highlight radio buttons.
10. Repeat the following steps for each section that you want to add to the form.
You must add at least one section to the form.
a. Under Popup Sections, click the Add button. The Create Popup Form
Section window opens.
b. In the Create Popup Form Section window, type a name for the section in
the Section Name field.
c. In the Number of rows field, type the number of rows in the section. Do
not type a number greater than the number of remaining effective rows,
which is displayed at the bottom of the New Popup Form Template
window.
d. Click OK.
e. Use the Up and Down buttons to set the order of the fields.

Note: The total number of rows in the popup field’s sections cannot exceed
the total number of rows in the popup field. When adding sections, pay
attention to the Remaining Effective Rows field and remember that
dividers between the sections require an additional row for each new
field.
11. When you are finished adding sections to the popup field, click Finish. The
new popup form is created in the editor.
12. Add fields to the form as appropriate. See“Creating a constant field” on page
502 and “Creating a variable field” on page 503.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
“Creating a form from a template” on page 505
The EGL Text Form editor uses templates to create commonly used types of
forms and fields. These templates are listed in the Templates drawer of the
Palette view.
Related tasks
506 EGL Programmer’s Guide
“Setting preferences for the Text Form editor” on page 510
“Creating a simple text or print form” on page 502
“Creating a constant field” on page 502
“Creating a variable field” on page 503
“Creating a popup menu”

Creating a popup menu


A popup menu is a special kind of form that can be added to a form group.
Fundamentally, a popup menu is the same as an ordinary text form, but popup
menus are created with pre-made features like a title, help text, and a specified
number of menu options. To create a popup menu in the EGL Text Form editor,
follow these steps:
1. Open a form group in the Text Form editor.
2. On the Palette view, click Popup Menu.
3. On the form group in the editor, click and drag a rectangle that indicates the
size and shape of the popup menu. The Create Form Part window opens.
4. In the Create Form Part Window, type a name for the form in the Enter part
name field. This name will be the name of the form part in the EGL source
code.
5. Click OK. The New Popup Menu Template window opens.
6. In the New Popup Menu Template, specify the size of the popup menu in the
Width and Height fields. By default, these fields are populated with the size
of the form you created in the editor.
7. In the Menu Title field, type the title of the menu.
8. In the Number of Menu Options field, type the number of menu options that
the popup menu will have.
9. In the Menu Help Text field, type any additional help text for the menu.
10. Click Finish. The new popup menu is created in the editor.
11. Add fields to the new popup menu and edit the existing fields as appropriate.
See “Creating a constant field” on page 502 and “Creating a variable field” on
page 503.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
“Creating a form from a template” on page 505
The EGL Text Form editor uses templates to create commonly used types of
forms and fields. These templates are listed in the Templates drawer of the
Palette view.
Related tasks
“Setting preferences for the Text Form editor” on page 510
“Creating a simple text or print form” on page 502
“Creating a constant field” on page 502
“Creating a variable field” on page 503
“Creating a popup form” on page 506

Displaying a record in a text or print form


The Record template, which is found in the Templates drawer of the Palette view,
creates a group of form fields that are equivalent to the fields in an EGL record
part. To create the form fields, follow these steps:
1. Open a form group in the EGL Text Form editor.

Building EGL Text User Interface applications 507


2. Create a form. See “Creating a simple text or print form” on page 502.
3. On the Palette view, click Record.
4. Within a form in the editor, click and hold the mouse to draw a rectangle that
represents the size and location of the fields. A preview box next to the mouse
cursor shows you the size of the record fields and their location relative to the
field.

Note: You can add a record only within an existing form.


5. When the record is the correct size, release the mouse. The EGL Record
Placement window opens.
6. In the EGL Record Placement, click Browse. The Select a Record Part dialog
opens.
7. In the Select a Record Part dialog, click the name of the record part that you
want to use or type the name of a record part.
8. Click OK. The Create a Record window is populated with a list of the fields
in that record.
9. Using one or more of the following methods, select and organize the record
part fields that you want to display as fields in the form:
v To remove a field, click its name and then click Remove .
v To add a field, follow these steps:
a. Click the Add button. The Edit Table Entry window opens.
b. In the Edit Table Entry window, type a name for the field in the Field
Name box.
c. In the Type list, select a type for the field.
d. If necessary for the type you have selected, specify the precision for the
field in the Precision field.
e. Specify a width for the field in the Field Width field.
f. If you want the field to be an input field, select the Make this field an
input field check box. Otherwise, clear the check box.
g. Click OK.
v To edit a field, follow these steps:
a. Click the field’s name.
b. Click the Edit button. The Edit Table Entry window opens.
c. In the Edit Table Entry window, type a name for the field in the Field
Name box.
d. In the Type list, select a type for the field.
e. If necessary for the type you have selected, enter the precision for the
field in the Precision field.
f. Specify a width for the field in the Field Width field.
g. If you want the field to be an input field, select the Make this field an
input field check box. Otherwise, clear the check box.
h. Click OK.
v To move fields up or down in the list, use the Up and Down buttons.
10. Using the Orientation radio buttons, choose a vertical or horizontal
orientation for the fields.
11. In the Number of Rows field, specify the number of rows you want the group
of fields to have.
12. If you want the group of fields to have a header row, select the Create header
row check box.

508 EGL Programmer’s Guide


13. Click Finish.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
“Creating a form from a template” on page 505
The EGL Text Form editor uses templates to create commonly used types of
forms and fields. These templates are listed in the Templates drawer of the
Palette view.
Related tasks
“Creating a simple text or print form” on page 502
“Creating a constant field” on page 502
“Creating a variable field” on page 503

Filtering the editor


Filters limit which forms are shown in the EGL Text Form editor. You can define
any number of filters, but only one filter can be active at a time. Filters affect only
the presentation of the form group at design time; they do not affect the EGL code
in any way.

You can switch between active filters with the list next to the Filters button at the
top of the editor. To create, edit, or delete filters, click the Filters button.

From the Filters window, you can manage your filters by using the following
functions:
v Select filters from the list.
v Add a new filter by clicking New.
v Delete a filter by selecting it from the list and clicking Remove.
v Select which forms are displayed when the filter is active.

To create a new filter in the EGL Text Form editor, follow these steps:
1. Open a form group in the Text Form editor.
2. In the Text Form editor, click the Filters button. The Filters window opens.
3. In the Filters view, click the New button. The New Filter dialog box opens.
4. In the New Filter dialog box, type a name for the filter and click OK.
5. Select the forms to be displayed while the filter is active by doing one or more
of the following steps:
v Clear the check boxes next to the forms that you want hidden by the filter.
v Select the check boxes next to the forms that you want shown by the filter.
v Click the Select All button to show every form.
v Click the Deselect All button to hide every form.
6. Click OK.
The new filter is active. You can switch filters by using the list next to the
Filters button.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
“Display options for the EGL Text Form editor” on page 510
Related tasks
“Creating a simple text or print form” on page 502

Building EGL Text User Interface applications 509


Display options for the EGL Text Form editor
The EGL Text Form editor has display options that enable you to control how form
groups are displayed in the editor at design time. These options do not change the
appearance of the form group at run time. From left to right at the top of the
editor, these are the buttons that control the display options:
Size This drop-down list allows you to select a new size for the form.
Toggle 4 color mode
Allows you to switch between monochromatic and 4-color modes.
Toggle rulers
Shows or hides rulers at the top and left side of the editor.
Toggle Gridlines
This option displays a grid over the form group to help in sizing and
arranging forms. To change the color of the grid, see “Setting preferences
for the Text Form editor.”
Toggle Sample Values
This option inserts sample values into variable fields, which are otherwise
invisible.
Toggle Black and White Mode
This option switches the background of the editor from black to white.
Zoom Level
Sets the magnification level of the editor.
Filters Sets the active filters. See “Filtering the editor” on page 509.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
Related tasks
“Filtering the editor” on page 509
“Setting preferences for the Text Form editor”

Setting preferences for the Text Form editor


The preferences for the EGL Text Form editor can change the appearance of the
Text Form editor, such as the background color and grid color. To change the
preferences for the Text Form editor, follow these steps:
1. From the menu bar, click Window → Preferences. The Preferences window
opens.
2. In the left pane of the Preferences window, expand EGL and click Text Form
editor.
3. In the right pane of the Preferences window, select the preferences for the Text
Form editor:
v In the Background Color field, select a background color for the Text Form
editor.
v In the Grid Color field, select a grid color for the Text Form editor.
v If you want to show a border around fields, select the Highlight fields check
box and select a color.
v If you want to show rulers at the top and left side of the Text Form editor,
select the Show rulers check box.
v In the Font list, click a font for the fields and click a size from the adjacent
list.

510 EGL Programmer’s Guide


Note: Choose a monospace font to ensure that your fields display at the
correct size in the Text Form editor. A monospace font is a font whose
characters all have the same width, such as Courier New.
v If you want blinking fields to be displayed in italic type in the editor, select
the Visually demonstrate blinking fields check box. This option does not
change the appearance of the fields at run time; it only changes their
appearance at design time.

Note: You can restore the EGL Text Form editor preferences window to its
default settings by clicking Restore Defaults.
4. When you are finished setting the preferences for the EGL Text Form editor,
click OK.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
“Filtering the editor” on page 509
Related tasks
“Setting preferences for the Text Form editor palette entries” on page 512
“Setting bidirectional text preferences for the Text Form editor”

Setting bidirectional text preferences for the Text Form editor


The EGL Text Form editor supports languages such as Arabic and Hebrew in
which the text is written right to left but numbers and Latin alphabetic strings
within the text are presented left to right. For more information, see “Working with
bidirectional data” on page 245. To change the preferences for the Text Form
editor’s support of bidirectional languages, follow these steps:
1. From the menu bar, click Window → Preferences. The Preferences window
opens.
2. In the left pane of the Preferences window, expand EGL and click EGL bidi
preferences.
3. In the right pane of the Preferences window, select the preferences for the Text
Form editor’s support of bidirectional languages:
v To enable the use of bidirectional language options in the Text Form editor,
select the Bi-directional options enabled check box. After this check box is
selected, all of the other options are available.
v To display and edit the bidirectional text fields in visual mode (the way they
will be displayed), select Enable visual data ordering.
v For languages that read from right to left, select Enable right-to-left
orientation.
v To place a button on the Text Form editor that enables you to change the
bidirectional settings for a formGroup, select Enable bidirectional settings
button. With this button, you can change the bidirectional settings for an
individual formGroup to be different from the settings in the Preferences
window.
v To default to visual display ordering in the Text Form editor (instead of
logical ordering), select Enable visual data ordering by default.
v To use right-to-left map coordinates for the Text Form editor, select Endable
right-to-left orientation by default. When a form group is set to use
right-to-left map coordinates, the top right corner is defined as the location
(1,1). With a left-to-right orientation, the location (1,1) is the top left corner.

Building EGL Text User Interface applications 511


The only reason to use right-to-left orientation in the form editor is to make
the design of a right-to-left form easier.
v To reverse directional punctuation characters like < and (, select Enable
symmetric swapping by default.
v To switch numerals from Hindi to Arabic, or Arabic to Hindi, select Enable
numeric swapping by default.
You can restore the EGL Text Form editor preferences window to its default
settings by clicking Restore Defaults.

BIDI support for Text UI and the Text UI Debugger in Java environments is
available on Windows-based systems only, and is not available on Linux. BIDI
support is available in all COBOL environments.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
“Filtering the editor” on page 509
“Working with bidirectional data” on page 245
Related tasks
“Setting preferences for the Text Form editor palette entries”

Setting preferences for the Text Form editor palette entries


The preferences for the EGL Text Form editor palette control the default color,
intensity, and highlighting for the types of constant and variable fields in the
palette. To change these preferences, follow these steps:
1. From the menu bar, click Window → Preferences. The Preferences window
opens.
2. In the left pane of the Preferences window, expand EGL → EGL Text Form
editor and click EGL Palette Entries.
3. In the right pane of the Preferences window, for each type of constant and
variable field in the Palette Entries list, select the following options:
v From the Color list, click a default color for that type of field.
v From the Intensity list, click a default intensity for that type of field.
v From the Highlight radio buttons, click a default highlighting style for that
type of field.
v From the Protect radio buttons, choose whether the field is protected from
user update by default.

Note: You can restore all of the palette entries to their default settings by
clicking Restore Defaults.
4. When you are finished setting the preferences for the palette entries, click OK
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
Related tasks
“Setting preferences for the Text Form editor” on page 510
“Creating a constant field” on page 502
“Creating a variable field” on page 503
Related reference
Form field properties

512 EGL Programmer’s Guide


Building EGL Console User Interface applications
Console User Interface, or Console UI, is a style of user interface similar to that
used on a UNIX-based program that interacts with a character-based terminal.

As the term character-based suggests, a console user interface shows only text on the
screen, no graphics or buttons, and it responds only to the keyboard, not the
mouse. However, with EGL, you to enhance your Console UI programs with
mouse functionality and rich client widgets by running your applications in rich
client platform (RCP) mode. See “Console UI modes” on page 529.
Related concepts
“Elements of a Console UI application”
A Console UI application can use several different types of EGL parts to supply
data and several different types of EGL variables to create the interface.
“Console UI modes” on page 529
EGL supports three modes in which you can run Console UI applications:
Swing, Curses, and rich client platform (RCP). The three modes have different
abilities, but in general a Console UI application behaves the same way in each
mode.
Related tasks
“Creating a Console User Interface” on page 516
Console UI relies on the openUI statement to define which forms and fields are
shown on the interface, which variables those forms and fields are bound to,
and which actions happen when the user performs tasks in the interface.
“Adding rich client widgets to a Console UI program” on page 519
When running in rich client platform (RCP) mode, you can use additional
Console UI components called widgets to add additional functionality.
“Running Console UI applications” on page 528
The process for running a Console UI application differs slightly depending on
the mode you are running in.
Related reference
Console UI parts
openUI

Elements of a Console UI application


A Console UI application can use several different types of EGL parts to supply
data and several different types of EGL variables to create the interface.

Like many types of applications with user interfaces, EGL Console UI applications
separate the interface from the logic used to create that interface. An ordinary EGL
program provides the logic for the application, while several different types of
parts can represent the interface itself.

Console UI forms and fields

A ConsoleForm part is a record of fields to be shown on the user interface. The


fields in this type of record do not store data or have a data type such as INT like
the fields in other types of records. Instead, the fields in a ConsoleForm define the

© Copyright IBM Corp. 1996, 2008 513


location and label of the fields that are shown on the screen. As a group, these
fields are sometimes referred to as a form. The Console UI program links the fields
on the screen with other EGL variables.

A field in a console UI record can be as simple as a name, a length in characters,


and a position on the screen. For example, here is a simple Console UI record that
defines a form:
Record CustomerConsoleRecord type consoleForm
{formSize = [10,40],name = "Customer Record"}
* consoleField {position = [1,4],
value = "Welcome to my console."};
ID consoleField {fieldLen = 5, position = [3,4],
name="customer_id"};
Fname consoleField {fieldLen = 20, position = [4,4],
name="first_name"};
Lname consoleField {fieldLen = 20, position = [5,4],
name="last_name"};
PhoneNum consoleField {fieldLen = 20, position = [6,4],
name="phone"};
end

Of the five fields in this form, one is a constant string of text; it cannot change at
run time. This field is named with an asterisk (*) and serves as header or
explanatory text, in this case ″Welcome to my console.″ The other fields are
variable; a Console UI program can use them to display data or accept input.

Menu and MenuItem parts

In Console UI, a menu is a set of options from which the user is expected to
choose one. When showing a menu on the interface, you define a menu part and
then define the options as an array of menuItem parts in the menuItems menu
property. For example, the following menu defines three options from which the
user can choose:
new Menu {labelText = "Choose an option: ",
menuItems = [
new MenuItem{name = "One", labelText = "Option One"},
new MenuItem{name = "Two", labelText = "Option Two"},
new MenuItem{name = "Three", labelText = "Option Three"}
]}

See “Creating a Console User Interface” on page 516 for an example of how to
respond when the user selects one of the options.

ArrayDictionary part

An ArrayDictionary is a type of EGL part that is often used to represent data in


Console UI. Unlike an array of records, in which you define one record part that
represents a row and then create an array of those rows, in an ArrayDictionary,
you define arrays of consoleFields that represent the columns. Defining data by the
columns can be useful in Console UI because ArrayDictionaries scroll automatically
in the limited space on a Console UI window.

A detailed example of an ArrayDictionary in Console UI is available at Using an


array dictionary in Console UI.

A detailed example of an ArrayDictionary in Console UI is available at ″Using an


array dictionary in Console UI″ in the EGL Language Reference.

514 EGL Programmer’s Guide


Console UI program

The Console UI program is an ordinary EGL program that creates and controls the
interface. In general, it creates a Window variable, uses functions in the EGL
library ConsoleLib to display that window, and then populates that window with
parts that represent the interface, such as ConsoleForm parts. Here is a simple
example of a Console UI program that uses the sample ConsoleForm part
described above:
program CreateAConsole type BasicProgram

function main()

// Step 1: Create a variable for the form.


myConsoleUIRecord CustomerConsoleRecord;
// Step 2: Create a window, but don't open it yet.
myWindow window {name="My Window", position=[1,1]};
// Step 3: Create variables for the form fields.
customer_id int;
first_name, last_name, phone char(30);

// Step 4: Open the window and open the form inside the window.
consoleLib.openWindowWithForm(myWindow,myConsoleUIRecord);
// Step 5: Link the variables to the fields in the form.
openUI myConsoleUIRecord
bind customer_id, first_name, last_name, phone
end

end

end

For more information on using Console UI programs, see “Creating a Console User
Interface” on page 516.

The EGL Plug-in project

With EGL, you can run your Console UI projects in a variety of modes. If you
want to run your Console UI application in rich client application (RCP) mode,
you need to convert your project to an EGL plug-in project.

For more information about the modes you can run your Console UI application
in, see “Console UI modes” on page 529. For more information on EGL plug-in
projects, see “Creating an EGL plug-in project” on page 74.
Related tasks
“Creating a Console User Interface” on page 516
Console UI relies on the openUI statement to define which forms and fields are
shown on the interface, which variables those forms and fields are bound to,
and which actions happen when the user performs tasks in the interface.
“Adding rich client widgets to a Console UI program” on page 519
When running in rich client platform (RCP) mode, you can use additional
Console UI components called widgets to add additional functionality.
“Running Console UI applications” on page 528
The process for running a Console UI application differs slightly depending on
the mode you are running in.
Related reference
Menu
Using an array dictionary in Console UI

Building EGL Console User Interface applications 515


ConsoleForm
Console UI parts
openUI

Creating a Console User Interface


Console UI relies on the openUI statement to define which forms and fields are
shown on the interface, which variables those forms and fields are bound to, and
which actions happen when the user performs tasks in the interface.

Opening and populating a window

The simplest way to create a Console UI is to create a window variable that


represents a user interface window and use a function such as
consoleLib.displayForm() to open the form in the window.
program basicConsole type BasicProgram

function main()
myWindow Window {name = "My Window",
position = [1,1]};
myConsoleRec CustomerConsoleRecord{name = "myForm"};

ConsoleLib.openWindow(myWindow);
ConsoleLib.displayForm(myConsoleRec);

end

end

Record CustomerConsoleRecord type consoleForm


{formSize = [10,40],name = "Customer Record"}
* consoleField {position = [1,4],
value = "Welcome to my console."};
ID consoleField {fieldLen = 5, position = [3,4],
name="customer_id"};
Fname consoleField {fieldLen = 20, position = [4,4],
name="first_name"};
Lname consoleField {fieldLen = 20, position = [5,4],
name="last_name"};
PhoneNum consoleField {fieldLen = 20, position = [6,4],
name="phone"};
end

However, this interface is not very useful because it does not enable the user to
interact with the form or window at all. Because this form does not enable any
interaction, the window closes as soon as it opens. You need to bind EGL variables
to the fields with the openUI statement to make the fields on the interface
meaningful and keep the window open while the user works with the interface.

Binding data to the fields in the window

Like many other types of applications with user interfaces, Console UI applications
separate the interface from the data being managed by the interface. When you
create a Console UI in EGL, you create the interface with parts like consoleForms
and then use the openUI statement to connect, or bind, those parts to variables in
your program. Then, when the person using the interface changes a value in the
consoleForm, the value of the variable changes to match. Conversely, when your
code changes the value of the variable, the value in the form changes to match.

516 EGL Programmer’s Guide


The following example expands on the previous example to bind four variables to
the four editable fields in the consoleForm:
program basicConsole type BasicProgram

function main()
myWindow Window {name = "My Window", position = [1,1]};
myConsoleRec CustomerConsoleRecord{name = "myForm"};

ConsoleLib.openWindow(myWindow);
ConsoleLib.displayForm(myConsoleRec);

customer_id int;
first_name, last_name, phone char(30);

openUI myConsoleRec
bind customer_id, first_name, last_name, phone
end

end

end

Record CustomerConsoleRecord type consoleForm


{formSize = [10,40],name = "Customer Record"}
* consoleField {position = [1,4],
value = "Welcome to my console."};
ID consoleField {fieldLen = 5, position = [3,4],
name="customer_id"};
Fname consoleField {fieldLen = 20, position = [4,4],
name="first_name"};
Lname consoleField {fieldLen = 20, position = [5,4],
name="last_name"};
PhoneNum consoleField {fieldLen = 20, position = [6,4],
name="phone"};
end

Now when you run this program, the window stays open so the user can tab
through the fields and type values. The line of code that begins openUI
myConsoleRec bind customer_id... specifies that the fields in the myConsoleRec are
bound to the variables listed in the bind clause.

Responding to events in the window

For your Console UI to react to actions that the user performs in the form, you
must define event handlers that tell EGL what to do in response to the action. An
event handler contains EGL statements like a function, but it begins with a
description of an event, such as a key being pressed or a value being typed in a
field. When the user presses a key or types a value in a field, the event handler
that is associated with that action is called.

The following example adds an event handler to the previous example. This event
handler is called when the user types a value in the customer_id field and moves
the cursor out of the field:
program basicConsole type BasicProgram

function main()
myWindow Window {name = "My Window", position = [1,1]};
myConsoleRec CustomerConsoleRecord{name = "myForm"};

ConsoleLib.openWindow(myWindow);
ConsoleLib.displayForm(myConsoleRec);

Building EGL Console User Interface applications 517


customer_id int;
first_name, last_name, phone char(30);

openUI myConsoleRec
bind customer_id, first_name, last_name, phone
onEvent(AFTER_FIELD:"customer_id")
if (customer_id == 3)
first_name = "John";
end
end

end

end

Record CustomerConsoleRecord type consoleForm


{formSize = [10,40],name = "Customer Record"}
* consoleField {position = [1,4],
value = "Welcome to my console."};
ID consoleField {fieldLen = 5, position = [3,4],
name="customer_id"};
Fname consoleField {fieldLen = 20, position = [4,4],
name="first_name"};
Lname consoleField {fieldLen = 20, position = [5,4],
name="last_name"};
PhoneNum consoleField {fieldLen = 20, position = [6,4],
name="phone"};
end

To respond when a user chooses an option in a menu, use the MENU_ACTION


event handler:
program menuTest type BasicProgram

function main()
openUI
new Menu {labelText = "Choose an option",
menuItems = [
new MenuItem{name = "One",labelText = "Option One"},
new MenuItem{name = "Two",labelText = "Option Two"},
new MenuItem{name = "Exit",labelText = "Exit"}
]}

onEvent(MENU_ACTION:("Exit"))
exit openUI;
onEvent(MENU_ACTION:("One"))
consolelib.displayAtLine("You chose option One", 5);
onEvent(MENU_ACTION:("Two"))
consolelib.displayAtLine("You chose option Two", 5);
end

end

end

In this example, the window provides a feedback message when the user selects
one of the first two options and closes when the user selects the ″Exit″ menu
option.

For other kinds of event handlers, see openUI.


Related tasks

518 EGL Programmer’s Guide


“Adding rich client widgets to a Console UI program”
When running in rich client platform (RCP) mode, you can use additional
Console UI components called widgets to add additional functionality.
“Running Console UI applications” on page 528
The process for running a Console UI application differs slightly depending on
the mode you are running in.
Related reference
openUI
Console UI parts

Adding rich client widgets to a Console UI program


When running in rich client platform (RCP) mode, you can use additional Console
UI components called widgets to add additional functionality.

Rich client widgets enable a Console UI interface to behave less like a


character-based interface and more like a graphical user interface. EGL supports
the following rich client widgets:
v buttons
v check boxes
v single-selection widgets, such as radio button groups, list boxes, or combo boxes
(also called drop-down boxes)

In general, using a rich client widget in your Console UI program involves these
steps:
1. Create the widget as a field in a console form and specify the properties for the
field.
2. In the Console UI program, create a variable to represent the state of the
widget:
v For check boxes, create a BOOLEAN variable.
v For single-selection widgets, create an INT variable.
v For buttons, no variable is needed.
3. With the bind clause of the openUI statement, bind the variable to the widget.
This step is not required for button widgets because the button widgets do not
need a variable.
4. Create an event handler for the widget:
v For check boxes, use the ConsoleCheckbox.STATE_CHANGED event.
v For combo boxes, use the ConsoleCombo.SELECTION_CHANGED event.
v For radio button groups, use the
ConsoleRadiogroup.SELECTION_CHANGED event.
v For list boxes, use the ConsoleList.SELECTION_CHANGED event.
v For buttons, use the ConsoleButton.PUSHED event.

See the following topics:


v “Adding a button widget” on page 520
v “Adding a check box widget” on page 522
v “Adding a single-selection widget” on page 524

These widgets are supported only when running in RCP mode. See “Console UI
modes” on page 529.

Building EGL Console User Interface applications 519


Related concepts
“Elements of a Console UI application” on page 513
A Console UI application can use several different types of EGL parts to supply
data and several different types of EGL variables to create the interface.
“Console UI modes” on page 529
EGL supports three modes in which you can run Console UI applications:
Swing, Curses, and rich client platform (RCP). The three modes have different
abilities, but in general a Console UI application behaves the same way in each
mode.
Related tasks
“Creating a Console User Interface” on page 516
Console UI relies on the openUI statement to define which forms and fields are
shown on the interface, which variables those forms and fields are bound to,
and which actions happen when the user performs tasks in the interface.
“Running Console UI applications” on page 528
The process for running a Console UI application differs slightly depending on
the mode you are running in.
“Adding a single-selection widget” on page 524
The combo box, radio button group, and list box are similar because they both
require the user to select a single option from a group of options.
“Adding a check box widget” on page 522
Unlike the button widget, the check box widget has a state; it is either checked
or not checked. Therefore, you must bind a boolean variable to the check box,
just like you would bind a text variable to a text field in a console form. When
the user selects the check box, the variable is set to TRUE, and when the user
clears the check box, the variable is set to FALSE.
“Adding a button widget”
The button widget is the simplest rich client widget because it does not need to
maintain a state like the others. You only need to create the button and specify
an event handler to run when the button is clicked.

Adding a button widget


The button widget is the simplest rich client widget because it does not need to
maintain a state like the others. You only need to create the button and specify an
event handler to run when the button is clicked.
1. In a console form, create the button by using the consoleButton predefined
part. This part represents the button widget.
Record buttonForm type ConsoleForm {formSize=[12,40]}
myButton consoleButton
{name = "simpleButton",
text = "Click here",
bounds=[4,4,1,15]};
end
2. At minimum, specify the following properties for the button:
name A mnemonic that you will use later to link the button to an event
handler
text The label for the button
bounds
An array of four integers that represent the row, column, height, and
width of the button, respectively
3. Within an openUI statement, specify an event handler for the button’s
PUSHED event:

520 EGL Programmer’s Guide


onEvent(ConsoleButton.PUSHED : "simpleButton")
SysLib.writeStderr("You pushed the button.");

A complete example of a Console UI program that uses a button in this way


follows.

In the file programs/simpleButton.egl:


package programs;

import forms.buttonForm

program simpleButton type BasicProgram

textValue string;
counter int=0;
function main()
myWindow WINDOW {name="myWindow",
position = [1,1]};
openWindow(myWindow);

myForm buttonForm {};


displayForm(myForm);

keepGoing boolean = true;


while (keepGoing == true)
openUI { bindingByName=no }
myForm
bind textValue
OnEvent(ConsoleButton.PUSHED : "simpleButton")
counter+=1;
textValue = "You have clicked the button "
+counter+" times.";
SysLib.writeStderr(textValue);
onEvent(ConsoleButton.PUSHED : "exitButton")
keepGoing = false;
end
end
end

end

In the file forms/buttonForm.egl:


package forms;

record buttonForm type ConsoleForm { formsize=[12,40] }


introText consoleField
{name="introText",
position = [1,1],
fieldLen = 20};
myButton consoleButton
{name = "simpleButton",
text = "Click here",
bounds=[4,4,1,15]};
exitButton consoleButton
{name = "exitButton",
text = "Click to exit",
bounds=[6,4,1,15]};
end
Related concepts
“Elements of a Console UI application” on page 513
A Console UI application can use several different types of EGL parts to supply
data and several different types of EGL variables to create the interface.

Building EGL Console User Interface applications 521


“Console UI modes” on page 529
EGL supports three modes in which you can run Console UI applications:
Swing, Curses, and rich client platform (RCP). The three modes have different
abilities, but in general a Console UI application behaves the same way in each
mode.
Related tasks
“Creating a Console User Interface” on page 516
Console UI relies on the openUI statement to define which forms and fields are
shown on the interface, which variables those forms and fields are bound to,
and which actions happen when the user performs tasks in the interface.
“Running Console UI applications” on page 528
The process for running a Console UI application differs slightly depending on
the mode you are running in.
“Adding rich client widgets to a Console UI program” on page 519
When running in rich client platform (RCP) mode, you can use additional
Console UI components called widgets to add additional functionality.
“Adding a single-selection widget” on page 524
The combo box, radio button group, and list box are similar because they both
require the user to select a single option from a group of options.
“Adding a check box widget”
Unlike the button widget, the check box widget has a state; it is either checked
or not checked. Therefore, you must bind a boolean variable to the check box,
just like you would bind a text variable to a text field in a console form. When
the user selects the check box, the variable is set to TRUE, and when the user
clears the check box, the variable is set to FALSE.
Related reference
Console UI parts
openUI

Adding a check box widget


Unlike the button widget, the check box widget has a state; it is either checked or
not checked. Therefore, you must bind a boolean variable to the check box, just
like you would bind a text variable to a text field in a console form. When the user
selects the check box, the variable is set to TRUE, and when the user clears the
check box, the variable is set to FALSE.
1. In a console form, create the check box by using the consoleCheckbox
predefined part.
Record checkForm type ConsoleForm {formSize=[12,40]}
myCheck consoleCheckbox
{name = "simpleCheck",
text = "Click here",
bounds=[4,4,1,15]};
end
2. At minimum, specify the following properties for the check box:
name A mnemonic that you will use later to link the check box to an event
handler
text The label for the check box
bounds
An array of four integers that represent the row, column, height, and
width of the check box, respectively
3. Create a boolean variable to represent the state of the check box:

522 EGL Programmer’s Guide


checkState boolean = false;
4. With an openUI statement, open the form and bind the variable to the check
box:
myForm checkForm {};
openUI myForm
bind checkState
//event handlers go here
end
5. Within the openUI statement, specify an event handler for the check box’s
STATE_CHANGED event:
onEvent(ConsoleCheckbox.STATE_CHANGED : "simpleCheck")
if (checkState == true)
SysLib.writeStderr("Checked");
else
SysLib.writeStderr("Cleared");
end

A complete example of a Console UI program that uses a check box in this way
follows:

In the file programs/simpleCheckbox.egl:


package programs;

import forms.checkForm;

program simpleCheckbox type BasicProgram

function main()
myWindow WINDOW {name="myWindow", position = [1,1]};
openWindow(myWindow);

myForm checkForm {};


displayForm(myForm);

textValue string = "Text.";


keepGoing boolean = true;
myCheckVar boolean = false;
while (keepGoing == true)
openUI myForm
bind textValue, myCheckVar
onEvent(ConsoleButton.PUSHED : "exitButton")
keepGoing = false;
onEvent(ConsoleCheckbox.STATE_CHANGED : "simpleCheck")
if (myCheckVar == true)
textValue = "Checked";
else
textValue = "Cleared";
end
end
end
end

end

In the file forms/checkForm.egl:


package forms;

record checkForm type ConsoleForm { formsize=[12,40] }


introText consoleField
{name="introText",
position = [1,1],
fieldLen = 20};
myCheck consoleCheckbox

Building EGL Console User Interface applications 523


{name="simpleCheck",
text="Checkbox",
bounds=[3,5,1,15]};
exitButton consoleButton
{name = "exitButton",
text = "Click to exit",
bounds=[6,4,1,15]};
end
Related concepts
“Elements of a Console UI application” on page 513
A Console UI application can use several different types of EGL parts to supply
data and several different types of EGL variables to create the interface.
“Console UI modes” on page 529
EGL supports three modes in which you can run Console UI applications:
Swing, Curses, and rich client platform (RCP). The three modes have different
abilities, but in general a Console UI application behaves the same way in each
mode.
Related tasks
“Creating a Console User Interface” on page 516
Console UI relies on the openUI statement to define which forms and fields are
shown on the interface, which variables those forms and fields are bound to,
and which actions happen when the user performs tasks in the interface.
“Running Console UI applications” on page 528
The process for running a Console UI application differs slightly depending on
the mode you are running in.
“Adding rich client widgets to a Console UI program” on page 519
When running in rich client platform (RCP) mode, you can use additional
Console UI components called widgets to add additional functionality.
“Adding a single-selection widget”
The combo box, radio button group, and list box are similar because they both
require the user to select a single option from a group of options.
“Adding a button widget” on page 520
The button widget is the simplest rich client widget because it does not need to
maintain a state like the others. You only need to create the button and specify
an event handler to run when the button is clicked.
Related reference
Console UI parts
openUI

Adding a single-selection widget


The combo box, radio button group, and list box are similar because they both
require the user to select a single option from a group of options.

Like the check box widget, the single-selection widgets must be bound to a
variable that represents their states. However, instead of a boolean variable, the
single-selection widgets must be bound to an INT variable to represent the index
of the currently selected option.
1. In a console form, create the widget using the predefined parts:
record singleSelectForm type ConsoleForm
{ formsize=[12,40] }
myRadio consoleRadioGroup
{name = "radio", bounds = [1,2,4,17]};
myCombo consoleCombo

524 EGL Programmer’s Guide


{name = "combo", bounds = [7,2,1,15]};
myList ConsoleList
{name ="list", bounds = [9,2,2,18]};
end
2. At minimum, specify the following fields for each widget:
name A mnemonic that you will use later to link the widget to an event
handler
bounds
An array of four integers that represent the row, column, height, and
width of the widget, respectively
3. In a program, create an integer variable to represent the state of the widget:
radioValue, comboValue, listValue int = 2;
4. Between creating the form variable and displaying the form in a window,
define the options in the widget with an array of variables or literals:
myWindow WINDOW {name="myWindow", position=[1,1]};
openWindow(myWindow);
myForm singleSelectForm{};

myForm.myCombo.items =
["Option One", "Option Two", "Option Three"];
myForm.myRadio.items =
["Option One", "Option Two", "Option Three"];
myForm.myList.items =
["one","two","three","four","five","six"];

displayForm(myForm);
5. With an openUI statement, open the form and bind the variables to the
widgets:
openUI myForm
bind radioValue, comboValue, listValue
//event handlers go here
end
6. Within the openUI statement, specify an event handler for the widget’s
SELECTION_CHANGED event:
onEvent (ConsoleRadioGroup.SELECTION_CHANGED : "radio")
SysLib.writeStdout("Radio selected: "::radioValue);
onEvent (ConsoleCombo.SELECTION_CHANGED : "combo")
SysLib.writeStdout("Combo selected: "::comboValue);
onEvent(ConsoleList.SELECTION_CHANGED : "list")
SysLib.writeStdout("List selected: "::listValue);

A complete example of a Console UI program that uses a combo box widget and
radio button group widget in this way follows:

In the file programs/singleSelectTest.egl:


package programs;

import forms.singleSelectForm;

program singleSelectTest type BasicProgram {}

radioValue, comboValue, listValue int = 2;

function main()
myWindow WINDOW {name="myWindow", position=[1,1]};
openWindow(myWindow);
myForm singleSelectForm{};

myForm.myCombo.items =

Building EGL Console User Interface applications 525


["Option One", "Option Two", "Option Three"];
myForm.myRadio.items =
["Option One", "Option Two", "Option Three"];
myForm.myList.items =
["one","two","three","four","five","six"];

displayForm(myForm);

openUI myForm
bind radioValue, comboValue, listValue
onEvent (ConsoleRadioGroup.SELECTION_CHANGED : "radio")
SysLib.writeStdout("Radio selected: "::radioValue);
onEvent (ConsoleCombo.SELECTION_CHANGED : "combo")
SysLib.writeStdout("Combo selected: "::comboValue);
onEvent(ConsoleList.SELECTION_CHANGED : "list")
SysLib.writeStdout("List selected: "::listValue);
end

end

end

In the file forms/singleSelectForm.egl:


package forms;

record singleSelectForm type ConsoleForm


{ formsize=[12,40] }
myRadio consoleRadioGroup
{name = "radio", bounds = [1,2,4,17]};
myCombo consoleCombo
{name = "combo", bounds = [7,2,1,15]};
myList ConsoleList
{name ="list", bounds = [9,2,2,18]};
end

When you run the EGL program in RCP mode, the user interface looks like this:

Each time you change the selection in one of the widgets, the appropriate event
handler runs and, in this case, prints a message to the Console view:

526 EGL Programmer’s Guide


The list box can also behave as a multiple-selection widget, allowing the user to
select more than one item from the list. To allow users to select more than one item
from the list, set the widget’s multipleSelect property to true:
myForm.list1.multipleSelect = TRUE;

When multipleSelect is set to false (as is the default) the value of the variable
bound to the widget contains the index of the selected item. If the first item is
selected, the variable contains the number 1; if the fifth item is selected, the
variable contains the number 5. When multipleSelect is set to true, the variable
contains a binary representation of the selected items. Each item in the list is
assigned a multiple of two according to its position: the first item is 1, the second
is 2, the third is 4, the fourth is 8, the fifth is 16, the sixth is 32, and so on. The
value of the variable is the sum of the values of all the selected items. For example,
if only the first item is selected, the variable contains 1. If the first and second
items are selected, the variable contains 3, which is the sum of the values for the
two selected items. If the second, fifth, and sixth items are selected, the variable
contains 50, or 2+16+32.
Related concepts
“Elements of a Console UI application” on page 513
A Console UI application can use several different types of EGL parts to supply
data and several different types of EGL variables to create the interface.
“Console UI modes” on page 529
EGL supports three modes in which you can run Console UI applications:
Swing, Curses, and rich client platform (RCP). The three modes have different
abilities, but in general a Console UI application behaves the same way in each
mode.
Related tasks
“Creating a Console User Interface” on page 516
Console UI relies on the openUI statement to define which forms and fields are
shown on the interface, which variables those forms and fields are bound to,
and which actions happen when the user performs tasks in the interface.
“Running Console UI applications” on page 528
The process for running a Console UI application differs slightly depending on
the mode you are running in.
“Adding rich client widgets to a Console UI program” on page 519
When running in rich client platform (RCP) mode, you can use additional
Console UI components called widgets to add additional functionality.
“Adding a check box widget” on page 522
Unlike the button widget, the check box widget has a state; it is either checked
or not checked. Therefore, you must bind a boolean variable to the check box,
just like you would bind a text variable to a text field in a console form. When
the user selects the check box, the variable is set to TRUE, and when the user
clears the check box, the variable is set to FALSE.

Building EGL Console User Interface applications 527


“Adding a button widget” on page 520
The button widget is the simplest rich client widget because it does not need to
maintain a state like the others. You only need to create the button and specify
an event handler to run when the button is clicked.
Related reference
Console UI parts
openUI

Running Console UI applications


The process for running a Console UI application differs slightly depending on the
mode you are running in.

For information on the different modes available for Console UI applications, see
“Console UI modes” on page 529.

Running in Swing or Curses mode

Running in Swing or Curses mode is no different from running any EGL


application generated to Java:
1. Save all changed files and generate the project.
2. In your EGL project, expand the Java Resources folder and find the Java
program to which your program part was generated. The Java file has the same
name as your program part, but with a .java extension.
3. Right-click the program file and then click Run As → Java Application.

Running in RCP mode

To run a Console UI program in rich client platform (RCP) mode, the Console UI
program must be in an EGL plug-in project. See “Creating an EGL plug-in project”
on page 74.

Running a Console UI program in RCP mode is different from running other types
of EGL programs because you run the application from the EGL file, not the Java
file:
1. Save all changed files and generate the project.
2. In your EGL project, right-click the file that contains the Console UI program
part and then click Run As RCP. The program opens in a new window. In this
window, you can use the enhanced GUI features of the workbench, including
using the mouse to select fields, and copying and pasting text between fields.
Related concepts
“Building EGL Console User Interface applications” on page 513
Console User Interface, or Console UI, is a style of user interface similar to that
used on a UNIX-based program that interacts with a character-based terminal.
“Console UI modes” on page 529
EGL supports three modes in which you can run Console UI applications:
Swing, Curses, and rich client platform (RCP). The three modes have different
abilities, but in general a Console UI application behaves the same way in each
mode.

528 EGL Programmer’s Guide


Console UI modes
EGL supports three modes in which you can run Console UI applications: Swing,
Curses, and rich client platform (RCP). The three modes have different abilities,
but in general a Console UI application behaves the same way in each mode.

Swing mode

Swing mode is the default mode for Console UI applications. If you write a
Console UI program, generate it, and run the generated Java source without
making any other changes, the resulting program runs in Swing mode. A Console
UI application running in Swing mode uses Java Swing libraries to simulate a
UNIX interface like that of Curses mode.

Curses mode

Curses mode is similar to Swing mode, but Curses mode is intended for users who
use telnet to access a UNIX system or who use a terminal device.

To use Curses mode you must add the EGL Curses library to your project and then
run the application in the same way as you would run it in Swing mode. After you
have added the EGL Curses library to your project, Curses mode becomes the
default mode for running Console UI applications. If you run the generated Java
output from a Console UI program, that program runs in Curses mode.

For information on how to install the EGL Curses library, see Installing the EGL
runtime code for Java.

RCP mode

Rich client platform (RCP) mode is similar to Swing mode, except that in RCP
mode, EGL applications use SWT libraries instead of Swing libraries. The resulting
application has graphical user interface fields (like fields in a Web page form or in
a wizard in the Eclipse workbench) in place of the character-based fields. Also,
RCP applications have mouse functionality and enhanced keyboard functionality,
enabling you to copy and paste text between fields. Finally, RCP mode supports
enhanced UI components, or widgets, that the other modes do not, such as
drop-down boxes, check boxes, and clickable buttons.

The other modes do not support these widgets, which means that you can run an
application designed for another mode in RCP mode, but you can generally not
run an application designed for RCP mode in another mode.

A Console UI program behaves similarly in RCP mode as in Swing or Curses


mode. The main difference is that you can use the mouse and enhanced keyboard
features of the workbench in a RCP program. However, because these features are
now enabled, the user might be able to make the program behave differently in
RCP mode:
v Because the mouse is enabled in RCP mode, the user can skip between fields in
any order, where in the other modes the user must move between fields in a
specific order.
v Because copying and pasting text is enabled in RCP mode, keyboard
combinations like Ctrl+X might behave differently in RCP mode.

Formatting masks are not supported in RCP mode.

Building EGL Console User Interface applications 529


Related concepts
“Building EGL Console User Interface applications” on page 513
Console User Interface, or Console UI, is a style of user interface similar to that
used on a UNIX-based program that interacts with a character-based terminal.
Related tasks
“Running Console UI applications” on page 528
The process for running a Console UI application differs slightly depending on
the mode you are running in.

530 EGL Programmer’s Guide


Creating reports with EGL
EGL offers different ways to create reports, using external engines to generate the
report contents.

You can create a report by using the following capabilities:


v The JasperReports engine creates reports in formats including PDF, HTML,
comma-separated, and plain text.
v The Business Intelligence and Reporting Tools (BIRT) engine creates reports in
HTML or PDF format.
v The EGL text report engine creates plain text reports.

Each engine has its particular advantages and drawbacks, as detailed in the
following sections. One common drawback is that these reports run on Java only.
You must create custom report programs for COBOL.

JasperReports engine
The JasperReport engine allows the greatest complexity. You use a design file to
dictate the layout, which can be quite complex. You can nest as many subreports as
you want to any depth, passing information to the subreport from the report or
subreport that calls it. The addition of an EGL JasperReports handler means you
can create dynamic reports that respond to events that occur as the report is
generated, such as reaching maximum values on subtotals, or changing between
various commission structures. Output options include PDF, HTML, XML, plain
text, and comma separated values (CSV) for use with Excel.

With greater flexibility comes increased effort required in using the product.
Mastering the design file is difficult enough that third-party applications are
available to help you. These applications, including JasperReports, are third-party
products, not affiliated with IBM.

If all you need is a simple text report, JasperReports may be a more powerful tool
than you need, like using a jet plane for a short trip down the street.

BIRT engine
BIRT is an Eclipse-based reporting system that allows for sophisticated output in
PDF or HTML format, including graphics, tables, graphs, and charts.

You can design a report in the Report Design perspective of your Workbench and
then write EGL code that drives report creation. EGL support is available in JSF
handlers and in programs generated for Java.

EGL text report engine


The EGL text report engine draws on EGL parts such as the generic Handler,
Delegate, and ExternalType. It is particularly useful for the migration of reports
from I4GL. You can use the Handler part to respond to a limited list of specific
events during the output of report data. Your data source can be anything you can
read from in EGL. It should take far less time to create a simple report design with
this engine than with JasperReports or BIRT.

© Copyright IBM Corp. 1996, 2008 531


As the name implies, the only available output format for the EGL text report
engine is a plain text file (though you may also direct output to stdout).
Related concepts
“Creating reports with JasperReports”
EGL uses the JasperReports framework to create reports in several formats,
including PDF, HTML, comma-separated values, and plain text.
“Creating reports with BIRT” on page 551
Business Intelligence and Reporting Tools (BIRT) is an Eclipse-based reporting
system that allows for sophisticated output in PDF or HTML format, including
graphics, tables, graphs, and charts. EGL support for BIRT is available when
you code either JSF handlers or programs generated for Java.
“Creating EGL text reports” on page 556
EGL offers its own report engine (an external Java class) that produces a simple
text report. This engine is particularly useful for migrating reports from
Informix 4GL.

Creating reports with JasperReports


EGL uses the JasperReports framework to create reports in several formats,
including PDF, HTML, comma-separated values, and plain text.

To create and export a report using the JasperReports framework in EGL, follow
these general steps:
1. Create and compile a JasperReports report design file. See “Creating the
JasperReport design file” on page 534.
2. Write a report driver program. See “Writing code to drive a report of type
JasperReport” on page 538.
3. Optionally, create a report handler with additional functions that are called by
the report design file. See “Creating an EGL JasperReport handler” on page
541.
4. Generate the project and run the report driver program. See “Running a report
of type JasperReport” on page 545

EGL does not require that you perform these tasks in a particular order, but you
must be aware of dependencies between the files. For example, if your report
design file calls functions in the report handler, you must write and generate the
report handler first and then compile the report design file. EGL compiles the
report design file each time you save a change to the report design file, or you can
direct EGL to compile the report design file by clicking Project → Clean → Clean all
projects.

EGL does not automatically refresh exported reports. If you change the report
design or if the data used in the report changes, you must run the report driver
program again.
Related concepts
EGL reports
“Elements of an EGL JasperReport application” on page 533
The main elements of a JasperReport application in EGL are a program to run
the report and a report design file to control the layout of the report.
Additionally, a report handler can give you greater control over the data put
into the report.
Related tasks

532 EGL Programmer’s Guide


“Creating the JasperReport design file” on page 534
The JasperReport design file specifies the layout and appearance of the report.
Unless you import a working design file (with the extension .jasper), you will
need to create or modify one.
“Writing code to drive a report of type JasperReport” on page 538
A report-driver program is an ordinary EGL program that runs a report using a
.jasper file that is compiled from a report design file.
“Creating an EGL JasperReport handler” on page 541
“Running a report of type JasperReport” on page 545
Related Reference
EGL library reportLib
EGL JasperReport Handler

Elements of an EGL JasperReport application


The main elements of a JasperReport application in EGL are a program to run the
report and a report design file to control the layout of the report. Additionally, a
report handler can give you greater control over the data put into the report.

Report design file

The report design file is an XML file with a .jrxml extension that describes how the
report will look and where the data will be displayed. You can code the XML file
yourself or use a third-party tool. The workbench does not provide a graphical
way to create report design files.

When you have finished writing the report design file, EGL compiles it into a
.jasper file, which your report driver program uses to create the report. For more
information on the report design file and an example, see “Creating the
JasperReport design file” on page 534.

Report driver program

Generally, an EGL program does the work of populating the report with data and
exporting its output. The report driver program performs the following tasks:
v Creates a Report variable to represent the report
v Populates that report variable with a report design file and information about
where the completed report will go
v Creates a ReportData variable to represent the data in the report
v Connects to a data source, retrieves data for the report, and puts that data into
the ReportData variable
v Calls functions in the EGL library ReportLib to run and export the report
For an example of a report driver program, see “Writing code to drive a report of
type JasperReport” on page 538.

Report handler

The report handler is an EGL logic part that provides additional functions to be
executed when the report runs. You can define a function in the report handler and
then call that function from a specific place in the report design file. Also, the
report automatically calls functions in the report handler at certain points during

Creating reports with EGL 533


the report-creation process. For example, the report calls functions in the report
handler before the report runs, after it runs and at the beginning and end of each
page.

The report handler is optional. You can manipulate much of the data and the
appearance of the report from the report driver program and the report design file,
but you might want to use a report handler if you need to respond to events in the
report.
Related concepts
“Creating reports with EGL” on page 531
EGL offers different ways to create reports, using external engines to generate
the report contents.
Related tasks
“Creating an EGL JasperReport handler” on page 541
“Creating the JasperReport design file”
The JasperReport design file specifies the layout and appearance of the report.
Unless you import a working design file (with the extension .jasper), you will
need to create or modify one.
“Writing code to drive a report of type JasperReport” on page 538
A report-driver program is an ordinary EGL program that runs a report using a
.jasper file that is compiled from a report design file.
“Running a report of type JasperReport” on page 545
Related Reference
EGL JasperReport Handler

Creating the JasperReport design file


The JasperReport design file specifies the layout and appearance of the report.
Unless you import a working design file (with the extension .jasper), you will need
to create or modify one.

For more detailed information than you will find in this topic, see the following
Web site:

http://jasperforge.org

You can use a file with the .xml extension for your source, although this can slow
your compilation. JasperReports works best with the .jrxml extension.

To add a design document to a package, follow these steps:


1. Create a design document in one of the following ways:
v Use a third-party JasperReports design tool (like JasperAssistant or iReport).
Make sure the file you create has a .jrxml extension.
v Use a text editor to write JasperReports XML source information into a new
text file and save the file as a .jrxml file.
2. Place the XML design document in the same EGL package as your report
driver file and optional EGL report handler.
3. Customize the XML source file to use one of the following data sources:
v When you have a fairly simple, straightforward database query, create a
report of the type DataSource.databaseConnection. Include your SQL query
in the XML design file source. The EGL report driver passes your connection
information to JasperReports.

534 EGL Programmer’s Guide


v When you need to perform complex database operations, or need to build
your SQL statement dynamically, create a report of the type
DataSource.sqlStatement. The EGL report driver includes your SQL query
and passes the result set to JasperReports.
v When your data comes from somewhere other than a database, create a
report of the type DataSource.reportData. The EGL report driver passes
complete report data to JasperReports; no connection information is
necessary.
4. Compile the source file.

An example of a report design file follows:


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE jasperReport PUBLIC
"//JasperReports//DTD Report Design//EN"
"http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">

<jasperReport name="simpleReport">

<field name="CUSTOMER_ID" class="java.lang.String" />


<field name="FIRST_NAME" class="java.lang.String" />
<field name="LAST_NAME" class="java.lang.String" />
<field name="PHONE" class="java.lang.String" />

<pageHeader>

<band height="30">
<staticText>
<reportElement x="0" y="0" width="70" height="24" />
<text>
<![CDATA[Customer ID: ]]>
</text>
</staticText>
<staticText>
<reportElement x="140" y="0" width="70" height="24" />
<text>
<![CDATA[First name: ]]>
</text>
</staticText>
<staticText>
<reportElement x="280" y="0" width="70" height="24" />
<text>
<![CDATA[Last name: ]]>
</text>
</staticText>
<staticText>
<reportElement x="420" y="0" width="70" height="24" />
<text>
<![CDATA[Phone: ]]>
</text>
</staticText>
</band>

</pageHeader>

<detail>

<band height="30">
<textField>
<reportElement x="0" y="0" width="70" height="24" />
<textFieldExpression>
<![CDATA[$F{CUSTOMER_ID}]]>
</textFieldExpression>
</textField>
<textField>

Creating reports with EGL 535


<reportElement x="140" y="0" width="70" height="24" />
<textFieldExpression>
<![CDATA[$F{FIRST_NAME}]]>
</textFieldExpression>
</textField>
<textField>
<reportElement x="280" y="0" width="70" height="24" />
<textFieldExpression>
<![CDATA[$F{LAST_NAME}]]>
</textFieldExpression>
</textField>

<textField>
<reportElement x="420" y="0" width="70" height="24" />
<textFieldExpression>
<![CDATA[$F{PHONE}]]>
</textFieldExpression>
</textField>
</band>

</detail>

</jasperReport>

This example report design file prints four columns of information: an ID number,
a first name, a last name, and a phone number. The <pageHeader> section prints
column headers, and the <detail> section prints rows of data based on the data
provided by the report driver program.

The following sections offer specifics for the different types of XML source files.
This information covers very simple cases; for more complex examples see either
the JasperReports Web site mentioned earlier or the documentation for your design
tool (if you decide to use one).

EGL source files of the type DataSource.databaseConnection


Include connection information in your EGL source file and include your SQL
query in the XML design file source. Here is the syntax for a very simple case:
<queryString><![CDATA[SELECT * FROM Table_Name]]></queryString>
Table_Name
Name of a table from your database

Define the specific fields (tied to columns in the SQL result set) you want to use:
<field name="Field_Name" class="java.lang.class_type"></field>
Field_Name
A column name in the result set from the query in your design file. The field
names must conform to Java variable name conventions. You can use aliases
for column names within your SQL statement to handle duplicate names,
illegal characters (such as ″.″), or other conflicts.
Class_Type
A java.lang class, such as Integer or String, that identifies the type of data to
which Field_Name refers

Place the fields on the report with a TextFieldExpression tag:


<textFieldExpression class="java.lang.class_type">
<![CDATA[$F{Field_Name}]]>
</textFieldExpression>

536 EGL Programmer’s Guide


EGL source files of the type DataSource.sqlStatement
Place your SQL statement in the EGL report driver file. You can either specify your
connection explicitly in your report driver or use the default connection in your
build descriptor. In the XML design file, define the specific fields that you want to
print on the report. The field names refer to column names in your SQL
statement’s result set:
<field name="Field_Name" class="java.lang.class_type"></field>
Field_Name
A column name in the result set that was created by the query in your EGL
report driver. The field names must conform to Java variable name
conventions. You can alias the column names within your SQL statement if
necessary.
Class_Type
A java.lang class such as Integer or String, identifying the type of data to
which Field_Name refers

Place the fields on the report with a TextFieldExpression tag:


<textFieldExpression class="java.lang.class_type">
<![CDATA[$F{Field_Name}]]>
</textFieldExpression>

EGL source files of the type DataSource.reportData


In this instance, you do not use a database, so you do not need a connection or
SQL statement, either in your XML source or in the EGL report driver. Instead
define the specific fields that you want to use from the records that you create in
the EGL report driver:
<field name="Field_Name" class="java.lang.class_type"></field>
Field_Name
The name of a field exactly as you specify it in your EGL source file
Class_Type
A java.lang class such as Integer or String, identifying the type of data to
which Field_Name refers

Place the fields on the report with a TextFieldExpression tag:


<textFieldExpression class="java.lang.class_type">
<![CDATA[$F{Field_Name}]]>
</textFieldExpression>

Compiling the XML design file source


EGL automatically compiles any .jrxml file that it finds in the package directory in
the EGL source folder, provided that these conditions are true:
v The .jrxml file has changed
v The .jrxml file is free of errors
v The javac compiler is in your execution path

EGL places the compiled .jasper file in the Java Resources\package_name directory
that is parallel to EGLSource\package_name. When you successfully generate your
EGL report driver, the product places a linked copy of the .jasper file in the
parallel bin\package_name directory. You can manually create and copy the .jasper
file by selecting Project → Build All or Project → Clean.

For guidelines on creating an XML design document and a report handler


simultaneously, see “Creating reports with JasperReports” on page 532. For an

Creating reports with EGL 537


example that shows how an XML design document gets a report data record from
the report handler, see “Writing code to drive a report of type JasperReport.”
Related concepts
“Creating reports with EGL” on page 531
EGL offers different ways to create reports, using external engines to generate
the report contents.
“Creating reports with JasperReports” on page 532
EGL uses the JasperReports framework to create reports in several formats,
including PDF, HTML, comma-separated values, and plain text.
Related tasks
“Creating an EGL JasperReport handler” on page 541
“Writing code to drive a report of type JasperReport”
A report-driver program is an ordinary EGL program that runs a report using a
.jasper file that is compiled from a report design file.
Related reference
EGL reports
EGL library reportLib

Writing code to drive a report of type JasperReport


A report-driver program is an ordinary EGL program that runs a report using a
.jasper file that is compiled from a report design file.

The following example shows a report driver program that uses data from a
specified database connection:
program reportDriverProgram type BasicProgram

function main()
SQLLib.defineDatabaseAlias("customer",
"jdbc:derby:C:\\databases\\CustomerDatabase");
SQLLib.connect("customer", "admin", "admin");

myReport Report = new Report();


myReportData ReportData = new ReportData();
myReport.reportDesignFile =
"C:\\Workspace\\MyProject\\bin\\reportModel.jasper";
myReport.reportDestinationFile = "C:\\temp.jrprint";
myReport.reportExportFile = "C:\\MyReport.pdf";
myReportData.connectionName = "customer";
myReportData.sqlStatement =
"select * from EGL.CUSTOMER order by CUSTOMER_ID desc";
myReport.reportData = myReportData;

reportLib.fillReport(myReport, DataSource.sqlStatement);
reportLib.exportReport(myReport, ExportFormat.pdf);

end

end

Because the backslash character (\) is used in escape sequences, you must use a
double backslash in path names.

538 EGL Programmer’s Guide


The following table explains the code in the previous example:

Code Explanation
SQLLib.defineDatabaseAlias("customer", Connects to a database and defines an alias
"jdbc:derby:C:\\databases for the database using functions in the EGL
\\CustomerDatabase"); library SQLLib
SQLLib.connect("customer",
"admin", "admin");
myReport Report = new Report(); Creates a new report variable to represent
the report
myReportData ReportData = Creates a new report data variable to
new ReportData(); represent the data in the report
myReport.reportDesignFile = Sets the location of the .jasper file that is
location; compiled from the report design file
myReport.reportDestinationFile = Sets the location of a temporary file that is
location; used while processing the report
myReport.reportExportFile = Sets the location of the exported report
location;
myReportData.connectionName = Sets the database connection that the report
"customer"; uses, in terms of the database alias defined
earlier
myReportData.sqlStatement = Sets the database access statement that
SQL statement; provides the data for the report
myReport.reportData = myReportData; Associates the report variable with the
report data variable
reportLib.fillReport(myReport, Fills the report with data
DataSource.sqlStatement);
reportLib.exportReport(myReport, Runs and exports the report
ExportFormat.pdf);

Populating a report from a customized record

The following code snippet shows how you might fill a report using your own
internal record as the data source. First, define a record like the following example,
somewhere outside the program:
Record myRecord type BasicRecord
author String;
description String;
title String;
end

Next, write the function to fill and drive the report:


//Variable declarations
myReport Report = new Report();
myReportData ReportData = new ReportData();

recArray myRecord[];
recArrayElement myRecord;

//Function containing the report driving code


function makeReport()
//Initialize report file locations
myReport.reportDesignFile =
"c:\\workspace\\report_project\\" ::
"bin\\report_package\\myReport.jasper";
myReport.reportDestinationFile =

Creating reports with EGL 539


"c:\\temp\\myReport.jrprint";

//Get the report data


populateReportData();
myReport.reportData = myReportData;

//Fill the report with data


reportLib.fillReport(myReport, DataSource.reportData);

//Export the report in HTML format


myReport.reportExportFile = "c:\\temp\\myReport.html";
reportLib.exportReport(myReport, ExportFormat.html);
end

function populateReportData()
recArrayElement.author="Jane Austen";
recArrayElement.title="Northanger Abbey";
recArrayElement.description = "British Novel";
recArray.appendElement(recArrayElement);

recArrayElement.author = "Jane Austen";


recArrayElement.title="Emma";
recArrayElement.description = "British Novel";
recArray.appendElement(recArrayElement);

recArrayElement.author = "Charles Dickens";


recArrayElement.title="Our Mutual Friend";
recArrayElement.description = "British Novel";
recArray.appendElement(recArrayElement);

recArrayElement.author = "Gustave Flaubert";


recArrayElement.title="Madame Bovary";
recArrayElement.description = "French Novel";
recArray.appendElement(recArrayElement);

recArrayElement.author = "M. Lermontov";


recArrayElement.title="Hero of Our Time";
recArrayElement.description = "Russian Novel";
recArray.appendElement(recArrayElement);
end

Selecting an export format

JasperReports saves filled report data as an intermediate destination file (extension


.jrprint), from which it can create multiple export files. You can export filled
reports as PDF, HTML, XML, CSV (comma-separated values that spreadsheet
programs can read), and plain text output. To export the report, use the
reportLib.exportReport() function in the EGL report-driver program with the
report variable and a parameter that indicates the format of the report.

The reportLib.exportReport() function recognizes the following parameters:


v ExportFormat.html
v ExportFormat.pdf
v ExportFormat.text
v ExportFormat.xml
v ExportFormat.csv

For example, the following code causes JasperReports to export a report as a PDF
file:
myReport.ReportExportFile = "c:\\temp\\my_report.pdf";
reportLib.exportReport(myReport, ExportFormat.pdf);

540 EGL Programmer’s Guide


Important: JasperReports does not automatically refresh exported reports. If you
change the report design or if data changes, you must refill and re-export the
report.
Related concepts
“Creating reports with EGL” on page 531
EGL offers different ways to create reports, using external engines to generate
the report contents.
Related tasks
“Creating an EGL JasperReport handler”
“Creating the JasperReport design file” on page 534
The JasperReport design file specifies the layout and appearance of the report.
Unless you import a working design file (with the extension .jasper), you will
need to create or modify one.
“Using JasperReport templates” on page 546
Related reference
EGL JasperReport Handler
EGL library reportLib

Creating an EGL JasperReport handler


An EGL report handler of type JasperReport provides blocks of code that the
JasperReports engine can access at run time. Predefined function names tie some of
these code blocks to events that occur when JasperReports fills a report. Such
events might include the beginning or end of a page, the beginning or end of a
line item, or the beginning or end of the report itself. You can call other, custom
functions directly from the XML design file source.

To create an EGL report handler, do as follows:


1. Identify a project or folder to contain the file. If you do not already have a
project or folder, you must create one.
2. In the workbench, click File → New → Other.
3. In the New window, expand EGL.
4. Click Report Handler.
5. Click Next.
6. Select the project or folder that will contain the EGL source file and then select
a package.
7. In the EGL Source File Name field, type the name of the report handler source
file. Because the report handler name will be identical to the file name, choose
a file name that adheres to EGL part name conventions (for example,
myReportHandler).
8. Click Finish.

The New EGL Report Handler wizard will give you a list of function names that
correspond to report fill events. For example, JasperReports will invoke
″beforePageInit()″ before entering a page. You must create the code for these
functions.

Alternatively, you can add this template information to an existing file by


following these steps:
1. Create a new EGL source file.
2. Type handler and then press Ctrl+space.

Creating reports with EGL 541


The remainder of this topic contains code examples that show the following items:
v The outline of a generic report handler
v How to get report parameters in a report-handler
v How to get and set report variables
v How to get field values
v How to add a report data record
v How to pass report data to an XML design document
v How to invoke a custom report handler function from the XML design
document

These few examples cannot address all the complexities possible in a report
handler. For more detail, see the JasperReports documentation.

Report handler template


This is the template code that by the New EGL Report Handler wizard creates:
handler handlerName type jasperReport

// Use Declarations
use usePartReference;

// Constant Declarations)
const constantName constantType = literal;

// Data Declarations
identifierName declarationType;

// Pre-defined Jasper callback functions


function beforeReportInit()
end

function afterReportInit()
end

function beforePageInit()
end

function afterPageInit()
end

function beforeColumnInit()
end

function afterColumnInit()
end

function beforeGroupInit(stringVariable string)


end

function afterGroupInit(stringVariable string)


end

function beforeDetailEval()
end

function afterDetailEval()
end
end

Getting report parameters


Reports can contain three types of items: parameters (set in the XML file and do
not change), variables (changeable by the XML file or the report handler) and

542 EGL Programmer’s Guide


fields (keyed to names in the data source). The following code snippet shows how
to get report parameters in a report handler:
handler my_report_handler type jasperReport

// Data Declarations
report_title String;

// Jasper callback function


function beforeReportInit()
report_title = getReportParameter("ReportTitle");
end

end

Getting and setting report variables


The following code snippet shows how to get and set report variables in a report
handler:
handler my_report_handler type jasperReport

// Data Declarations
item_count int;

// Jasper callback function


function beforeDetailEval()
item_count = getReportVariableValue("itemCount");
end

function afterDetailEval()
setReportVariableValue("itemCount", (item_count + 1));
end
end

You must match variable types in the report handler with those in your XML
source file.

Getting report field values


The following example code snippet shows how to get report field values in a
report handler:
handler my_report_handler type jasperReport

// Data Declarations
employee_first_name String;

// Jasper callback function


function beforeColumnInit()
employee_first_name = getFieldValue("fName");
end
end

Saving report data in the report handler


The following example code shows how to save a customer record under the name
″saveCustomer″ for later access:
handler my_report_handler type jasperReport

// Data Declarations
customer_array customerRecordType[];
c customerRecordType;

// Jasper callback function


function beforeReportInit()
customer ReportData;

//create the ReportData object for the Customer subreport

Creating reports with EGL 543


c.customer_num = getFieldValue("c_customer_num");
c.fname = getFieldValue("c_fname");
c.lname = getFieldValue("c_lname");
c.company = getFieldValue("c_company");
c.address1 = getFieldValue("c_address1");
c.address2 = getFieldValue("c_address2");
c.city = getFieldValue("c_city");
c.state = getFieldValue("c_state");
c.zipcode = getFieldValue("c_zipcode");
c.phone = getFieldValue("c_phone");
customer_array.appendElement(c);
customer.data = customer_array;
addReportData(customer, "saveCustomer");
end
end

Retrieving report data in the XML file


After report data is saved in the report handler, you can retrieve it in the XML
source file and pass it to a subreport:
<jasperReport name="MasterReport" ... scriptletClass="subreports.my_report_handler">
...

<subreport>
<dataSourceExpression>
<![CDATA[(JRDataSource)(((subreports.SubReportHandler)
$P{REPORT_SCRIPTLET}).getReportData( new String("saveCustomer")))]]>;
</dataSourceExpression>
<subreportExpression class="java.lang.String">
<![CDATA["C:/RAD/workspaces/customer_subreport.jasper"]]>;
</subreportExpression>
</subreport>

...
</jasperReport>

Invoking a function from the XML design document


This report handler has one simple function: to print ″Hello, World!″
handler my_report_handler type jasperReport

function hello () returns (String)


return("Hello, world!");
end
end

Invoke it from the XML design document with this code:


<jasperReport name="MasterReport" ... scriptletClass="my_package.my_report_handler">
...

<summary>
<band height="40">
<textField>
<reportElement positionType="Float" x="0" y="20" width="500" height="15"/>
<textElement textAlignment="Center">
<font reportFont="Arial_Bold" size="10"/>
</textElement>
<textFieldExpression class="java.lang.String">
<![CDATA[((my_package.my_report_handler)$P{REPORT_SCRIPTLET}).hello()]]>
</textFieldExpression>
</textField>
</band>
</summary>

...
</jasperReport>

544 EGL Programmer’s Guide


The phrase ″Hello, world!″ will print at the end of the report.
Related concepts
“Creating reports with EGL” on page 531
EGL offers different ways to create reports, using external engines to generate
the report contents.
Related tasks
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.
“Using JasperReport templates” on page 546
Related Reference
EGL reports
Additional JasperReport handler functions
EGL library reportLib
EGL JasperReport Handler
Additional JasperReport handler functions

Running a report of type JasperReport


To run a report of type JasperReport, you must have the following files in the
specified locations:
v An EGL project with a build descriptor file.
v A compiled report design file (extension jasper) somewhere on your system.
Specify the location of the report design file in the report driver program. For
more information, see “Creating the JasperReport design file” on page 534.
v A report driver program (extension .egl) in the EGLSource folder of the project.
See “Writing code to drive a report of type JasperReport” on page 538.
v Optionally, you can have a report handler (extension .egl) in the EGLSource
folder of the project.
v If your report driver program accesses a database, you might need to tell EGL
where to find the appropriate Java Database Connectivity (JDBC) driver. You
might need to add an external Java Archive (JAR) file to your project properties.

To create and fill a report for an EGL project, follow these steps:
1. Build the EGL project by clicking Project → Build or Project → Clean. EGL
automatically generates Java code from any EGL source files that have changed
since the last build and compiles any changed design document source files.
2. Run the Java program that contains the generated report driver program. One
way to do this in the Package Explorer view is to navigate to and right-click
the .java file that contains the code. Then select Run As → Java Application
from the menu.

When you create a report, the JasperReports engine first creates an intermediate
destination file (extension .jrprint), from which it can create multiple export files in
different formats (.pdf, .html, .xml, .txt, or .csv). You specify locations for all of
these files in the report driver.
Related concepts
“Creating reports with EGL” on page 531
EGL offers different ways to create reports, using external engines to generate
the report contents.
“Elements of an EGL JasperReport application” on page 533
The main elements of a JasperReport application in EGL are a program to run

Creating reports with EGL 545


the report and a report design file to control the layout of the report.
Additionally, a report handler can give you greater control over the data put
into the report.
Related tasks
“Creating an EGL JasperReport handler” on page 541
“Creating the JasperReport design file” on page 534
The JasperReport design file specifies the layout and appearance of the report.
Unless you import a working design file (with the extension .jasper), you will
need to create or modify one.
“Writing code to drive a report of type JasperReport” on page 538
A report-driver program is an ordinary EGL program that runs a report using a
.jasper file that is compiled from a report design file.
Related reference
EGL reports
EGL library reportLib
EGL JasperReport Handler

Using JasperReport templates


EGL provides code that you can add to your program with a few keystrokes. That
code can provide most of the statements that you need to fill and export a report
through JasperReports or can give you a template for writing a report handler.

To fill and export a report through JasperReports, choose any of these data sources
for the report:
v Database connection
v Custom report data
v Result object from a specified SQL query

To add a report handler template to your source file, follow these steps:
1. Open a new file in your text editor.
2. Type handler, then press Ctrl+space
3. The editor will replace the word ″handler″ with template code. Work through
the code and add statements for the functions that you want to use. For more
information, including code examples, see Creating an EGL report handler.

To add JasperReport code to your source file, follow these steps:


1. Move your cursor to a new line within the main() section of your program.
2. Type jas, then press Ctrl+space
3. The editor provides a menu with options for database, custom, or SQL data;
select the appropriate template.
4. The editor will replace the letters ″jas″ with code; use the Tab key to move to
the fields that you need to change.

You can edit the templates themselves by following these steps:


1. Click Window → Preferences.
2. When a list of preferences is displayed, expand EGL.
3. Expand Editor and select Templates.
4. Scroll through the list of templates and select a template. For example, select
handler to display the report handler template.
5. Click Edit.

546 EGL Programmer’s Guide


6. Change the template to meet your needs.
7. Click Apply and then click OK to save your changes.
Related concepts
“Creating reports with EGL” on page 531
EGL offers different ways to create reports, using external engines to generate
the report contents.
Related tasks
“Creating an EGL JasperReport handler” on page 541
“Writing code to drive a report of type JasperReport” on page 538
A report-driver program is an ordinary EGL program that runs a report using a
.jasper file that is compiled from a report design file.

Creating JasperReport subreports


In the simplest case, with the subreport capability of JasperReports you can to
print associated data for each line item in a report—from the same table, from
another table in the same database, or from another data source altogether. More
complex cases are beyond the scope of this topic; refer to JasperReports
documentation for such information.

In complex cases you might need a report handler to provide data for the
subreport; see Creating an EGL report handler. In some simple cases, you can add a
subreport in two simple steps:
1. Add subreport code to the design file for the main report.
2. Create one or more design files for the subreport or subreports.

Here is an elementary example of how you can create a subreport and add it to
your report. Given a report that prints all the customers from the table
CUSTOMER, you can add a subreport that shows all invoices for each customer,
drawn from the table ORDERS.
1. This is a section of code from the main report design file. This code was
originally written to print one line for each customer in the table CUSTOMER.
Add the code shown in bold in the following example:
<queryString><![CDATA[SELECT * FROM ADMINISTRATOR.CUSTOMER]]></queryString>
<field name="CUST_NO" class="java.lang.Integer">
</field>
<field name="CUST_NAME" class="java.lang.String">
</field>
<detail>
<band height="100">
<subreport>
<reportElement positionType="Float" mode="Opaque" x="0" y="31"
width="709" height="12" isRemoveLineWhenBlank="true"/>
<subreportParameter name="CURRENT_CUST">
<subreportParameterExpression>
<![CDATA[$F{CUST_NO}]]>
</subreportParameterExpression>
</subreportParameter>
<connectionExpression>
<![CDATA[$P{REPORT_CONNECTION}]]>
</connectionExpression>
<subreportExpression class="java.lang.String">
<![CDATA[new String("C:\\workspace\\report_project\\bin
\\report_package\\my_subreport.jasper")]]>
</subreportExpression>
</subreport>
<textField>
<reportElement positionType="Float" x="57" y="11"

Creating reports with EGL 547


width="304" height="20"/>
<textElement/>
<textFieldExpression class="java.lang.String">
<![CDATA[$F{CUST_NO} + " " + $F{CUST_NAME}]]>
</textFieldExpression>
</textField>
</band>
</detail>

The <subreport> tag gives JasperReports the information it needs to run the
subreport:
v Positioning information (the same parameter that you will find in the main
report)
v Parameters that you want to pass to the subreport (in this case, the number
of the current customer, which you will need in the SQL SELECT statement
in the subreport)
v Connection information, because the report driver for this report specifies a
data source of DataSource.databaseConnection
v The location of a compiled report design file for the subreport (in this case,
my_subreport.jasper)
2. The subreport design file is not different in kind from any other .jasper design
file. Include the following essential code in that file:
<parameter name="CURRENT_CUST" class="java.lang.Integer"/>
<queryString><![CDATA[SELECT * FROM ADMINISTRATOR.ORDERS
WHERE CUST_NO = $P{CURRENT_CUST}]]></queryString>
<field name="CUST_NO" class="java.lang.Integer">
</field>
<field name="INVOICE_NO" class="java.lang.Integer">
</field>
<field name="ORDER_TOTAL" class="java.lang.Float">
</field>
<detail>
<band height="100">
<textField>
<reportElement positionType="Float" x="50" y="10" width="300" height="20"/>
<textElement/>
<textFieldExpression class="java.lang.String">
<![CDATA["Invoice # " + $F{INVOICE_NO} + " total: " +
$F{ORDER_TOTAL}]]>
</textFieldExpression>
</textField>
</band>
</detail>

Even though you passed the parameter CURRENT_CUST to the subreport, you
must tell the report what type the parameter is, using the class= attribute of the
<parameter> tag. Next comes the query string (JasperReports is very particular
about the order of the tags within the file). Here you reference the value of
CURRENT_CUST as $P{CURRENT_CUST}. The field names refer to column
names in the ORDERS table, which you can then reference inside the
<textFieldExpression> tag.

These are the only changes that you need to make to add a subreport; you do not
need to change any code in the EGL report driver program. If you want to include
other sources of data or complex calculations, however, you must create a report
handler (see Creating an EGL report handler).

You can create nested subreports. For example, you might call up line items for
each invoice from a third table. This would involve adding the information within

548 EGL Programmer’s Guide


a <subreport> tag to the subreport file my_subreport.jasper, and creating a separate
design file for the nested subreport (you might call it my_invoice_subreport.jasper).
There is no limit to the depth to which you can nest subreports.
Related Tasks
“Creating an EGL JasperReport handler” on page 541
“Creating the JasperReport design file” on page 534
The JasperReport design file specifies the layout and appearance of the report.
Unless you import a working design file (with the extension .jasper), you will
need to create or modify one.
Related Reference
EGL JasperReport Handler

Adding support for Jasper reports to a project


Before you can create reports with EGL and Jasper, you must add support for
Jasper reports to your project and add a Java compiler to your system’s path
variable.

Adding Jasper report support adds JAR files to your project that enable EGL to
compile report design files. You only need to do this once for each project that uses
Jasper reports, and there is no need to remove support from a project.

You can add support for Jasper reports only to EGL projects, not to EGL Web
projects.
1. In the Project Explorer view, right-click your EGL project and then click
Properties. The Properties window opens.
2. In the Properties window, click EGL Project Features.
3. Under EGL Project Features at the right side of the window, select the EGL
with Jasper report support check box. If this check box is already selected,
leave it selected.
4. Click OK.

Alternately, you can enable Jasper report support in a new project. Select the EGL
with Jasper report support check box in the New EGL Project wizard. Selecting
this check box has the same effect as selecting the check box in the Properties
window.

Adding the Java compiler to the PATH environment variable

To compile a report design file, EGL needs a Java compiler in your system’s PATH
environment variable.

Use a Java compiler with the same version as the version of Java you are using to
generate EGL. Follow these steps to tell what level of Java you are using:
1. Right-click an EGL project and then click Properties.
2. In the Properties window, click Java Compiler.
This page shows settings for the project’s Java compiler. By default, the Enable
project specific settings check box is cleared and the rest of the fields on the
page are disabled.
3. If the Enable project specific settings check box is selected, the version of Java
that you are using in this project is shown in the Compiler compliance level
field.

Creating reports with EGL 549


4. If the Enable project specific settings check box is cleared, click Configure
Workspace Settings. The Preferences window opens to the Compiler page, and
the version of Java you are using for all your projects is shown in the Compiler
compliance level field.

Follow these steps to add the Java compiler to your system:


1. Obtain and install a Java SDK if you do not already have one. IBM offers a Java
SDK for download at the following Web site: http://www.ibm.com/
developerworks/java/jdk/.
2. In your system’s PATH environment variable, add the location of the Java SDK.
See your operating system documentation for instructions.

Adding support for PDF reports

If you want to export reports in Portable Document Format (PDF), follow these
additional steps after adding support for Jasper reports:
1. Download the file iText-1.3.jar from the following Web site:http://
prdownloads.sourceforge.net/itext.
2. In the Project Explorer view, right-click your project and then click Properties.
3. In the Properties window, click Java Build Path.
4. On the Libraries tab, click Add External JARs.
5. In the JAR Selection window, select the iText-1.3.jar file that you just
downloaded and click Open.
Now the iText-1.3.jar file is listed under JARs and class folders on the build
path.
6. Click OK.

Setting the export location for reports in RCP mode

If you are creating reports in a Console UI application that is running in rich client
platform (RCP) mode, you must set the osgi.user.area system property to the
location where you want to store reports. Otherwise, reports will be created in the
product installation directory.
1. Click Run → Run. The Run window opens.
2. From the list of runtime configurations, expand Eclipse Application and then
click the run configuration for the program.
3. On the Arguments tab of the run configuration, add the following code:
-user "<location>"

In place of <location>, use the directory to which you want to generate the
reports.
4. Click Apply to save changes to the run configuration.
Related concepts
“Creating reports with EGL” on page 531
EGL offers different ways to create reports, using external engines to generate
the report contents.
“Elements of an EGL JasperReport application” on page 533
The main elements of a JasperReport application in EGL are a program to run
the report and a report design file to control the layout of the report.
Additionally, a report handler can give you greater control over the data put
into the report.

550 EGL Programmer’s Guide


“Features and facets of EGL projects” on page 76
EGL projects can have additional abilities, added through features and facets.
Related tasks
“Creating the JasperReport design file” on page 534
The JasperReport design file specifies the layout and appearance of the report.
Unless you import a working design file (with the extension .jasper), you will
need to create or modify one.
“Writing code to drive a report of type JasperReport” on page 538
A report-driver program is an ordinary EGL program that runs a report using a
.jasper file that is compiled from a report design file.
“Creating an EGL JasperReport handler” on page 541
“Running a report of type JasperReport” on page 545

Creating reports with BIRT


Business Intelligence and Reporting Tools (BIRT) is an Eclipse-based reporting
system that allows for sophisticated output in PDF or HTML format, including
graphics, tables, graphs, and charts. EGL support for BIRT is available when you
code either JSF handlers or programs generated for Java.

You can begin designing your output by opening the Report Design perspective of
the Workbench and creating a Report project. Alternatively, you can do all your
work in an EGL or Web project.

You create a report, which (in the context of your output-design work) is an XML
file whose default extension is .rptdesign. The steps are as follows:
1. Click File or right click on the project
2. Select New > Other
3. At the Select a Wizard dialog, choose Business Intelligence and Reporting Tools
> Report
4. Specify a parent folder and report name, and click Next
5. At the New Report dialog, select a template that will be the basis of your
report. Help is available if you press the question icon, and details on report
design will be displayed subsequently if you check Show Report Creation
Cheat Sheet.
6. Click Finish.
7. Your subsequent tasks include specifying a data source (for example, a JDBC
connection), specifying a data set (for example, the database columns specified
in an SQL SELECT statement), and using a palette to drag and drop elements
such as labels and tables. You can rely on the cheat sheet and can get a fuller
introduction to report design by accessing the tutorial and background detail at
the following Web site:

http://www.eclipse.org/birt

Working at the EGL or Web perspective, you create EGL code that drives output
creation. The creation can have two steps:
1. The report (hereafter called the design file) is converted to a second file, called a
document file, which has a default extension of .rptdocument and contains data
in an intermediate format
2. The document file is converted to the PDF or HTML output

Creating reports with EGL 551


Two other choices are possible, to speed processing:
v You can skip the creation of a separate document file
v You can start the process with an existing document file instead of a design file

The basic idea for working with BIRT in EGL is as follows:


v You create an EGL BIRT report, which is a variable based on BIRTReport, an
external type. You can include various details (name of a design file, for
example) when declaring that variable, or you can avoid specifying some or all
of the details and add them later by invoking functions or setting fields that are
specific to the EGL BIRT report. In either case, you can specify the details at
development time, by using literals, or at run time, by using variables.
Here’s an example of the syntax that first creates an EGL BIRT report and then
specifies the fully qualified name of the design file:
myReport BIRTReport { };
myReport.designFile = "C:/MyBIRTReport.rptdesign";
v You invoke a function that creates the output, as in the following example:
myReport.createReportFromDesign();
The following creation functions are available:
– createReportFromDesign() creates output from a design file, without storing
the report data in a document file
– createReportFromDocument() creates output from a document file
– createDocument() creates a document file from a design file
v You can create an EGL report handler of type BIRTHandler. This optional logic
part contains functions that act as event handlers, allowing you to customize
many details that affect the report output. When EGL is creating a report
document (as is possible with createDocument or createReportFromDesign), the
EGL runtime code invokes the event handlers in response to the following
events, among others:
– The opening or closing of a text file or database connection
– The opening or closing of a database cursor
– The retrieving of a row of database data into report fields
– The creation of a report element such as a label or grid
An event handler might (for example) accomplish one of the following tasks:
– Specify the value of a report parameter that guides some aspect of report
processing
– Specify a user ID and password for connecting to a database
– Set up an SQL SELECT statement to guide data retrieval from the database
– Act as an intermediary, receiving displayable data from your EGL program
and then providing that data to the report engine at the appropriate time
– Change report formatting and text in response to a specific value being
placed into the report

You can use a cascading style sheet (CSS) to control display characteristics of the
report.
Related concepts
“Creating reports with EGL” on page 531
EGL offers different ways to create reports, using external engines to generate
the report contents.
Related tasks

552 EGL Programmer’s Guide


“Creating an EGL BIRT handler” on page 555
An EGL BIRT handler (that is, an EGL handler of type BIRTHandler) contains
functions that are invoked when EGL is creating a report document. The
process of creating a BIRT handler is to create a source file and, within that file,
to code the handler. For details on what to code, see ″EGL BIRT handler″ in the
Reference Guide.
“Adding support for BIRT reports to a project”
Before your EGL code can create BIRT reports, you must add support to your
project. You need to add support only once for each project, and you do not
need to remove support if you stop using BIRT reports. During this beta,
support is available for General and Plug-in projects.
Related reference
BIRT Reports
Central to EGL’s support for Business Intelligence and Reporting Tools (BIRT) is
the external type called BIRTReport. This topic describes how to create a
variable of that type and how to use it to create output.
EGL BIRT handler
An EGL BIRT handler part contains event handlers, which are functions
invoked during report creation. For an overview of EGL support for BIRT, see
″Creating reports with BIRT″ in the Programmer’s Guide.

Adding support for BIRT reports to a project


Before your EGL code can create BIRT reports, you must add support to your
project. You need to add support only once for each project, and you do not need
to remove support if you stop using BIRT reports. During this beta, support is
available for General and Plug-in projects.

You can add support for BIRT as you create a project. On the second screen in the
New EGL Project wizard, check Show Advanced Settings, and at the next screen,
select the EGL with BIRT report support check box.

Alternatively, you can add support for an existing project:


1. In the Project Explorer view, right-click your EGL project and then click
Properties. The Properties window opens.
2. In the Properties window, click EGL Project Features.
3. Under EGL Project Features at the right side of the window, select the EGL
with BIRT report support check box. If this check box is already selected, leave
it selected.
4. Click OK.

Also, if you need to reference graphics that are stored in the BIRT resource folder,
click Windows -> Preferences ->Report Design -> Resource and specify the folder.
For additional details on graphics and BIRT, see ″External types in BIRT
report-layout event handler″; in particular, the section on ImageInstance.

Adding support for PDF reports

If you want to export reports in Portable Document Format (PDF), you have an
additional step after adding support for BIRT reports.

For a General project, do as follows:


1. Download the file iText-1.3.jar from the following Web site:http://
prdownloads.sourceforge.net/itext.

Creating reports with EGL 553


2. In the Project Explorer view, right-click your project and then click Properties.
3. In the Properties window, click Java Build Path.
4. On the Libraries tab, click Add External JARs.
5. In the JAR Selection window, select the iText-1.3.jar file that you just
downloaded and click Open.
Now the iText-1.3.jar file is listed under JARs and class folders on the build
path.
6. Click OK.

For a Plug-in project, do a series of steps outside of the Integrated Development


Environment:
1. Download the file iText-1.3.jar from the following Web site:http://
prdownloads.sourceforge.net/itext.
2. Find the product install location for IBM shared code and then the plugins
directory; for example:
C:\Program Files\IBM\SDP70Shared\plugins
3. In the plugins directory, find the most recent version of the directory for plugin
com.lowagie.itext; for example
com.lowagie.itext_1.3.0.v20070205-1728
As shown, the name is followed by a version number and timestamp.
4. Ensure that a lib directory is within the directory for plugin com.lowagie.itext.
If lib is not there, add it; for example:
com.lowagie.itext_1.3.0.v20070205-1728\lib
5. Copy the file iText-1.3.jar into the lib directory.

Setting the build descriptor option birtEngineHome

Before you can work with BIRT, you need to download BIRT runtime code and set
the birtEngineHome build descriptor option, but only if you are working in a
General project. Here are the steps:
1. Go to http://www.eclipse.org/birt
2. Access the runtime code of interest. At this writing, the procedure is as follows:
a. On the left of the page, click Download
b. At the next page, go to the More Downloads section and click Recent
Builds Page
c. At the next page, go to the Latest Releases section and, in the Build Name
column, click 2_3_0
d. At the next page, go to the Report Engine section and click
birt-runtime-2.3.0.zip
e. At the next page, click a mirror location and follow the displayed
instructions to download the code

Note: Rational Business Developer 7.5 supports BIRT version 2.3.0 and no
others.
3. Unzip the downloaded code into a directory of your choice; for example,
C:\birt
4. In the project build descriptor, set the birtEngineHome option to the fully
qualified path of the ReportEngine directory; for example, C:\birt\birt-runtime-
2_3_0\ReportEngine

554 EGL Programmer’s Guide


Accessing the non-EGL jar files needed at deployment time

To deploy code that runs a BIRT report, ensure that you deploy a set of jar files
that are found in the ReportEngine\lib subdirectory of the directory that contains
the BIRT runtime code; for example, in C:\birt\birt-runtime-2_3_0\ReportEngine\
lib.

The jar files are commons-codec-1.3.jar, coreapi.jar, engineapi.jar, js.jar, modelapi.jar,


and scriptapi.jar. For a description of how to deploy them, see the Generation
Guide section ″Preparing for Deployment″.
Related concepts
“Creating reports with BIRT” on page 551
Business Intelligence and Reporting Tools (BIRT) is an Eclipse-based reporting
system that allows for sophisticated output in PDF or HTML format, including
graphics, tables, graphs, and charts. EGL support for BIRT is available when
you code either JSF handlers or programs generated for Java.
Related tasks
“Creating an EGL BIRT handler”
An EGL BIRT handler (that is, an EGL handler of type BIRTHandler) contains
functions that are invoked when EGL is creating a report document. The
process of creating a BIRT handler is to create a source file and, within that file,
to code the handler. For details on what to code, see ″EGL BIRT handler″ in the
Reference Guide.
Related reference
BIRT Reports
Central to EGL’s support for Business Intelligence and Reporting Tools (BIRT) is
the external type called BIRTReport. This topic describes how to create a
variable of that type and how to use it to create output.
EGL BIRT handler
An EGL BIRT handler part contains event handlers, which are functions
invoked during report creation. For an overview of EGL support for BIRT, see
″Creating reports with BIRT″ in the Programmer’s Guide.
birtEngineHome
External types in a BIRT report-layout event handler
This topic reviews the EGL external types that you use when coding a
report-layout event handler. For background information, see ″EGL BIRT
reports,″ ″BIRT handler″ and ″BIRT report-layout event handlers.″

Creating an EGL BIRT handler


An EGL BIRT handler (that is, an EGL handler of type BIRTHandler) contains
functions that are invoked when EGL is creating a report document. The process of
creating a BIRT handler is to create a source file and, within that file, to code the
handler. For details on what to code, see ″EGL BIRT handler″ in the Reference
Guide.

To create a BIRT handler, do as follows:


1. Identify a project or folder to contain the file. If necessary, create the project or
folder.
2. In the workbench, click File -> New -> EGL -> EGL Source File.
3. Select the project or folder that will contain the EGL source file and then select
a package.

Creating reports with EGL 555


4. In the EGL Source File Name field, type the name of the handler source file.
The file name will be identical to the name of the report handler name.
5. Click Finish.
6. The next step works only if the capability ″EGL with BIRT support″ is in effect.
To put that capability into effect, click Window->Preferences and, when the
Preferences dialog is displayed, highlight EGL and, at the right, select the
checkbox for EGL with BIRT report support.
7. In the EGL source editor, type handler with no subsequent space and press
Ctrl-Space. At the context menu, select Handler - EGL BIRT Handler.
8. Type the handler name.

For an overview of EGL support for BIRT, see ″Creating reports with BIRT.″
Related concepts
“Creating reports with BIRT” on page 551
Business Intelligence and Reporting Tools (BIRT) is an Eclipse-based reporting
system that allows for sophisticated output in PDF or HTML format, including
graphics, tables, graphs, and charts. EGL support for BIRT is available when
you code either JSF handlers or programs generated for Java.
Related tasks
“Creating an EGL BIRT handler” on page 555
An EGL BIRT handler (that is, an EGL handler of type BIRTHandler) contains
functions that are invoked when EGL is creating a report document. The
process of creating a BIRT handler is to create a source file and, within that file,
to code the handler. For details on what to code, see ″EGL BIRT handler″ in the
Reference Guide.
“Adding support for BIRT reports to a project” on page 553
Before your EGL code can create BIRT reports, you must add support to your
project. You need to add support only once for each project, and you do not
need to remove support if you stop using BIRT reports. During this beta,
support is available for General and Plug-in projects.
Related reference
BIRT Reports
Central to EGL’s support for Business Intelligence and Reporting Tools (BIRT) is
the external type called BIRTReport. This topic describes how to create a
variable of that type and how to use it to create output.
EGL BIRT handler
An EGL BIRT handler part contains event handlers, which are functions
invoked during report creation. For an overview of EGL support for BIRT, see
″Creating reports with BIRT″ in the Programmer’s Guide.

Creating EGL text reports


EGL offers its own report engine (an external Java class) that produces a simple
text report. This engine is particularly useful for migrating reports from Informix
4GL.

The following steps provide a broad overview of the process of creating an EGL
text report:
1. Create a basic Handler part. This program performs the following actions:
v It declares a report variable that has access to the functions and variables of
the report engine (the Java class). The declaration can optionally change

556 EGL Programmer’s Guide


default format values such as margins, headers, and so on. For more
information on the specific values you can set when creating the variable, see
Creating a TextReport variable.
v It defines functions that are tied to specific events during report generation.
See “Handler events for a text report.”
v It passes control to the report engine, which calls the handler functions as
appropriate.
2. Create a report generator program. This program performs the following
actions:
v It declares a variable that is based on the basic Handler part.
v It passes control to the handler program.

For a sample text report program and handler, see “Writing code to print a text
report” on page 558.

The text report engine includes functions for most of the tasks that you perform in
the handler, including functions to start and finish the report, to print lines, text, or
white space, to manage headers and footers, and more. For a complete list of these
functions, see Text report functions.

For more information on converting existing I4GL reports to EGL, refer to the IBM
Informix 4GL to EGL Conversion Utility User’s Guide.
Related concepts
“Creating reports with EGL” on page 531
EGL offers different ways to create reports, using external engines to generate
the report contents.
“Handler events for a text report”
The TextReport external type defines the events that a basic text report handler
can react to.
“Writing code to print a text report” on page 558
This topic provides a sample text report program and handler.
Text report functions

Handler events for a text report


The TextReport external type defines the events that a basic text report handler can
react to.

Each event is a variable that you reference through the text report variable. You
can code a function for any of these events. The text report engine calls the
corresponding function whenever the event occurs. Use a simple EGL assignment
statement in the handler to associate a function with an event, as in the following
example:
myReport.onFirstPageHeaderListener = printHeader1;

If you assign a function name to one of these event variables, you must create a
matching function in the handler. The matching functions must have a single
argument, a TextReportEvent type variable.

For a complete list of event variables, see Text report variables. For a sample text
report program and handler, see “Writing code to print a text report” on page 558.
Related concepts

Creating reports with EGL 557


“Creating reports with EGL” on page 531
EGL offers different ways to create reports, using external engines to generate
the report contents.
“Writing code to print a text report”
This topic provides a sample text report program and handler.
Text report variables
The text report engine recognizes a specific set of events during report
generation. Each event is represented by a variable in the engine.

Writing code to print a text report


This topic provides a sample text report program and handler.

Prerequisites
v An EGL project
v A database and a working connection to that database

Synopsis
The program prints a list of all customers in the SQL database and their current
balances.

The following events take place in the course of the program:


1. The report generator program creates variables that are based on
CustomerRecord and textReportHandler.
2. The report generator calls the start() function from the handler.
3. The handler start() function creates a variable that is based on the
TextReport ExternalType, and specifies functions for two events: onEveryRow
and onLastRow. The function then passes control of the report to the text
report engine by means of the myReport.startReport() function.
4. The myReport.startReport() function does not change any report formatting,
so the report engine returns control to the handler, which returns control to
the report generator.
5. The report generator creates a result set using the EGL open statement. This
result set contains all customers from the current database.
6. The report generator loops through the result set. For each customer, it sends
the handler output() function a customer name and balance.
7. The handler stores the customer name and balance in a record that is
accessible to all functions in the handler and updates the running balance
total.
8. The handler then passes control to the report engine using the
outputToReport() function.
9. After performing certain housekeeping tasks, the report engine calls the
onEveryRow() function in the handler.
10. The onEveryRow() function in the handler sends the customer name in the
current print position, moves to the 40th column of the page, prints the
customer balance, and sends a carriage return and form feed to the report file.
11. Control passes back to the report generator, which seeks the next customer
record to process. When it has processed all customers, the generator calls the
finish() function in the handler.
12. The finish() function in the handler passes control to the report engine
through the finishReport() function.
13. The report engine finds a function for the last-row event and calls
onLastRow() from the handler.
558 EGL Programmer’s Guide
14. The onLastRow() function in the handler prints the running total that the
handler has been updating.
15. The report engine closes the report file, and control passes back to the handler,
and finally to the generator, which terminates the run unit.

The customer record


The program uses the following record to access the SQL database of customers:
record CustomerRecord type SQLRecord
{tableNames = [["ADMINISTRATOR.CUSTOMER", "L1"]],
keyItems = [customerNumber]}

customerNumber STRING {column="C_NUMBER", maxLen=6};


customerName STRING {column="C_NAME", isSQLNullable=yes, maxLen=25};
customerAddr1 STRING {column="C_ADDR1", isSQLNullable=yes, maxLen=25};
customerAddr2 STRING {column="C_ADDR2", isSQLNullable=yes, maxLen=25};
customerAddr3 STRING {column="C_ADDR3", isSQLNullable=yes, maxLen=25};
customerBalance MONEY {column="C_BALANCE", isSQLNullable=yes};
end

The report generator


Execution begins with the report generator.
package com.companyb.customer;

program reportGenerator type BasicProgram

myCustomer CustomerRecord;
myHandler textReportHandler{};

function main()
myHandler.start(); // passes control to handler

// get customer list from database


open myResults scroll for myCustomer;
forEach (from myResults) // loop through results
myHandler.output(myCustomer.customerName, myCustomer.customerBalance);
end // forEach
myHandler.finish(); // close report
end
end

The generic handler


Both the report generator and the report engine call functions from the handler.
package com.companyb.customer;

record reportRecord type BasicRecord


customerName STRING;
customerBalance MONEY;
end

handler textReportHandler type BasicHandler

myReport TextReport{}; // creates instance


currentReportRecord reportRecord;
runningTotal MONEY = 0;

function start()
myReport.onEveryRowListener = onEveryRow;
myReport.onLastRowListener = onLastRow;

// accept defaults on everything but destination file


myReport.startReport("D:/temp/customerReport.txt",
null,null,null,null,null,null);
end

Creating reports with EGL 559


function output(cName STRING in, cBal MONEY in)
// this information comes from the forEach loop in the main program
currentReportRecord.customerName = cName;
currentReportRecord.customerBalance = cBal;
runningTotal = runningTotal + cBal;

// pass control to the report engine


// onEveryRow is called
myReport.outputToReport();
end

function finish()
// pass control to the report engine again
// onLastRow is called
myReport.finishReport();
end

function onEveryRow(myEvent TextReportEvent in)


myReport.printText(currentReportRecord.customerName);
myReport.column(40);
myReport.printText(currentReportRecord.customerBalance);
myReport.println();
end

function onLastRow(myEvent TextReportEvent in)


myReport.println(); // skip a line
myReport.printText("All customers:");
myReport.column(40);
myReport.printText(runningTotal);
end
end
Related reference
“Creating EGL text reports” on page 556
EGL offers its own report engine (an external Java class) that produces a simple
text report. This engine is particularly useful for migrating reports from
Informix 4GL.

560 EGL Programmer’s Guide


Working with Web transaction applications in EGL
Web transactions in EGL are a holdover from VisualAge Generator, and offer a
very basic Web interface for user I/O. Best practice is to use Web transactions for
migration only. New code should use JavaServer Faces (JSF) for a Web interface.

The central idea of Web transactions is similar to the one behind Text UI:
v A VGWebTransaction program (comparable to a Text UI program) presents a
Web page for user input.
v The Web page is based on a VGUIRecord (comparable to a Text UI form). EGL
transforms fields in the record into controls on the Web page, using field
properties to determine the type of control to create.

When generating COBOL, EGL simply includes the VGUIRecord in the compiled
program. When generating Java, EGL creates the following JSP files:
v filename.jsp, for each VGUIRecord file, where filename.egl is the source file
name.
v EGLWebStartup.jsp, a Web page that displays a list of your VGWebTransaction
programs. You select a program and run it from this page rather than running
the associated filename.jsp page.
v CSOERRORUIR.jsp, the error page that you customize to report on TCP/IP
communication problems and on problems internal to a Web transaction.
v Vagen1EntryPage.jsp, the default selection list for EGLWebStartup.jsp.
v A series of sample files that show how to perform common tasks:
– reqPage.jsp
– usrMsgPage.jsp
– Vagen1ErrorPage.jsp
– Vagen1ExpiredPasswordPage.jsp
– Vagen1LogonPage.jsp

You can customize these JSP files using Page Designer (see “Using EGL with the
Eclipse IDE” on page 1).

To run Web transactions in EGL, you must perform the following steps:
1. Modify configuration files (see “Web transaction configuration files” on page
563).
2. Get a Web server running in your workspace (see “Adding a Web server” on
page 393).
3. Customize Vagen1EntryPage.jsp to list your VGWebTransaction programs (see
“Running VGWebTransaction programs” on page 564).
4. Launch your programs through EGLWebStartup.jsp (see “Running
VGWebTransaction programs” on page 564).

Customizing JSP files


EGL does not just allow you to modify the JSP files that it creates from your
VGUIRecord files; it takes for granted that you will heavily modify these files. For
this reason, EGL does not overwrite an existing name.jsf file (where name is name
of your VGUIRecord). Instead, if name.jsf exists, EGL creates (or overwrites) a file

© Copyright IBM Corp. 1996, 2008 561


named newname.jsf. You must copy the changed portions of the file to name.jsf
yourself. Alternatively, if you want EGL to replace name.jsf, delete the file before
generating.
Related concepts
“Using EGL with the Eclipse IDE” on page 1
The Eclipse IDE offers a graphical user interface (GUI) called the workbench, in
which users perform work by pointing and clicking objects on the screen as
well as by typing code. In this way, when you are working with EGL, you are
using the Eclipse workbench, so it is worth taking a minute to look at the tools
in the workbench.
“Using VGUIRecord properties” on page 564
The relationship between the field properties determines how EGL translates
fields from the VGUIRecord into HTML controls on a JSP.
“Using JavaServer pages with Web transactions” on page 567
“UI record bean API” on page 570
Related tasks
“Web transaction configuration files” on page 563
Before you can run Web transactions in EGL, you must modify at least one
configuration file.
“Adding a Web server” on page 393
You must have a Web server started and synchronized before you can run Web
applications.
“Running VGWebTransaction programs” on page 564
To run a Web transaction program, start by running EGLWebStartup.jsp on your
Web server.

Adding Web transaction support to an EGL Web project


Before you can use Web transactions in your EGL project, you must add support
for Web transactions to your project. You can do this when you create the project,
or add support to an existing project.

Add support for Web transactions at the time you create a project:
v Create a new EGL Web project and select the Show Advanced Settings check
box on the general settings page of the New EGL Project wizard.
v Select the EGL support with Legacy Web Transactions check box on the Project
Facets page. The Project Facets page is the second page after the general settings
page.
Add support for Web transactions to an existing EGL Web project:
1. In the Project Explorer view, right-click the EGL Web project and then click
Properties. The Properties window opens.
2. In the Properties window, click Project Facets.
3. Click Add/Remove Project Facets.
4. In the Project Facets window, select the EGL support with Legacy Web
Transaction check box.
5. Click Finish.
6. Click OK.

Adding support for Web transactions makes the following changes to the project:

562 EGL Programmer’s Guide


v Jar files are added to the folder WebContent\WEB_INF\lib and to the project’s
Java build path. These Jar files constitute the runtime support of a Web
application and the EGL gateway servlet.
v The following sample and utility files are added to the project’s WebContent
folder:
– CSOERRORUIR.jsp
– EGLWebStartup.jsp
– Vagen1EntryPage.jsp
– Vagen1ErrorPage.jsp
– Vagen1ExpiredPasswordPage.jsp
– Vagen1LogonPage.jsp
– vawcg-wp.gif
– visage.gif
v Files that set properties for the gateway servlet and information for linkage
between Web transactions are added to the folder JavaResources\JavaSource. See
Gateway servlet parameters and Linkage properties.
v The gateway servlet is registered in the Web configuration file.

You can not remove support for Web transactions from a project.

If you want each new EGL Web project created to have support for Web
transactions, open the EGL preferences window and select the EGL support with
Legacy Web Transactions check box. See Setting EGL preferences.
Related tasks
“Working with Web transaction applications in EGL” on page 561
“Setting general preferences” on page 173
Related reference
Gateway servlet parameters
Web transaction linkage properties

Web transaction configuration files


Before you can run Web transactions in EGL, you must modify at least one
configuration file.

The gw.properties file in the JavaResources: src folder contains basic


configuration information for your Web transaction application. By default, the file
names csogw.properties as the hptLinkageProperties file, which resolves locations
for your application.

You will have to edit the csogw.properties file (or whatever file you use to specify
your linkage) before your programs will run properly. The following instructions
cover the simplest case; for more complex cases, and for more information, see
″Web transaction linkage properties″ in the EGL Generation Guide.
1. You can configure the file to look for your Web transaction programs in
different locations depending on the file name. In this example, assume all your
files are located in a single local directory. The asterisk in the following line is a
wildcard that represents any character or string of characters:
application.*=allfiles
2. You have now associated the name allfiles with any application EGL is
looking for. Tell EGL that the files are local with the following line:

Working with Web transaction applications in EGL 563


serverLinkage.allfiles.commtype=DIRECT
3. Assign a folder (relative to the current JavaResources: src folder) where your
generated programs reside (shown as fileLocation in the following line):
serverLinkage.allfiles.javaProperty=fileLocation

These three lines provide the minimum configuration information for


EGLWebStartup.jsp to work properly.
Related concepts
“Working with Web transaction applications in EGL” on page 561
Web transaction linkage properties

Running VGWebTransaction programs


To run a Web transaction program, start by running EGLWebStartup.jsp on your
Web server.

You do not directly run either a VGWebTransaction program or a JSP file based on
a VGUIRecord. Instead EGL manages the interaction between the program, the JSP,
and the related bean by means of a Web page, EGLWebStartup.jsp, that is
generated for you automatically when you associate the project with runtime Web
server.

EGLWebStartup.jsp displays in a browser in your Web server; if necessary EGL will


start the server for you. The page presents a list of programs for the user to choose
from.

By default, EGLWebStartup.jsp displays the selection list that it finds in


Vagen1EntryPage.jsp (for other options, see “Web transaction configuration files”
on page 563). Customize this list to include all Web Transaction programs you
want to run from this project. Use the name of the VGWebTransaction source
program, with no extension, as in the following example:
<FORM METHOD=POST ACTION="<%= hptGatewayURL %>">
<BR>Choose a Program to execute below:<BR>
<SELECT NAME="hptAppId" SIZE=10>
<OPTION VALUE=CPGM01>Customer file maintenance
<OPTION VALUE=CPGM02>Process new orders
<OPTION VALUE=CPGM03>Print invoices
</SELECT>
Related concepts
“Working with Web transaction applications in EGL” on page 561
“Web transaction configuration files” on page 563
Before you can run Web transactions in EGL, you must modify at least one
configuration file.

Using VGUIRecord properties


The relationship between the field properties determines how EGL translates fields
from the VGUIRecord into HTML controls on a JSP.

Most UI controls involve setting the uiType property to one of the following
values:
v input
v inputOuput
v output

564 EGL Programmer’s Guide


The following table shows how to create each of the specified HTML controls.
Table 56. HTML controls
HTML Field is selectedIndex-
control array? uiType Field length Item Field value
Text box N input or <=80 chars n/a Initial display
inputOutput
Text area N input or > 80 chars n/a Initial display
inputOutput (between
<textarea> and
</textarea>
tags)
Radio Y input or n/a Numeric field Not used
buttons inputOutput
Check boxes Y input or n/a Numeric array Not used
inputOutput
Single- Y output n/a Numeric field Entries in
selection combo box
combo box
Multiple- Y output n/a Numeric array Entries in
selection combo box
combo box

The following code creates a set of three radio buttons:


10 ID INT [3] {
displayName = "First option: \nSecond option: \nThird option:" ,
selectedIndexItem = SELECTEDID,
uiType = input
} = [1, 2, 3];

10 SELECTEDID int {
uiType = none
};

The displayed control looks like the following example:

Note that each radio button label is followed by a text box that contains the value
of the corresponding array member. These text boxes are an artifact of the
VisualAge Generator implementation; EGL maintains this behavior for
compatibility. Because the variable that generates the display has three INT

Working with Web transaction applications in EGL 565


members, and has a uiType of input, you could, in theory, enter new values for
any of those members; in practice, there is no reason to do so.

If you change SELECTEDID to an array, the code will create a Web page with
check boxes instead of radio buttons:
10 SELECTEDID int [3] {
uiType = none
};

If you take the same code and change the uiType to output, EGL will create a
combo box rather than radio buttons or check boxes. Here it makes sense to also
change the display name, as the user is selecting a value from the array rather than
from the prompt message. If SELECTEDID is an array, the user can hold down the
Shift key and make multiple selections. If SELECTEDID is a single INT, as in the
following code, the user can select only a single value:
10 ID INT [3] {
displayName = "Pick a number:" ,
selectedIndexItem = SELECTEDID,
uiType = output
} = [1, 2, 3];

10 SELECTEDID int {
uiType = none
};

The displayed control looks like the following example:

Other controls
Other values of the uiType property create other HTML artifacts. Consider the
following example of a field from a VGUIRecord source file:
10 MYLINK char(32) {
displayName = "MyLink",
uiType = programLink,
@programLinkData {
programName = "DEST_PGM",
uiRecordName = "DEST_PGE",
newWindow = no,
linkParms = [
@linkParameter { name = "PARM", value="ParmData" },
@linkParameter { name = "NAME", valueRef=NAME },
@linkParameter { name = "ID", value="107" }
]
}
};

Here the UI type of programLink causes the contents of the displayName property
(″MyLink″) to be displayed as a link. That link points to the program in the

566 EGL Programmer’s Guide


programName property (″DEST_PGM″), which launches the page in the
uiRecordName property (″DEST_PGE″). The names and values in each of the
@linkParameter properties are passed in a query string with the URL of the
destination program.

The following example shows a field that generates a <FORM> tag and all
associated contents on the browser:
10 MYFORM01 char(60) {
displayName = "MyForm01",
uiType = uiForm,
@programLinkData {
programName = "DEST_PGM",
uiRecordName = "DEST_PGE",
newWindow = no,
linkParms = [
@linkParameter { name = "PARM", value="ParmData" }
]
}
};

Substructure fields below MYFORM01 declare fields within the form, such as any
of the input or output controls shown earlier, or the following submit button:
20 BUTTON1 char(8) {
displayName = "Submit",
uiType = submit
} = "SUBMIT";

When the user submits the form, The VGWebTransaction program calls the
program in the programName property using the show command. For information
about how field values are passed to the called program, see ″show″ in the EGL
Language Reference.
Related concepts
“Working with Web transaction applications in EGL” on page 561
Related reference
show considerations for Web transactions

Using JavaServer pages with Web transactions


When you save a VGUIRecord source file, a default JSP file is created, based on the
fields in the VGUIRecord part. You can edit this default JSP to change its
appearance or the data displayed on it. More information on JSP technology is
available atJavaServer Pages (JSP) technology

JavaServer Pages (JSP files) are ASCII files that have a .jsp suffix and contain a
mixture of HTML tags and JSP syntax. A Web application server transforms a JSP
file into a Java servlet by a process known as page compilation.

Scriptlets

Pieces of Java code called scriptlets can be inserted into JSP files. Scriptlets can be
placed anywhere in the JSP source. At run time, the Java code in the scriptlet runs
on the server side, but the Java code itself is not included with the HTML sent to
the browser. Methods specific to UI record beans are covered in “UI record bean
API” on page 570.

The following code shows a simple scriptlet:


<% if (x == 1) {out.println(EMPNO.getLabel())}; %>

Working with Web transaction applications in EGL 567


The Java code in a scriptlet can add to the HTML by printing a string to the out
PrintWriter object. This out object is created and made available to the scriptlet as
part of the page compilation process of the JSP. The out object accepts only strings.
If you need to print something other than a string type, you must first convert that
type to a string.

There are three ways to print to the out object.


<% out.print(string_value); %>
This scriptlet adds the string string_value to the HTML code at the location
of the scriptlet.
<% out.println(string_value); %>
This scriptlet adds the string string_value to the HTML code at the location
of the scriptlet and then adds a carriage control character. Adding the
carriage control character starts the next HTML code on the next line,
which can increase the readability of the source code. This carriage return
does not affect the appearance of the HTML in the browser, and it does not
have the effect of the HTML <br> tag.
<% string_value %>
This scriptlet is equivalent to <% out.print(string_value); %>.

In this way, scriptlets let you access data in the VGUIRecord and use that data on
the page. For specific methods for accessing a UI record bean, see “UI record bean
API” on page 570.

Bean tags

The JSP file created to go along with the VGUIRecord references a UI record bean.
This UI record bean gives the scriptlets in the JSP access to the data in the
VGUIRecord. The JSP file references this bean with the <jsp:useBean> tag.

For example, the following code references a bean to be used in a JSP file:
<jsp:useBean id="referenceName"
class="beanClassName"
type="interfaceName"
scope="beanScope" />
referenceName
The name of the bean. Other scriptlets in the JSP file can use this bean by
referring to its name as defined in the <jsp:useBean> tag.
beanClassName
The fully qualified class name of the bean, such as java.lang.String.
interfaceName
A interface implemented by a bean. This attribute is optional.
beanScope
The scope of the bean. Valid values are:
session
The bean is stored in the HttpSession object.
request
The bean is stored in theHttpServletRequest object.
page The bean is stored in the JSP page context.
application
The bean is stored in the servlet context.

568 EGL Programmer’s Guide


Directives

The JSP file can also include JSP directives. Two of these directives are significant
when working with Web transactions:

The import directive lets you add Java import statements. These import statements
apply to any scriptlet in the JSP. Java import statements are a shorthand to save
you from having to type out the fully qualified name of the package everywhere
when referring to elements inside it.

Add the following import directive to each JSP file created to work with a
VGUIRecord:
<%@ page import = "com.ibm.vgj.uibean.VGDataElement" %>

The errorPage directive specifies a Web page to forward the browser to in response
to an uncaught exception. For example, if a UI record JSP specifies an incorrect
array index in a call to the UI record bean, the JSP specified in the errorPage
directive handles the error.

Do not specify CSOERRORUIR.jsp in the errorPage directive, even though


CSOERRORUIR.jsp is the error page that you customize to report on TCP/IP
communication problems and on problems internal to a Web transaction. If you
want all errors to be presented by CSOERRORUIR,jsp, specify
errorPage="vagen1error.jsp".

The following example shows an errorPage directive:


<%@ page errorPage="jspName.jsp" %>
Related concepts
“UI record bean API” on page 570
“Working with Web transaction applications in EGL” on page 561

Transferring control between JSF Handlers and Web transactions


EGL JSF Handlers, VisualAge Generator Web transactions, and EGL
VGWebTransaction parts can forward control and data to each other, but each does
so in a different way.

To forward control from a pageHandler to a VisualAge Generator Web transaction


or EGL VGWebTransaction part, use the EGL forward statement.
v The simplest way to forward control to a Web transaction or VGWebTransaction
part is to forward control to the gateway servlet instead of the Web transaction
or VGWebTransaction part directly. In this case, the forward statement points the
browser to the gateway servlet’s introductory page, and it is not possible to send
any parameters. This type of forward statement has the following format:
forward to URL "URL";
URL
The complete URL of the gateway servlet on which the target Web
transaction is located.
v To forward control directly to a specific VisualAge Generator Web transaction or
EGL VGWebTransaction part, you must specify which Web transaction or
VGWebTransaction that the gateway servlet should load. This type of forward
statement has the following format:
forward to URL "URL?hptAppId=linkageID";

Working with Web transaction applications in EGL 569


URL
The complete URL of the gateway servlet on which the target Web
transaction is located.
linkageID
The linkage ID of the Web transaction or VGWebTransaction part. This
parameter is the webtran parameter in the application property that defines
this Web transaction in the linkage properties file. For example, if a Web
transaction is defined in the linkage properties file with the code
application.WEBUITRAN=CICS5, the linkageID parameter in the forward
statement is WEBUITRAN. For more information, see ″Web transaction linkage
properties″ in the EGL Generation Guide.

To forward control from a VisualAge Generator Web transaction or EGL


VGWebTransaction part to an EGL pageHandler part, you must modify the JSP file
associated with the Web transaction.
v If the JSP file associated with the Web transaction uses a form tag, modify the
action attribute of that tag to reference the URL of the JSP file associated with
the pageHandler.
v If the JSP file associated with the Web transaction uses an anchor tag, modify
the href attribute of that tag to reference the URL of the JSP file associated with
the pageHandler.
Related tasks
“Web transaction configuration files” on page 563
Before you can run Web transactions in EGL, you must modify at least one
configuration file.
Web transaction linkage properties

UI record bean API


At run time, the VGUIRecord part is represented by a UI record bean. The
commands listed in the interface below can access this bean from a JSP file.

The String class is used by all get and set methods implemented for variables with
a uiType property of input, output, or inputOutput in the Java Bean generated for
the UI record.

Set and get methods implemented for variables that are defined with a uiType of
none return the appropriate Java class for the variable.

UI Record Bean Interface

The get and set methods implemented for the UI record bean are described in this
section. These methods get and change information about the VGUIRecord as a
whole.
String getTitle();
Returns the default title of the page from the title property of the
VGUIRecord.
String getHelpText();
Returns the text from the help property of the VGUIRecord.
String getGatewayURL();
Returns the gateway URL and is used as the ACTION of an HTML form.

570 EGL Programmer’s Guide


String getSecureGatewayURL();
Returns the gateway URL with the HTTPS protocol and is used as the
ACTION of an HTML form.
String getPageID();
String form of the number that uniquely marks the page that is served to
the client.
String getAppID();
Returns the ID that identifies the Web transaction with which the
VGUIRecord is associated.
String getSessionID();
Returns the ID that identifies the current gateway session that processes
the submit request.
boolean hasInputError();
Indicates whether or not any field in the VGUIRecord is in error.
VGDataElement elementNamed(String name);
Returns the element in the UI record bean named name.
VGDataElement getfieldName();
Returns the value of the specified field from the VGUIRecord.
void setfieldName(String value);
Sets the specified field from the VGUIRecord to the specified value.

VGDataElement Interface

These methods get or change information about an individual field (a


VGDataElement) within the VGUIRecord.
Enumeration getEditTableValues();
Returns the elements in an edit table associated with an input field.
String getErrorMessage();
Returns the error message associated with the element.
String getGatewayURL();
For variables that do not have a uiType property set to form or
programLink, returns the same value as the UI record bean version of this
method.
For variables that do have a uiType property set to form or programLink,
returns a URL string that contains all the parameters as defined by the link
properties. This string is usable as an HREF in an <A> HTML element.
String getSecureGatewayURL();
Same as getGatewayURL() but uses the HTTPS protocol.
String getHelpText();
Returns the text in the help property for the field.
int getIndex();
Returns the index of the element.
String getLabel();
Returns the label UI property of a variable. If the variable is an element of
an array, returns the label defined for the index of the VGDataElement
instance.

Working with Web transaction applications in EGL 571


String getTextValue();
Returns the String value of the element with all output formatting on the
data.
TableModel getTextValuesTable();
Returns a TableModel of all formatted text values for the occurrences and
sub-elements of the VGDataElement instance.
boolean hasInputError();
Returns TRUE if the element has an input error.
boolean isDisplayable();
Returns TRUE if the variable associated with a submit button has a
non-blank value.
boolean isEmpty();
Returns TRUE only when the field is an array, and the value of the field
specified by the numElementsItem property is zero.
In any other case the method returns FALSE. The following cases return
FALSE:
v The field is not an array.
v The field is an array, but the numElementsItem property has a null
value.
v The field is an array, but the value of the field specified by the
numElementsItem property is not zero.
boolean isSelected();
Returns TRUE if the index of the element is a value in the field specified
by the SelectedIndexItem property.
Enumeration occurrences();
If the target VGDataElement is an array, the method returns an
Enumeration containing the elements of that array. The number of
elements returned is limited by the value of the field in the
numElementsItem property. If the target is not an array, the method
returns an Enumeration with only a single element.
Enumeration subElements();
Returns Enumeration of VGDataElements that are valid sub-elements (the
uiType property is not set to none) of the VGDataElement instance. Only
the lowest level sub-elements are returned. The index of each sub-element
is that of the VGDataElement instance.
void setDatetimeFormat(DateFormat_object);
Sets a Java DateFormat object to specify the valid format for date/time
values that pass between the browser and tier 2 in either direction. You can
use this method only on a variable that has been assigned a date or time
edit.
Related concepts
“Working with Web transaction applications in EGL” on page 561
“Using JavaServer pages with Web transactions” on page 567

572 EGL Programmer’s Guide


Debugging EGL applications
Debugging is the process of monitoring the execution of a program to pinpoint the
causes of errors. With the EGL debugger, you can set breakpoints (places for
execution to pause), examine or change variables, and move through the program
one step at a time. You can debug the following code:
v JSF Handlers
v Programs
v Rich UI Handlers; in this case, see Rich UI debugging

At its simplest, debugging an EGL program involves the following:


v Selecting the preference Window → Preferences → EGL → Debug → Stop at first
line of a program
v Opening an EGL source program in the editor
v Changing to the Debug perspective (Window → Open Perspective → Other →
Debug)
v Right-clicking the program name in the Outline view and selecting Debug EGL
Program
v Clicking the Step Into button to move through the program

Debugging using JDBC for SQL access

The debugger uses JDBC for SQL access, which creates the following differences
from running on environments where JDBC is not used:
v JDBC does not support two-phase commit. There are separate calls to the SQL
manager and MQ series manager for commit and rollback. Therefore, if a
problem occurs, it is possible for one resource to commit or rollback without the
corresponding commit or rollback for the other resource.
v JDBC always runs dynamic SQL. Generated COBOL uses static SQL except
when you use the EGL prepare statement or a table name host variable
(tableNameVariables property in the SQLRecord definition). Therefore, there are
the following differences:
– In dynamic mode, single row select can result in more than one row being
returned without setting sysVar.sqlData.sqlCode to -811. As long as there is
only one row that satisfies the criteria you do not notice a difference. See the
following sample technique for how you can address this difference if it is
important to you.
– JDBC converts data that is defined on the host as a CHAR, DBCHAR, or
MBCHAR SQL column with the ″FOR BIT DATA″ option. If you have this
situation, set the asBytes property to YES for the field that corresponds to the
SQL column that is defined as ″FOR BIT DATA″.

The following limitations also apply to both Debug and Java programs. There is a
difference between Debug and generated COBOL programs, but no difference
between Debug and generated Java programs:
v Be sure to use the DATE, TIME, and TIMESTAMP primitive types when
defining fields for SQL columns that contain these types. You can use the CHAR
primitive type, as long as the CHAR variable has the sqlDataCode property set
to indicate the type of the SQL column. You can also use CHAR without the

© Copyright IBM Corp. 1996, 2008 573


sqlDataCode property, but when you omit the sqlDataCode, you must rely on
the JDBC driver to convert the dates to CHAR format. For further information
on sqlDataCode, see sqlDataCode
v Certain SQL information is not supported by JDBC:
– sqlLib.sqlData.sqlerrmc
– sqlLib.sqlData.sqlwarn[n]
– sysVar.sqlData.sqlerrmc
– sysVar.sqlData.sqlwarn[n]

More sophisticated debugging involves launch configurations, breakpoints,


database connections, setting variable values, and other concepts. For an overview,
see “Stepping through an application in the EGL debugger” on page 575.

Debug environment different from host

There is a technique you can use when the debug environment is different from
the host environment: In the EGL -> Debug preferences, select Set systemType to
DEBUG. In the EGL program you can include logic such as the following:
if (sysVar.systemType is debug)
// do nothing
else
// check for sysVar.sqlData.sqlCode = -811
end

This enables you to include system-specific logic that is only valid on the host
system.

For information on the keyboard differences, see the EGL function key mapping
table in validationBypassKeys or helpKey.

Debugging programs

To debug programs that do not run under JEE, you can start the debug session as
described in “Stepping through an application in the EGL debugger” on page 575.

For information on EGL debugger commands, see “EGL debugger commands” on


page 580. For more information on how build descriptor settings affect the EGL
debugger, see “How build descriptor settings affect the EGL debugger” on page
583.
Related concepts
VisualAge Generator compatibility
“Character encoding options for the EGL debugger” on page 603
“EGL debugger commands” on page 580
Rich UI debugging
Related tasks
“Setting preferences for SQL database connections” on page 219
“Setting preferences for the EGL debugger” on page 604
This topic tells you how to change your preferences for the EGL debugger.
“Stepping through an application in the EGL debugger” on page 575
This topic offers guidance on the basic steps of debugging a program in the
EGL debugger.
“Creating a launch configuration in the EGL debugger” on page 588

574 EGL Programmer’s Guide


Setting the default build descriptors
Related reference
helpKey
remoteComType in callLink element
sqlDB
getVAGSysType()
systemType
sqlDataCode
sqlID
sqlPassword
sqlJNDIName
validationBypassKeys

Stepping through an application in the EGL debugger


This topic offers guidance on the basic steps of debugging a program in the EGL
debugger.

Strategies for debugging an application are beyond the scope of this


documentation, but in general the heart of the debugging process is identifying the
source of a problem in the code. For example, if your program ends abnormally,
you can use the debugger to step through the code and find the point at which the
program fails. If the program gives unexpected output, you can use the debugger
to track the values of variables and find the point at which the output deviates
from the expected.

The debugger always starts debugging from a program part. If you want to debug
another logic part, such as a library, you must step into the other logic part from a
program. In some cases you might benefit from writing a simple program with no
other function than to call the logic part that you want to debug.

Prerequisites
v An EGL project
v An EGL program to debug

The following example provides a program with a simple error that you can use to
test the debugger:
program myDebugTestPgm type BasicProgram

function main()

//Provide some initial values for the array of items.


customerItems items[3];
customerItems[1].itemNumber=1;
customerItems[2].itemNumber=2;
customerItems[3].itemNumber=3;
customerItems[1].itemCost=12.50;
customerItems[2].itemCost=200;
customerItems[3].itemCost=49.95;
customerItems[1].itemQuantity=30;
customerItems[2].itemQuantity=10;
customerItems[3].itemQuantity=60;

counter int;
orderTotal float=0;

Debugging EGL applications 575


//Calculate the total cost of the items.
//Use the discountPrice function to get the discounted cost of each item.
for (counter from 1 to customerItems.getSize() by 1)
orderTotal += discountPrice(customerItems[counter].itemCost,
customerItems[counter].itemQuantity);
end // for loop

//Write the output to the console.


SysLib.writeStderr("The total cost for the order is $" + orderTotal);
end // main

//Return a total price for a group of items


//based on the item price and a quantity discount.
function discountPrice(itemCost float in, itemQuantity int in) returns(float)
discountRate float=0;
quantCost float=0;

//Determine the discount for each quantity.


//Discount 20% for more than 50 items.
//Discount 5% for more than 20 items.
case
when (itemQuantity > 50)
discountRate = 1/5;
when (itemQuantity > 20 && itemQuantity <= 50)
discountRate = 1/20;
otherwise
//bug - division by zero
discountRate = 1/0;
end

//Multiply the cost of the item, the number of items,


//and the discounted price.
quantCost = itemCost*itemQuantity*(1-discountRate);
quantCost = MathLib.round(quantCost, -2);

return (quantCost);
end // function discountPrice

end // program

record items type BasicRecord


itemNumber int;
itemCost float;
itemQuantity int;
end

If you generate this program and run it, EGL will return an error pointing to the
discountPrice function and the expression 1/0. In this case, the error is easy to
see, but in other cases you might not be able to find the error so easily. Your first
step in identifying the source of the error might be to run the program in the
debugger with breakpoints to find where the program fails.

Adding breakpoints

You can mark one or more lines of code as breakpoints. When the debugger
encounters a breakpoint, it pauses before running the associated line of code. You
then have the option of checking the current values of program variables before
telling the debugger how to proceed. Breakpoints do not affect the generated
source in any way; they are meaningful only during the debugging process.

To add a breakpoint, double-click the gray margin to the left of the code in the
EGL editor. In the previous example, you might want to add breakpoints
throughout the discountPrice function because the error tells you that this
576 EGL Programmer’s Guide
function is where the error occurred. Breakpoints are marked with blue circles in
this gray area:

You can add a breakpoint at most lines of EGL code that conduct logic, including
the following examples:
v An assignment statement, such as:
myString = "Hello";
v A variable declaration that includes an assignment, such as:
myInt int = 5;
v A call to a system function or other EGL function, such as:
SysLib.writeStderr("Hello");
v A loop or comparison statement, such as:
if (myInt == 5)

However, you cannot add breakpoints at the following lines of code:


v A variable declaration that does not include an assignment.
v An end statement.
v A line of code that begins with function, or that begins with program, package,
or any other line that declares a logic part. However, you can set a preference to
have the debugger treat the first line of each program as though it contained a
breakpoint. See “Setting preferences for the EGL debugger” on page 604.
v Any line within a data part.
v A blank line or a line that consists only of a comment.

For more instructions on using breakpoints, see “Using breakpoints in the EGL
debugger” on page 584.

You can debug a program without using breakpoints. If you check the preference
Window → Preferences → EGL → Debug → Stop at first line of a program, it has the
same effect as setting a breakpoint at the first executable line inside the main()
function of the program. From this point you can step through or around
succeeding lines of code, that is, execute a single line and pause. For more on the
step commands, see “EGL debugger commands” on page 580.

Debugging EGL applications 577


Running a program in the EGL debugger

After you have added breakpoints to your program, or set the Stop at first line
option (see ″Adding breakpoints″ earlier in this topic), you can run it in the
debugger.

The debugger requires a launch configuration to describe how it will run the
application. There are two ways to create a launch configuration:
v Have the debugger to create a launch configuration automatically when you
start debugging.
v Create a launch configuration manually. See “Creating a launch configuration in
the EGL debugger” on page 588 for more information.
For most programs, you can use the automatically created launch configuration.
1. In the Project Explorer view, right-click the EGL source program that you want
to debug and then click Debug EGL Program. The debugger performs the
following tasks:
v If no launch configuration exists for the program, the debugger creates a
default launch configuration. You can view this configuration by clicking
Run → Debug.
v Depending on your workbench preferences, the debugger might switch to
the Debug perspective automatically or prompt you to do so. You can switch
perspectives manually by clicking Window → Open Perspective → Other →
Debug.
v The debugger begins running the program.
2. After the debugger has started running the program, it continues until it
encounters a breakpoint, or, if you have set the preference for it, finds the first
line of executable code. At this point, the debugger pauses and displays the
following information:
v The EGL editor highlights the line about to be executed.
v The Variables view shows the value of all the variables in the current logic
part, including the value of system variables. You can use this view to track
the value of a variable through the program. You can also change the value
of a variable while the debugger is paused at a breakpoint.
v The Debug view lists the threads running within the current run unit. In
simple terms, this view shows which program or logic part is currently
running. Use this view to resume or stop the debugging process.
v The Breakpoints view lists the breakpoints in the program. From this view,
you can disable a breakpoint temporarily by clearing its check box.
3. When you want the debugger to continue, click the Resume button at the top
of the Debug view. The debugger continues to the next breakpoint. You can
also use one of the Step buttons to see the program execute the next line and
pause again.
In the example program, you can run the program from breakpoint to
breakpoint until the debugger reaches the line discountRate = 1/0;, at which
point the debugger returns the same error that you see in the console when
running the program.
4. When you are finished debugging, click the Terminate button at the top of the
Debug view to stop the debugger or allow the program to finish running.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging

578 EGL Programmer’s Guide


“EGL debugger commands” on page 580
Debugger
Related tasks
“Setting preferences for the EGL debugger” on page 604
This topic tells you how to change your preferences for the EGL debugger.
“Creating a launch configuration in the EGL debugger” on page 588
“Starting a non-JEE application in the EGL debugger” on page 590
“Using breakpoints in the EGL debugger” on page 584
This topic shows you how to use breakpoints in debugging your programs. You
can manage breakpoints inside or outside of an EGL debugging session.
“Viewing variables in the EGL debugger” on page 585
This topic shows you how to view variables in your program while your are
debugging your programs.

Debugging an EGL batch program


If you are working on a batch program that you intend to deploy in a J2EE
context, you can use the launch configuration to debug the program in a non-J2EE
context. Although the setup is straightforward, you need to adjust some values:
1. Set the value of the J2EE build descriptor option to NO when you use the
launch configuration.
2. Adjust Java property values to conform to differences in accessing a relational
database:
v For J2EE, specify a string like jdbc/MyDB, which is the name to which a data
source is bound in the JNDI registry. You can specify that string in the
following ways:
– By setting the sqlJNDIName build descriptor option; or
– By placing a value in the EGL SQL Database Connections preference page,
in the Connection JNDI Name field; for details, see “Setting preferences
for SQL database connections” on page 219.
v For non-J2EE, specify a connection URL like jdbc:db2:MyDB. You can specify
that string in the following ways:
– By setting the sqlDB build descriptor option; or
– By placing a value in EGL SQL Database Connections preference page, in
the field Connection URL. For details, see “Setting preferences for SQL
database connections” on page 219.

For information on EGL debugger commands, see “EGL debugger commands” on


page 580. For more information on how build descriptor settings affect the EGL
debugger, see “How build descriptor settings affect the EGL debugger” on page
583. For information on Secondary Authentication ID, see “Secondary
Authentication ID” on page 220.
Related concepts
VisualAge Generator compatibility
“Character encoding options for the EGL debugger” on page 603
“EGL debugger commands” on page 580
Related tasks
“Setting preferences for SQL database connections” on page 219
“Setting preferences for the EGL debugger” on page 604
This topic tells you how to change your preferences for the EGL debugger.

Debugging EGL applications 579


“Secondary Authentication ID” on page 220
“Stepping through an application in the EGL debugger” on page 575
This topic offers guidance on the basic steps of debugging a program in the
EGL debugger.
“Creating a launch configuration in the EGL debugger” on page 588
Setting the default build descriptors
Related reference
remoteComType in callLink element
sqlDB
getVAGSysType()
systemType
sqlID
sqlPassword
sqlJNDIName

EGL debugger commands


You can use the following commands to interact with the EGL debugger:
Add breakpoint
Identifies a line at which processing pauses. When code execution pauses,
you can examine variable values, as well as the status of files and screens.
Breakpoints are carried from one debugging session to the next, unless you
remove the breakpoint. You cannot set a breakpoint at a blank line or at a
comment line.
Disable breakpoint
Inactivates a breakpoint, but does not remove it.
Enable breakpoint
Activates a breakpoint that was previously disabled.
Remove breakpoint
Clears the breakpoint so that processing no longer automatically pauses at
the line.
Remove all breakpoints
Clears every breakpoint.
Run Runs the code until the next breakpoint, or until the run unit ends. In any
case, the debugger stops at the first statement in the main function.
Run to line
Runs all statements up to, but not including, the statement on a specified
line. This command is not available in Rich UI debugging.
Jump to line
Right-clicking the gray border to the left of a line of code and then clicking
this option repositions the debugger at that line. You can jump only to a
line in a function that is part of the currently active stack; that is, the
function that you are in currently or a function that has called the current
function. This command is not available in Rich UI debugging.
Step into
Runs the next EGL statement and pauses.
The following list indicates what happens if you issue the command step
into for a particular statement type:
580 EGL Programmer’s Guide
call Stops at the first statement of a called program if the called
program runs in the EGL debugger. Stops at the next statement in
the current program if the called program runs outside of the EGL
debugger.
The EGL debugger searches for the receiving program in every
project in the workbench.
converse
Waits for user input. That input causes processing to stop at the
next running statement, which might be in a validator function.
forward
If the code forwards to a JSF Handler, the debugger waits for user
input, and then stops at the next running statement, which might
be in a validator function. If the code forwards to a program, the
debugger stops at the first statement in that program.
function invocation
Stops at the first statement in the function.
show, transfer
Stops at the first statement of the program that receives control in a
transfer. The target program is EGL source code that runs in the
EGL debugger, but is not generated by EGL.
After either a show statement or a transfer to transaction
statement, the behavior of the EGL debugger depends on the
debugger mode:
v In Java mode, the EGL debugger switches to the build descriptor
for the new program or, (if no such build descriptor is in use,
prompts the user for a new build descriptor. The new program
can have a different set of properties from the program that ran
previously.
v In COBOL mode, the build descriptor for the previous program
remains in use, and the new program cannot have a different set
of properties.
The EGL debugger searches for the receiving program in every
project in the workbench.
Step over
Runs the next EGL statement and pauses, but does not stop within
functions that are invoked from the current function.
The following list indicates what happens if you issue the command step
over for a particular statement type:
converse
Waits for user input and then skips any validation function (unless
a breakpoint is in effect). Stops at the statement that follows the
converse statement.
forward
If the code forwards to a JSF Handler, the debugger waits for user
input and stops at the next running statement, but not in a
validator function, unless a breakpoint is in effect.
If the code forwards to a program, the debugger stops at the first
statement in that program.

Debugging EGL applications 581


show, transfer
Stops at the first statement of the program that receives control.
The target program is EGL source code that runs in the EGL
debugger, but is not generated by EGL.
After either a show statement or a transfer to transaction
statement, the behavior of the EGL debugger depends on the
debugger mode:
v In Java mode, the EGL debugger switches to the build descriptor
for the new program or, if no such build descriptor is in use,
prompts the user for a new build descriptor. The new program
can have a different set of properties from the program that ran
previously.
v In COBOL mode, the build descriptor for the previous program
remains in use, and the new program cannot have a different set
of properties.
The EGL debugger searches for the receiving program in every
project in the workbench.
Step return
Runs the statements needed to return to an invoking program or function,
then pauses at the statement that receives control in that program or
function.
The step return command in a validator function is an exception. In that
case, the behavior is identical to that of a step into command, which
primarily means that the EGL debugger runs the next statement and
pauses.

The EGL debugger ignores the following EGL system functions:


v sysLib.audit()
v sysLib.purge()
v vgLib.startTransaction()

You can add a breakpoint at these statements, for example, but a step into
command merely continues to the subsequent statement, with no other effect.

Finally, if you issue the command step into or step over for a statement that is the
last one running in the function (and if that statement is not return, exit program,
or exit stack), processing pauses in the function itself so that you can review
variables that are local to the function. To continue the debug session in this case,
issue another command.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging
Related tasks
“Creating a launch configuration in the EGL debugger” on page 588
“Stepping through an application in the EGL debugger” on page 575
This topic offers guidance on the basic steps of debugging a program in the
EGL debugger.
“Using breakpoints in the EGL debugger” on page 584
This topic shows you how to use breakpoints in debugging your programs. You
can manage breakpoints inside or outside of an EGL debugging session.

582 EGL Programmer’s Guide


How build descriptor settings affect the EGL debugger
A build descriptor helps to determine some aspects of the debugging environment.
For example, the system build descriptor option determines which mode the EGL
debugger will run in. The debugger has three modes, JavaScript (for Rich UI), Java,
and COBOL; if you set the system type to DEBUG, then the mode is set to Java
automatically. The mode controls how the debugger acts in situations where the
EGL runtime behavior differs for JavaScript, Java, and COBOL output.

For details on Rich UI, see Rich UI debugging. Otherwise, the EGL debugger selects
the build descriptor in accordance with the following rules:
v If you specified a debug build descriptor for your program or JSF Handler, the
EGL debugger uses that build descriptor. For details on how to establish the
debug build descriptor, see Setting the default build descriptors.
v If you did not specify a debug build descriptor, the EGL debugger prompts you
to select from a list of your build descriptors.
v If the build descriptor you specified lacks any required database-connection
information, the EGL debugger gets the connection information by reviewing
your preferences. For details on how to set those preferences, see “Setting
preferences for SQL database connections” on page 219.

If you are debugging a program that you intend for use in a text or batch
application in a Java environment, and if that program issues a transfer statement
that switches control to a program that you also intend for use in a different run
unit in a Java environment, the EGL debugger uses a build descriptor that is
assigned to the receiving program. The choice of build descriptor is based on the
rules described earlier.

If you are debugging a program that is called by another program, the EGL
debugger uses the build descriptor that is assigned to the called program. The
choice of build descriptor is based on the rules that are described earlier, except
that if you do not specify a build descriptor, the debugger does not prompt you for
a build descriptor when the called program is invoked; instead, the build
descriptor for the calling program remains in use.

Note: You must use a different build descriptor for the caller and the called
program if one of those programs (but not both) uses VisualAge Generator
compatibility. The generation-time status of VisualAge compatibility is
determined by the value of the vagCompatibility build descriptor option.

A build descriptor or resource association part that you use for debugging code
might be different from the one that you use for generating code. For example, if
you intend to access a VSAM file from a program that is written for a COBOL
environment, you are likely to reference a resource association part in the build
descriptor. The resource association part must refer to the runtime target system
(for example, zOS) and must refer to a file type (for example, vsamrs) that is
appropriate for the target system. The debug situation differs from the generation
situation as follows:
v At generation time, the resource association part indicates the system name of
the file that is used in the target environment.
v At debug time, the system name must reflect another naming convention, as
appropriate when you access a remote VSAM file from an EGL-generated Java
program on Windows 2000, NT, or XP; for details on that naming convention,
see your VSAM support documents.

Debugging EGL applications 583


System type used at debug time

In addition to the system build descriptor option, a value for system type can be
set in sysVar.systemType. Also, a second value is available in
vgLib.getVAGSysType if you requested development-time compatibility with
VisualAge Generator).

The value in sysVar.systemType is the same as the value of the system build
descriptor option, except that the value is DEBUG in either of two cases:
v You select the preference Set systemType to DEBUG, as mentioned in “Setting
preferences for the EGL debugger” on page 604; or
v You specified NONE as the build descriptor to use during the debugging
session, regardless of the value of that preference.

The vgLib.getVAGSysType system function returns the VisualAge Generator


equivalent of the value in sysVar.systemType. For details, see the table in
getVAGSysType().
Related concepts
VisualAge Generator compatibility
“Debugging EGL applications” on page 573
Rich UI debugging
Related tasks
“Setting preferences for SQL database connections” on page 219
“Setting preferences for the EGL debugger” on page 604
This topic tells you how to change your preferences for the EGL debugger.
“Creating a launch configuration in the EGL debugger” on page 588
Setting the default build descriptors

Using breakpoints in the EGL debugger


This topic shows you how to use breakpoints in debugging your programs. You
can manage breakpoints inside or outside of an EGL debugging session.

Prerequisites
v An EGL project
v An EGL program or other logic part that needs debugging

Breakpoints are used to pause the execution of a program in the debugger. You can
manage breakpoints inside or outside of an EGL debugging session. Keep the
following in mind when working with breakpoints:
v A blue marker in the left margin of the Source view indicates that a breakpoint
is set and enabled.
v A white marker in the left margin of the Source view indicates that a breakpoint
is set but disabled.
v The absence of a marker in the left margin indicates that a breakpoint is not set.

Adding or removing a breakpoint

To add or remove a single breakpoint in an EGL source file you can do either of
the following:
v Position the cursor at the breakpoint line in the left margin of the Source view
and double-click.

584 EGL Programmer’s Guide


v Position the cursor at the breakpoint line in the left margin of the Source view
and right-click. A menu opens. Click either Add or Remove (The Remove option
is only there if a breakpoint is already set).

Disabling or enabling a breakpoint

To disable or enable a single breakpoint in an EGL source file, follow these steps:
1. In the Breakpoint view, right-click on the breakpoint. A menu opens.
2. Click either Enable or Disable.

Remove all breakpoints

To remove all breakpoints from an EGL source file, follow these steps:
1. Right-click any breakpoint that is displayed in the Breakpoints view. A menu
opens.
2. Click Remove All.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging
Related tasks
“Creating a launch configuration in the EGL debugger” on page 588
“Starting a non-JEE application in the EGL debugger” on page 590
“Stepping through an application in the EGL debugger” on page 575
This topic offers guidance on the basic steps of debugging a program in the
EGL debugger.
“Viewing variables in the EGL debugger”
This topic shows you how to view variables in your program while your are
debugging your programs.

Viewing variables in the EGL debugger


This topic shows you how to view variables in your program while your are
debugging your programs.

Prerequisites
v An EGL project
v An EGL program or other logic part that needs debugging

Variables and breakpoints


When you are debugging a program, you will probably have the debugger stop or
pause at certain points in your program (see “Using breakpoints in the EGL
debugger” on page 584 for more information on using breakpoints to make the
debugger pause while debugging your program). Whenever a program is paused,
you can view the current values of the variables in the program.

Displaying and changing values


You typically use the Variable view to monitor the changing values of your
variables. To display their values, do one of the following:

Debugging EGL applications 585


v Click the Options button at the top of the view (the triangle), and then click
Layout and either Horizontal View or Vertical View. Also on the Options menu,
choose Detail pane. The Variables view will split into two panes, one showing
the current value of the variable.
v Click the Options button at the top of the view (the triangle), then click Layout →
Show Columns. If you do not see the Value column, choose Layout → Show
Columns → Value.

To change a value, right-click the value and choose the appropriate option from the
popup menu. The wording of the option varies depending on the context.

For more information, see ″Buttons in the Variables view″ in this topic.

Buttons in the Variables view


In the Variables view, expand the parts in the navigator to see the variables that
are associated with them. The Variables view provides the following buttons:
Show Type Names
This toggle displays or hides the types on which the variables are based.
This button is not available if you chose to show columns. In that case, you
can request a column that shows the variable type.
Show Logical Structure
Collapse All
This hides all the variable names and shows only the parts in the current
program.
[Options]
Click this downward pointing triangle icon to display a list of further
options:
Layout
The following layout options are available for the Variables view:
Vertical View Orientation
The detail pane is displayed below the variables.
Horizontal View Orientation
The detail pane is displayed to the right of the variables.
Variables View Only
This option closes the detail pane.
Show Columns
This option reformats the view in table form
Select Columns
This option is only available if you select Show Columns.
The following columns are available:
Name The name of the variable.
Declared Type
The original type of the variable.
Value The current value of the variable. Click this cell to
enter a new value for the variable, or right-click
and choose Change Value to display a window
where you can change the value.

586 EGL Programmer’s Guide


Actual Type
The actual type will differ from the declared type
only when the variable was originally ANY type
and took on another type through assignment.
Show All Jython Variables
This option does not apply to EGL.
Detail pane
This option opens a separate pane in the Variables view to display
the details of a highlighted variable. You can type a value for the
variable in this pane, highlight that value, right-click, and select
Assign Value to assign the value to the variable.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging
Related tasks
“Creating a launch configuration in the EGL debugger” on page 588
“Starting a non-JEE application in the EGL debugger” on page 590
“Configuring a server for EGL Web debugging” on page 592
“Using breakpoints in the EGL debugger” on page 584
This topic shows you how to use breakpoints in debugging your programs. You
can manage breakpoints inside or outside of an EGL debugging session.

Making code updates while debugging an application


The EGL debugger supports hotswapping, which means that the debugger processes
the code changes that you make as you step through an application. Hotswapping
lets you to test and modify your application at the same time. To take advantage of
this feature, set the Enable hotswapping EGL debug preference:
1. From the main menu, click Window → Preferences. The Preferences page is
displayed.
2. Expand EGL and click Debug. The Debug dialog box is displayed.
3. Click Enable hotswapping.
4. Click OK to save the changes and exit the page.

If hotswapping is enabled and you change a function that is on the function stack,
the debugging session continues at the first line of the changed function.

Compatibility
Table 57. Compatibility considerations for hot swapping
Platform Issue
Rich UI Hot swapping is not supported. Similarly, the EGL debugger
does not respond to changes made to variable values in the
Variables view.

Related concepts
“Starting the EGL debugger for EGL projects” on page 588
Start the debugging process by creating a launch configuration.
“EGL debugger commands” on page 580
Rich UI debugging
Related tasks

Debugging EGL applications 587


“Setting preferences for the EGL debugger” on page 604
This topic tells you how to change your preferences for the EGL debugger.
“Stepping through an application in the EGL debugger” on page 575
This topic offers guidance on the basic steps of debugging a program in the
EGL debugger.
“Creating a launch configuration in the EGL debugger”
Setting the default build descriptors

Starting the EGL debugger for EGL projects


Start the debugging process by creating a launch configuration.

To start the debugging process outside of Rich UI you need a launch configuration.
You can create a launch configuration yourself, but the EGL debugger creates one
automatically if you do not create one.

To start the EGL debugger and have it create a launch configuration for you, see
“Starting a non-JEE application in the EGL debugger” on page 590. To create a
launch configuration yourself, see “Creating a launch configuration in the EGL
debugger.” If you are debugging an EGL application that is called from an
EGL-generated Java application or Java wrapper, you must create a special kind of
launch configuration called an EGL Listener launch configuration. To create one,
see “Creating an EGL Listener launch configuration” on page 589.
Related concepts
Rich UI debugging
Related tasks
“Starting a non-JEE application in the EGL debugger” on page 590
“Creating a launch configuration in the EGL debugger”
“Creating an EGL Listener launch configuration” on page 589

Creating a launch configuration in the EGL debugger


To start debugging an EGL text program, non-JEE basic program, or Rich UI
handler in an EGL debugging session, you need to establish a launch
configuration. You can create a launch configuration yourself, or you can have the
EGL application create one for you automatically. In relation to automatic
configurations, see Starting a non-JEE application in the EGL debugger or Rich UI
debugging.

To start a program using a launch configuration that you create yourself, follow
these steps:
1. Click Run → Debug. The Debug window opens.
2. In the left pane of the Debug window, click EGL Program.
3. Click the New launch configuration at the top of that same pane. A new
launch configuration is displayed below the EGL Program heading. The
Launch tab is initially displayed.
4. In the Name field, type a name for the launch configuration. By default, the
launch configuration has the same name as the program, unless a
configuration already exists for this program.
5. In the Project field of the Load tab, type the name of your project.
6. In the EGL program source file field, select the program that you want to
debug.

588 EGL Programmer’s Guide


7. If you are debugging a called program that takes arguments, click the
Arguments tab. List the arguments for the program, in order, as you would in
a call statement.
8. If you need to use a different JRE than the default for this project, click the
JRE tab and complete the information there.
9. If you need additional Java classes to run the program, specify the paths for
those classes on the Classpath tab.
10. Add any needed source files on the Source tab.
11. To set environment variables for the duration of the debug session only, type
the names and values on the Environment tab.
12. Click Apply to save the launch configuration settings.
13. Click Debug to launch the program in the EGL debugger.

Note: If you have not yet clicked Apply to save the launch configuration settings,
clicking Revert will remove all changes that you have made.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging
Related tasks
“Starting a non-JEE application in the EGL debugger” on page 590
“Stepping through an application in the EGL debugger” on page 575
This topic offers guidance on the basic steps of debugging a program in the
EGL debugger.
“Using breakpoints in the EGL debugger” on page 584
This topic shows you how to use breakpoints in debugging your programs. You
can manage breakpoints inside or outside of an EGL debugging session.
“Viewing variables in the EGL debugger” on page 585
This topic shows you how to view variables in your program while your are
debugging your programs.

Creating an EGL Listener launch configuration


To debug a non-JEE EGL application called from an EGL-generated Java
application or wrapper, an EGL Listener launch configuration is required. To create
an EGL Listener launch configuration, do as follows:
1. Click the arrow next to the Debug button on the toolbar, then click Debug, or
select Debug from the Run menu.
2. The Debug dialog box is displayed.
3. Click EGL Listener in the Configurations list, then click the New launch
configuration button.
4. The Listener launch configuration is named New_configuration. If you want to
change the name of the launch configuration, type the new name in the Name
field.
5. If you do not type a port number, the port defaults to 8346; otherwise, type a
port number. Each EGL Listener requires its own port.
6. If you are debugging a called program that takes arguments, click the
Arguments tab. List the arguments for the program, in order, as you would in
a call statement.
7. If you need to use a different JRE than the default for this project, click the
JRE tab and complete the information there.

Debugging EGL applications 589


8. If you need additional Java classes to run the program, specify the paths for
those classes on the Classpath tab.
9. Add any needed source files on the Source tab.
10. To set environment variables for the duration of the debug session only, type
the names and values on the Environment tab.
11. Click Apply to save the Listener launch configuration.
12. Click Debug to launch the EGL Listener.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging
Related tasks
“Creating a launch configuration in the EGL debugger” on page 588
“Starting a non-JEE application in the EGL debugger”
“Stepping through an application in the EGL debugger” on page 575
This topic offers guidance on the basic steps of debugging a program in the
EGL debugger.
“Viewing variables in the EGL debugger” on page 585
This topic shows you how to view variables in your program while your are
debugging your programs.
“Using breakpoints in the EGL debugger” on page 584
This topic shows you how to use breakpoints in debugging your programs. You
can manage breakpoints inside or outside of an EGL debugging session.

Starting a non-JEE application in the EGL debugger


To start debugging an EGL text program or non-JEE basic program in an EGL
debugging session, a launch configuration is required. A launch configuration
specifies the location of a program on disk and specifies how the program must be
launched. You can let the EGL application create the launch configuration (implicit
creation), or you can create one yourself (see “Creating a launch configuration in
the EGL debugger” on page 588).

To launch a program using an implicitly created launch configuration, do as


follows:
1. In the Project Explorer view, right-click the EGL source file that you want to
launch. Alternatively, if the EGL source file is open in the EGL editor, you can
right-click the program in the Outline view. A menu opens.
2. Click Debug EGL Program. A launch configuration is created, and the program
is launched in the EGL debugger.

To view the implicitly created launch configuration, do as follows:


1. Click the arrow next to the Debug button on the toolbar. A pop-up menu
displays.
2. Click Debug. The Debug dialog displays. The name of the launch configuration
is displayed in the Name field. Implicitly created launch configurations are
named according to the project and source file names.

Note: You can also display the Debug dialog by clicking Run → Debug.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging

590 EGL Programmer’s Guide


Related tasks
“Creating a launch configuration in the EGL debugger” on page 588
“Stepping through an application in the EGL debugger” on page 575
This topic offers guidance on the basic steps of debugging a program in the
EGL debugger.
“Using breakpoints in the EGL debugger” on page 584
This topic shows you how to use breakpoints in debugging your programs. You
can manage breakpoints inside or outside of an EGL debugging session.
“Viewing variables in the EGL debugger” on page 585
This topic shows you how to view variables in your program while your are
debugging your programs.

Invoking the EGL debugger from generated Java code


You can invoke the EGL debugger from an EGL-generated Java program or
wrapper, so you can use the EGL debugger when you work on a partly deployed
application. The program needs a call statement that you then associate with the
callLink element of a linkage options part. Similarly, you must associate the
wrapper with a callLink element. In either case, the element must specify the
remoteComType property as DEBUG.

Programs running in JEE

To invoke the EGL debugger from an EGL-generated program or wrapper that


runs in JEE, follow these steps:
1. Make sure you have added a linkage options part to your build file. For
instructions on how to do this, see Adding a linkage options part to an EGL
build file.
2. Edit the callLink element to include the remoteComType property. To edit the
callLink element, see Editing the callLink element of a linkage options part. For
details on setting the remoteComType property, see remoteComType in callLink
element.
3. Make sure that the program to be debugged is running in the same server as
its caller.
4. Add the EGL debugger JAR files to the server. Make sure the server is running
in debug mode.
5. Run the program in the debugger.

Programs not running in JEE

Different rules apply when the called program to be debugged does not run in JEE.
When this is the case, the caller of the program might be running anywhere,
including on a remote system. Follow these steps:
1. Start a listener program. Start a listener by using an EGL Listener launch
configuration that has only one configurable setting, a port number. The default
port number is 8346.
2. If multiple EGL Listeners are running at the same time, you must specify a
different port for each EGL Listener. You might also need to specify a different
port if port 8346 is being used by another application or if a firewall prevents
use of that port. To specify a different port number, see “Creating an EGL
Listener launch configuration” on page 589.
Related tasks

Debugging EGL applications 591


“Creating an EGL Listener launch configuration” on page 589

Debugging Web projects with the EGL debugger


Use the EGL debugger to debug Web projects.

Before you can debug an EGL Web application, you must configure the server for
debugging. This needs to be done only once; see Configuring a server for EGL
debugging. This process will restart the server in Debug mode. To begin debugging,
see Starting an EGL Web debugging session.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging
Related tasks
“Configuring a server for EGL Web debugging”
“Starting an EGL Web debugging session” on page 594

Configuring a server for EGL Web debugging


Before you can debug EGL Web applications, you must configure the server for
EGL debugging. You need to do this configuration step only once per server. If you
use Tomcat, make sure that you request EGL debugging support at the time you
define the new server to EGL.

EGL Debug is the default debugging mode. If you want to debug generated Java
code rather than the EGL JSF handler, see ″Debugging Java code″ later in this
topic.

To configure a server for EGL debugging, do as follows:


1. In the Debug perspective, find or open the Server view (Window → Show View
→ Other → Server → Servers). The Status column of the display says
″Debugging″ when the server is running in EGL debug mode.
2. If Status column does not report ″Debugging,″ and the server is not running,
right click the server name and choose Debug from the pop-up menu. If the
server is running, right-click the server name and click Restart → Debug.
3. To take the server out of EGL debug mode, right-click the server name and
choose Restart → Start.

Debugging Java code


EGL assumes that you want the server to debug EGL JSF Handler parts. If you
want to debug generated Java code instead, you must set the egl.jsfhandler.debug
system property to FALSE. Do this by passing the property as a VM argument to
the server. Methods for doing this depend on which server you are running.

On Apache Tomcat, edit the VM arguments section of the launch configuration


(Run → Debug), as in the following figure:

592 EGL Programmer’s Guide


Restart the server for the property to take effect.

For IBM WebSphere Application Server, version 6.1, the process is more
complicated. Right-click the server name in the Server view and choose Run
administrative console. In the left menu pane of the Integrated Solutions Console,
expand Servers, and click Application servers. The console displays a list of
servers; click yours. On the Configuration tab of the next page, the last group of
options is headed Additional Properties. Under this heading, click Debugging
Service. On the Debugging Service page, add the following (with a space
afterwards) to the beginning of the string in JVM debug arguments:
-Degl.jsfhandler.debug=false

That area of the console looks like the following figure:

Debugging EGL applications 593


Click Apply to save your changes. The console will ask you if you want to Save or
Review your changes; click Save. Restart the server for the property to take effect.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging
Related tasks
“Starting an EGL Web debugging session”
“Stepping through an application in the EGL debugger” on page 575
This topic offers guidance on the basic steps of debugging a program in the
EGL debugger.

Starting an EGL Web debugging session


Before you follow the instructions in this topic, you must have generated each JSF
Handler that you want to debug at least once, as explained in “Debugging Web
projects with the EGL debugger” on page 592, and you must have started your
server in Debug mode (see “Configuring a server for EGL Web debugging” on
page 592).

To start debugging an EGL Web application, follow these steps:


1. In the Project Explorer for the EGL perspective, expand the
WebContent/WEB-INF folder for your project. Right-click the JSP file that you
594 EGL Programmer’s Guide
want to run and then select Debug As → Debug on Server from the pop-up
menu. EGL will change to the Debug perspective, deploy the application to the
server, and start the application.
2. Begin debugging the application. For an overview of this process, see “Stepping
through an application in the EGL debugger” on page 575.
3. As you find bugs and correct your EGL code, make sure that the debugger
picks up the changes and continues debugging with the updated code. The
easiest way to make the debugger use the updated code is to generate the parts
that you have changed, but you can also restart the server or restart the project
on the server.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging
Related tasks
“Configuring a server for EGL Web debugging” on page 592
“Stepping through an application in the EGL debugger” on page 575
This topic offers guidance on the basic steps of debugging a program in the
EGL debugger.

Debugging services with the EGL debugger


You can debug your local EGL services similarly to the way that you debug other
programs.

Prerequisites
You will need an EGL Service part, as well as a requester that has binding
information for accessing the service.

Note that before you can debug a Web service on WebSphere Application Server,
you must generate the service.

Debugging a local service


The simplest way to debug a service is to call it from a program in the same
project as the service. You can then pass test values to the service and inspect the
results.

Perform the following steps:


1. Create a new EGL source program.
2. In the program, declare a service variable that is based on the Service part that
you want to test.
3. Create a service client binding in the deployment descriptor as an EGL service
(not a Web service) with a ″local″ protocol. See “Calling a local service” on
page 483 for instructions.
4. Using the service client binding, bind the variable to the service with
{@BindService{bindingKey = "ServiceClientBindingName"}}.
5. In the main() function of the program, make at least one call to the service
using that variable. The easiest way is to hard code the input values in the
service call and write the output values to the console, as in the following
example:
program addTestProgram type BasicProgram

myAddingMachine additionService

Debugging EGL applications 595


{@BindService {bindingKey = "additionService"}};

function main()
sumint int;
sumint = myAddingMachine.addInts(5, 12);
SysLib.writeStdOut("result = " + sumint);
end
end
6. Set a breakpoint at the service call. See “Using breakpoints in the EGL
debugger” on page 584.
7. Set breakpoints in the service, as you would in any logic part.
8. Debug your new EGL source program. At the breakpoint before the service call,
step into the service code. The debugger pauses at the breakpoints in the
service just as in any other logic part.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging
Related tasks
“Calling a local service” on page 483
You can call an EGL or native service that is local to your application without
exposing that service as a Web service.
“Using breakpoints in the EGL debugger” on page 584
This topic shows you how to use breakpoints in debugging your programs. You
can manage breakpoints inside or outside of an EGL debugging session.
“Stepping through an application in the EGL debugger” on page 575
This topic offers guidance on the basic steps of debugging a program in the
EGL debugger.

Debugging IMS and DL/I applications


Debugging applications that run remote IMS programs or that access data from a
DL/I database requires configuration of both the host and the local workspace.

Debugging SQL and DL/I programs is available for IMS only. The debugger makes
database calls to the host, but otherwise interprets the code on the local client
system. For information on starting the debug server, see “Starting the DLI Debug
Server on the z/OS host” on page 601.

Prerequisites
The following applications are required on the host for debugging:
v TCPIP
v DB2 v.7 or higher
v IMS v.7 or higher
– Open Database Access (ODBA)
v Resource Recovery Services (RRS)
v Workload Manager (WLM)

The IMS debugger uses ODBA to talk to the database capabilities in IMS.
RRS/MVS (Resource Recovery Services) is required; OS/390® Release 3 is the
minimum level that can support the ODBA interface.

596 EGL Programmer’s Guide


Host configuration
The following areas need to be configured on the host system:
v DRA (Database Resource Adapter) Startup Table (ELADRA)
v WLM (Workload manager) (ELADBWLM)
v DB2 stored procedure (EZESP1CR and EZESP1GR)
v Proxy startup JCL (ELADBGPX)
v Debug server startup JCL (ELADBGRN)
Sample files are provided; the member names are shown above inside parentheses.
All JCL and SQL samples are located in the COBOL runtime in
ELA.V6R0M1.SELAJCL and ELA.V6R0M1.SELASAMP, respectively.

The source files in this section are available as part of the Rational COBOL
Runtime for zSeries package.

DRA Startup Table


The following table lists the changes you need to make to the ELADA.JCL file.
Table 58. Changes to ELADRA.JCL
From To
Add a jobcard
SYSLIB Modify to match your system configuration.
#dbctlid Replace #dbctlid with the DB control id for your
database. This value also goes into the imsID build
descriptor option.

The value comes from the JCL that you use to start
IMS. The IMS JCL parameter should look like this:
IMSID XXXX IMS SUBSYSTEM IDENTIFIER

In this example, XXXX represents the DB control id.


IMS.SDFSRESL The PDS SDFSRESL for your system.
MAXTHRD=99 Replace 99 with the max number of simultaneous
debug sessions (the minimum is 3).
CNBA=0 (FPBUF+FPBOF)*MAXTHREAD **
FPBUF=0 FPBUF is the number of buffers to be allocated to
each thread for FP use. **
FPBOF=0 FPBOF is the number of buffers and overflow
buffers to be allocated to each thread for FP use. **
TIMEOUT=60 Set the TIMEOUT startup parameter as high as
possible, preferably longer than longest running
UOR.
AGN=IVP See IMS 7 Administration Guide System for
information on configuring IMS security.
//SYSLMOD DD Replace ELA.V6ROM1.SELADBGL with the PDS
DSN=ELA.V6ROM1.SELADBGL where you want the DRA startup to reside.
NAME DFSIVP10(R) Replace DFSIVP10 with DFS followed by #dbctlid
from above.

Debugging EGL applications 597


//ASM EXEC PGM=IEV90,
// PARM='DECK,NOOBJECT,LIST,XREF(SHORT),ALIGN',
// REGION=4096K
//SYSLIB DD DSN=IMS.OPTIONS,DISP=SHR
// DD DSN=IMS.SDFSMAC,DISP=SHR
// DD DSN=SYS1.MACLIB,DISP=SHR
//SYSUT1 DD UNIT=SYSDA,SPACE=(1700,(400,400))
//SYSUT2 DD UNIT=SYSDA,SPACE=(1700,(400,400))
//SYSUT3 DD UNIT=SYSDA,SPACE=(1700,(400,400))
//SYSPUNCH DD DSN=&&OBJMOD;,
// DISP=(,PASS),UNIT=SYSDA,
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=400),
// SPACE=(400,(100,100))
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
PZP TITLE 'DATABASE RESOURCE ADAPTER STARTUP PARAMETER TABLE'
DFSIVP10 CSECT
**********************************************************************
* MODULE NAME: DFSIVP10 *
* DESCRIPTIVE NAME: DATABASE RESOURCE ADAPTER (DRA) *
* STARTUP PARAMETER TABLE. *
* FUNCTION: TO PROVIDE THE VARIOUS DEFINITIONAL PARAMETERS *
* FOR THE COORDINATOR CONTROL REGION. THIS *
* MODULE MAY BE ASSEMBLED BY A USER SPECIFYING *
* THEIR PARTICULAR NAMES, ETC. AND LINKEDITED *
* INTO THE USER RESLIB AS DFSPZPXX. WHERE XX *
* IS EITHER 00 FOR THE DEFAULT, OR ANY OTHER ALPHA- *
* NUMERIC CHARACTERS. *
**********************************************************************
EJECT
DFSPRP DSECT=NO, X
DBCTLIB=#dbctlid, X
DDNAME=, X
DSNAME=IMS.SDFSRESL, X
MAXTHRD=99, X
MINTHRD=2, X
TIMER=60, X
USERID=, X
CNBA=10, X
FPBUF=5, X
FPBOF=3, X
TIMEOUT=60, X
SOD=A, X
AGN=IVP
END
//LNKEDT EXEC PGM=IEWL,
// PARM='LIST,XREF,LET,NCAL'
//SYSUT1 DD UNIT=SYSDA,SPACE=(1024,(100,50))
//SYSPRINT DD SYSOUT=*
//SYSLMOD DD DSN=ELA.V6R0M1.SELADBGL,DISP=SHR
//SYSLIN DD DISP=(OLD,DELETE),DSN=&&OBJMOD;
// DD DDNAME=SYSIN
//SYSIN DD *
NAME DFSIVP10(R)

Workload manager
You must create a dedicated WLM for IMS debugging. In the JCL, change the
STEPLIB to match your system configuration:
//ELADBWLM PROC RGN=0K,APPLENV=ELADBWLM,DB2SSN=#db2ssn,NUMTCB=8
//*
//SYMBOLS INCLUDE MEMBER=$INCLUDE
//*
//IEFPROC EXEC PGM=DSNX9WLM,REGION=&RGN;,TIME=NOLIMIT,DYNAMNBR=10,
// PARM='&DB2SSN;,&NUMTCB;,&APPLENV;'
//STEPLIB DD DISP=SHR,DSN=#db2.SDSNEXIT
// DD DISP=SHR,DSN=#db2.SDSNLOAD

598 EGL Programmer’s Guide


// DD DISP=SHR,DSN=#cee.SCEERUN
// DD DISP=SHR,DSN=ELA.V6R0M1.SELALMD
// DD DISP=SHR,DSN=#cobol.SIGYCOMP
// DD DISP=SHR,DSN=&HLQTCP..SEZATCP;
//ELAPRINT DD SYSOUT=*
//SYSTSPRT DD SYSOUT=*
//CEEDUMP DD SYSOUT=*
//SYSMDUMP DD SYSOUT=*
//SYSABEND DD DUMMY
//********************************************************************
//* WORKFILES FOR COMPILERS AND BINDER
//********************************************************************
//SYSUT1 DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT2 DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT3 DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT4 DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT5 DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT6 DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT7 DD UNIT=SYSDA,SPACE=(CYL,(1,1))

Stored procedure definition


You need a SQL stored procedure to access a database on the host for EGL
debugging. SQL for creating the stored procedure and granting access to all users
can be found with the EGL runtime samples PDS.

The stored procedure EZESP1CR.sql makes a DL/I database available to the


debugger:
CREATE PROCEDURE schema.EZESP1 ( IN VAR01 SMALLINT,
IN VAR02 INT,
INOUT VAR03 VARCHAR(32672) FOR BIT DATA,
INOUT VAR04 VARCHAR(32672) FOR BIT DATA )
EXTERNAL NAME EZESP1
LANGUAGE COBOL
PARAMETER STYLE GENERAL
NOT DETERMINISTIC
COLLID collid
WLM ENVIRONMENT eladbwlm
RUN OPTIONS 'ALL31(OFF) STACK(,,BELOW)'

Change the placeholders to values that are appropriate to your system:


schema The schema where the stored procedure is to be installed.
collid The collection ID for your system.
eladbwlm
The name of the workload manager that you specified earlier.

The stored procedure EZESP1GR.sql grants all users access to EZESP1CR.sql:


GRANT EXECUTE ON PROCEDURE schema.EZESP1 TO PUBLIC

Local workspace configuration


Take the following actions in your local workspace to enable remote debugging:
v In Window → Preferences → EGL → Debug, uncheck the option Set systemType
to DEBUG. This will force EGL to use the systemType from the build descriptor
option.
v You must have JDBC on the client system. The actual .jar files you need depend
on the version of JDBC that you are running.
v Make sure you have a functioning default JDBC DB2 connection to the host; the
EGL debugger uses this connection to access DL/I.

Debugging EGL applications 599


v If you access a DB2 database in both the debugged code and in a called
program, the Default JDBC connection must be set to NOAUTOCOMMIT.
v Set the imsID build descriptor option to the CHAR(4) name of your IMS
subsystem.
v Make sure you have a preference page for IMS DLI under Window →
Preferences → EGL → Debug. If not, go to Window → Preferences → General →
Capabilities and click Advanced. In the Advanced window, expand EGL
Developer and select the EGL DLI check box. Close and reopen the Preferences
window to see the IMS DLI debug page.
v On the IMS DLI debug preferences page (see previous step), enter the following
information
StoredProcedureSchema
The schema that contains the stored procedure.
HostPort
The number of the port where the debugger server is listening.
ConversionTable
Defines the language of the host. This is the same table used in call
linkage conversion.
ProxyIdleTimeout
The amount of time the proxy will sit idle (no DLI activity) before the
debugger server tells it to abort. This should be long enough to allow for
processing time, but short enough that you don’t use up all available
processes in case the connection drops repeatedly.
PSB Name
Three options are available:
dliLib.psbData
The default for CICS. The program still uses a DL/I property for
transaction commit/rollback determination, but the PSB name
comes from the psbData record in dliLib.
Main program
The default for IMS. This is either the value of the alias property
(if used), or the program name. This value is folded to upper
case.
Prompt
At the start of each debug session, the user is prompted to enter
the PSB name used to access DL/I data. With the ODBA
interface, the PCB must be named and must match at PCB in the
PSB defined either in the program for IMS or in dliLib.psbData
for CICS.
v If you run called programs on the host, go to Window → Preferences → EGL →
Debug → Debug Behavior Mapping → Called program mapping. For each called
program that performs database access (DL/I or SQL) add an entry and set
mapping mode to IMS debug.
Related concepts
“Debugging EGL applications” on page 573
“How build descriptor settings affect the EGL debugger” on page 583
“Starting the DLI Debug Server on the z/OS host” on page 601

600 EGL Programmer’s Guide


Starting the DLI Debug Server on the z/OS host
On z/OS, you can configure the debug server to debug IMS DLI.

Syntax
You start a debug server by using z/OS JCL commands. The syntax for the
parameters line is as follows:

// PARM = ' -p portno


-a 0
-V

'
-n n -q q -t

where
-p Specifies the port number (portno) to which the server listens to communicate
with the clients.
-V Specifies the verbosity level of the server. You may specify this parameter up
to three times (maximum verbosity).
-a Specifies authentication mode:
0 Server state: A or U (unauthorized). If U, APF-authorized build
programs will fail. If you specify a TSO user ID and password, the
server ignores them and the build transaction is performed under the
access and authority of the user ID assigned to the build server job.
-n Specifies the number of concurrent builds. The default is 1. Set n equal to the
number of concurrent builds you want to allow. Once there are n number of
concurrent builds running, the build server queues any additional requests and
submits them on a first come first served basis as builds are completed.
-q Specifies the size of the queue (q) for clients. The default is 10. Each queued
client uses a TCP/IP socket. Therefore setting this too high may require more
sockets than are available, causing unpredictable results. If the queue is full,
subsequent clients are rejected by the server. However, the build client retries
the build in that case.
-t Starts tracing of this server job and writes output to STDOUT. This parameter
is normally used only for debugging.

Procedure
Modify the proxy job JCL to match your system configuration.

The JCL to start a proxy on the host is contained in the file named
EZEDBGPX.JCL. You must modify the STEPLIB portion of the JCL to match your
system configuration.
//jobcard
//*------------------------------------------------------
//RUNPGM EXEC PGM=EZEDBPXY,DYNAMNBR=30,TIME=NOLIMIT,
// PARM='&PARM;'
//* Avoid changing the PARM statement. The &PARM; keyword will
//* be replaced by parameters.
//STEPLIB DD DSN=ELA.V6R0M1.SELALMD,DISP=SHR
// DD DSN=ELA.V6R0M1.SELADBGL,DISP=SHR
// DD DSN=IMS.SDFSRESL

Debugging EGL applications 601


//*
//STDOUT DD SYSOUT=*
//STDERR DD SYSOUT=*
//CCUBLOG DD SYSOUT=*

To start a z/OS debug server, complete the following steps with the
ELADBGRN.JCL:
1. Add a job card.
2. Modify the parameters on the PARM statement of the EXEC card as necessary.
(See the parameter list above.)
3. Modify the STEPLIB DD statement to point to the data set that contains the
build server load modules. This library contains all the load modules that make
up the remote build server.
4. Modify the ELADBGP DD statement to point to the data set that contains the
JCL to run an individual debug proxy job.
5. 5. Modify the parameter (PARM=) statement as appropriate for your job (see
example below).
6. Submit the job.

Example
Following is an example of JCL that starts the debug server as a batch program for
IMS debugging:
//jobcard
//*------------------------------------------------------
//RUNPGM EXEC PGM=ELAMAIN,REGION=7400K,
// PARM='-p 5527 -a 0 -n 10 '
//STEPLIB DD DSN=ELA.V6R0M1.SELALMD,DISP=SHR
//ELADBGP DD DISP=SHR,DSN=ELA.V6R0M1.SELAJCL(ELADBGPX)
//STDOUT DD SYSOUT=*
//STDERR DD SYSOUT=*
//CCUBLOG DD SYSOUT=*

Special considerations for debugging


If you start the server on z/OS from an APF-authorized library (this is optional in
mode 0), the build script can specify an APF authorized program as the executable.

Note: In this case, the build script can also specify non-APF authorized programs.
However, in a multistep JCL script, an authorized program cannot be
executed after an unauthorized program.

If the server is not started from an APF-authorized library, the build script can
specify only non-APF authorized programs as executables.

Setting the language of messages returned from the build server


The debug server on z/OS returns messages in any of the languages listed in the
next table. English is the default.

Language Code
Brazilian Portugese ptb
Chinese, simplified chs
Chinese, traditional cht
English, USA enu
French fra
German deu

602 EGL Programmer’s Guide


Language Code
Italian ita
Japanese jpn
Korean kor
Spanish esp

To cause debug-server messages to be returned in a language other than English,


change the setting of environment variable CCU_LANG on the client machine. The
variable contains one of the language codes listed in the previous table. To return
messages in French, for example, set CCU_LANG to fra.

Also, the components that invoke the build server may need to issue messages if
communication with the build server fails. To return those messages in a language
other than English, change the setting of the environment variable
CCU_CATALOG on the client machine. The value of CCU_CATALOG is a string
like the following (on a single line):
shared_resources\eclipse\plugins
\com.ibm.etools.egl.distributedbuild_version\executables\ccu.cat.xxx
shared_resources
The shared resources directory for your product, such as C:\Program
Files\IBM\SDP70Shared on a Windows system or /opt/IBM/SDP70Shared on a
Linux system. If you installed and kept a previous version of an IBM product
containing EGL before installing your current product, you may need to
specify the shared resources directory that was set up in the earlier install.
version
The installed version of the plugin, including three numbers separated by
periods, a string separator, and the date and time that the plugin was built; for
example, 7.0.0.RFB_20070120_1300. If more than one is present, use the one
with the most recent version number, unless you have a reason to use an older
version.
xxx
The code for the language of interest; one of the codes listed in the previous
table
Related tasks
“Debugging IMS and DL/I applications” on page 596
Debugging applications that run remote IMS programs or that access data from
a DL/I database requires configuration of both the host and the local
workspace.

Character encoding options for the EGL debugger


When you use the EGL debugger outside of Rich UI, you can specify the type of
character encoding to use while debugging. Character encoding controls how the
debugger represents character and numeric data internally, how it compares
character data, and how it passes parameters to remote programs, files, and
databases. To change these options, see Setting preferences for the EGL debugger.

The EGL debugger supports two different types of character encoding: the default
encoding on your local system and Extended Binary Coded Decimal Interchange
Code (EBCDIC). The default character encoding for the EGL debugger is the same
as your local system’s default encoding.

Debugging EGL applications 603


v When the default character encoding is selected, the debugger represents CHAR,
DBCHAR, MBCHAR, DATE, TIME, INTERVAL, NUM, and NUMC variables in
the default format, typically ASCII. Comparisons between character variables use
the ASCII collating sequence. Data must be converted to host format when
calling remote programs and when accessing remote files and databases.
If you choose this setting and do not specify a conversion table, the debugger
chooses an appropriate conversion table when you call a remote program or
access a remote file or database. For more information on conversion tables, see
callConversionTable.
v When EBCDIC character encoding is used, the debugger represents CHAR,
DBCHAR, MBCHAR, DATE, TIME, and INTERVAL variables with EBCDIC
encoding. NUM and NUMC variables are represented in host numeric format.
Comparisons between character variables use the EBCDIC collating sequence.
Data does not need to be converted to host format when calling remote
programs or when accessing remote files and databases, but data is converted to
the appropriate Java or ASCII format when making SQL calls or calls to local
C++ routines. EBCDIC encoding is available in several languages.
If you choose EBCDIC character encoding and do not specify a conversion table,
the debugger does not use a conversion table when you call a remote program
or access a remote file or database. The program name, library name, and any
passed parameters are encoded according to EBCDIC character encoding.

If your Java Runtime Environment does not support the selected character
encoding, you will see a warning message when the debugger starts. If you choose
to continue debugging, the debugger will return to the default encoding type.

You can not change character encoding during a debugging session. You must
restart the debugger for a change in character encoding to take effect.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging
Related tasks
“Setting preferences for the EGL debugger”
This topic tells you how to change your preferences for the EGL debugger.
Related reference
Data conversion

Setting preferences for the EGL debugger


This topic tells you how to change your preferences for the EGL debugger.

There are two pages of preferences for the EGL debugger. The first contains
general preferences, and the second contains a list of programs or services that you
want to debug in the generated code (Java or COBOL), as described in Debug
behavior mapping in this topic.

The only preferences used for debugging Rich UI applications are as follows:
v Stop at first line of a program
v Set systemType to DEBUG
v In the Default behavior mapping dialog box, the settings in the Service
Reference tab

For further details on Rich UI, see Rich UI debugging.

604 EGL Programmer’s Guide


General preferences
To set general preferences for the EGL debugger, follow these steps:
1. From the main menu, click Window → Preferences.
2. In the Preferences window, expand EGL in the tree and then click Debug.
This opens the EGL debugger preferences.
3. If you want the debugger to treat a program declaration like a breakpoint,
check Stop at first line of a program.
4. If you want to make changes to your code as you debug, check Enable
hotswapping.
5. If you want to require that a user ID and password be specified for remote
calls to an SQL database while debugging, click the box next to Prompt for
SQL user ID and password when needed. This user ID and password are
separate from those that are used to access an SQL database. For more
information, see ″SQL database access″ later in this section.
6. Click the check box for Set systemType to DEBUG to cause the value of
sysVar.systemType to be DEBUG rather than the value of the system build
descriptor option.
7. Type the initial values for sysVar.terminalID, sysVar.sessionID, and
sysVar.userID. If you do not specify values, each defaults to your user ID on
Windows 2000, NT, XP, and Linux.
8. In the Remote User and Remote Password fields, type the user ID and
password to be used for remote calls while debugging.
The user ID and password that are used for remote calls while debugging are
separate from the user ID and password that are used to access a SQL
database.
9. Type the port number for the EGL debugger in the EGL Debugger Port value
field. The default is 8345. For more information, see ″EGL debugger port″ later
in this section.
10. Select the type of character encoding to use when processing data during a
debugging session in the Character encoding field. The default is the local
system’s file encoding. For more information, see “Character encoding options
for the EGL debugger” on page 603.
11. To specify external Java classes for use when the debugger runs, modify the
class path. You might need extra classes, for example, to support MQ message
queues, JDBC drivers, or Java access functions.
The class path additions are not visible to the WebSphere Application Server
test environment, but you can add to that environment’s classpath by working
on the Environment tab of the server configuration.
Use the buttons to the right of the Class Path Order section.
v To add a project, JAR file, directory, or variable, click the appropriate
button: Add Project, Add JARs, Add Directory, or Add Variable.
v To remove an entry, select it and click Remove.
v To move an entry in a list of two or more entries, select the entry and click
Move Up or Move Down.
12. To restore the default settings, click Restore Defaults.
13. To save your changes, click Apply or, if you are finished setting preferences,
click OK.

SQL database access


To determine the user ID and password to use for accessing an SQL database, the
EGL debugger considers the following sources in order:

Debugging EGL applications 605


1. The build descriptor used at debug time; specifically, the sqlID and
sqlPassword build descriptor options.
2. The SQL preferences page, as described in “Setting preferences for SQL
database connections” on page 219; at that page, you can also specify other
connection information.
3. An interactive dialog that is displayed at connection time. This dialog is
displayed when you select the check box Prompt for SQL user ID and
password when needed.

The user ID and password that are used to access an SQL database are separate
from the user ID and password that are used to make remote calls while
debugging. To set the user ID and password for remote calls while debugging, see
the earlier instructions for setting preferences in the debugger.

EGL debugger port


The EGL debugger uses a port to establish communication with the Eclipse
workbench. The default port number is 8345. If another application is using that
port or if that port is blocked by a firewall, set a different value as described in the
earlier instructions for setting preferences in the EGL debugger.

If a value other than 8345 is specified as the EGL debugger port and if an EGL
program will be debugged on the J2EE server, you must edit the server
configuration:
1. Go to the Environment tab, System Properties section.
2. Click Add.
3. In the Name field, type com.ibm.debug.egl.port.
4. In the Value field, type the port number.

Debug behavior mapping


When you debug a program that calls another program or a service, the debugger
can execute either the EGL source code or the generated code for the called
program or service. By default, the debugger uses the EGL source code. To use the
generated code, add an entry to the ″Debug behavior mapping″ table.

Add entries as follows:


1. From the main menu, click Window → Preferences.
2. In the Preferences window, expand EGL in the tree, expand Debug, and click
Debug Behavior Mapping.
3. For calls to programs, click the Called Programs tab. For each row of the table,
specify the following fields:
Mapping mode
Select one of the following values:
source If you want to debug the EGL source file for the called
program. This is the default.
generated
If you want to debug the generated Java or COBOL code for
the called program. For example, you might choose this
example if you don’t have the EGL source file in your
workspace, or if the source file is large and runs slowly in the
debugger.

606 EGL Programmer’s Guide


IMS debug
If you are debugging IMS and you have called programs that
reside on the host. This setting allows the calls to the host
program to participate in the debugger transaction.
Call target
The name of the program that is called from the program that you are
debugging. You can use an asterisk (*) at the end of the target as a
wildcard.
Part mapping
The fully qualified name of the program or service that you want the
debugger to run when the program in Call target is called. Do not use
an asterisk in this field.
4. For calls to services, click the Service References tab. For each row of the table,
specify the following fields:
Mapping mode
Select one of the following values:
source If you want to debug the EGL source file for the service. This is
the default.
generated
If you want to debug the generated Java or COBOL code for
the service. For example, you might choose this example if you
don’t have the EGL source file in your workspace, or if the
source file is large and runs slowly in the debugger.
Service binding key
The name of the binding key in the deployment descriptor for the
service that you are calling.
Part mapping field
The fully qualified name of the service that you want the debugger to
run when the service in Service binding key is called. Do not use an
asterisk in this field.
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
VisualAge Generator compatibility
“Debugging EGL applications” on page 573
“Character encoding options for the EGL debugger” on page 603
Rich UI debugging
Related tasks
“Setting preferences for SQL database connections” on page 219
Related reference
sessionID
systemType
terminalID
userID

Debugging EGL applications 607


608 EGL Programmer’s Guide
Appendix. Notices
This information was developed for products and services offered in the U.S.A.
IBM may not offer the products, services, or features discussed in this document in
other countries. Consult your local IBM representative for information on the
products and services currently available in your area. Any reference to an IBM
product, program, or service is not intended to state or imply that only that IBM
product, program, or service may be used. Any functionally equivalent product,
program, or service that does not infringe any IBM intellectual property right may
be used instead. However, it is the user’s responsibility to evaluate and verify the
operation of any non-IBM product, program, or service.

IBM may have patents or pending patent applications covering subject matter
described in this document. The furnishing of this document does not grant you
any license to these patents. You can send license inquiries, in writing, to:
IBM Director of Licensing
IBM Corporation
North Castle Drive
Armonk, NY 10504-1785
U.S.A.

For license inquiries regarding double-byte (DBCS) information, contact the IBM
Intellectual Property Department in your country or send inquiries, in writing, to:
IBM World Trade Asia Corporation
Licensing
2-31 Roppongi 3-chome, Minato-ku
Tokyo 106-0032, Japan

The following paragraph does not apply to the United Kingdom or any other
country where such provisions are inconsistent with local law:
INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS
PUBLICATION ″AS IS″ WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS
FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or
implied warranties in certain transactions, therefore, this statement may not apply
to you.

This information could include technical inaccuracies or typographical errors.


Changes are periodically made to the information herein; these changes will be
incorporated in new editions of the publication. IBM may make improvements
and/or changes in the product(s) and/or the program(s) described in this
publication at any time without notice.

Any references in this information to non-IBM Web sites are provided for
convenience only and do not in any manner serve as an endorsement of those Web
sites. The materials at those Web sites are not part of the materials for this IBM
product and use of those Web sites is at your own risk.

Licensees of this program who wish to have information about it for the purpose
of enabling: (i) the exchange of information between independently created

© Copyright IBM Corp. 1996, 2008 609


programs and other programs (including this one) and (ii) the mutual use of the
information which has been exchanged, should contact:
Intellectual Property Dept. for Rational Software
IBM Corporation
3600 Steeles Avenue East
Markham, ON Canada L3R 9Z7

Such information may be available, subject to appropriate terms and conditions,


including in some cases, payment of a fee.

The licensed program described in this document and all licensed material
available for it are provided by IBM under terms of the IBM Customer Agreement,
IBM International Program License Agreement or any equivalent agreement
between us.

Any performance data contained herein was determined in a controlled


environment. Therefore, the results obtained in other operating environments may
vary significantly. Some measurements may have been made on development-level
systems and there is no guarantee that these measurements will be the same on
generally available systems. Furthermore, some measurements may have been
estimated through extrapolation. Actual results may vary. Users of this document
should verify the applicable data for their specific environment.

Information concerning non-IBM products was obtained from the suppliers of


those products, their published announcements or other publicly available sources.
IBM has not tested those products and cannot confirm the accuracy of
performance, compatibility or any other claims related to non-IBM products.
Questions on the capabilities of non-IBM products should be addressed to the
suppliers of those products.

All statements regarding IBM’s future direction or intent are subject to change or
withdrawal without notice, and represent goals and objectives only.

This information contains examples of data and reports used in daily business
operations. To illustrate them as completely as possible, the examples include the
names of individuals, companies, brands, and products. All of these names are
fictitious and any similarity to the names and addresses used by an actual business
enterprise is entirely coincidental.

COPYRIGHT LICENSE:

This information contains sample application programs in source language, which


illustrate programming techniques on various operating platforms. You may copy,
modify, and distribute these sample programs in any form without payment to
IBM, for the purposes of developing, using, marketing or distributing application
programs conforming to the application programming interface for the operating
platform for which the sample programs are written. These examples have not
been thoroughly tested under all conditions. IBM, therefore, cannot guarantee or
imply reliability, serviceability, or function of these programs.

Each copy or any portion of these sample programs or any derivative work, must
include a copyright notice as follows:

© (your company name) (year). Portions of this code are derived from IBM Corp.
Sample Programs. © Copyright IBM Corp. _enter the year or years_. All rights
reserved.

610 EGL Programmer’s Guide


If you are viewing this information softcopy, the photographs and color
illustrations may not appear.

Programming interface information


Programming interface information is intended to help you create application
software using this program.

General-use programming interfaces allow you to write application software that


obtain the services of this program’s tools.

However, this information may also contain diagnosis, modification, and tuning
information. Diagnosis, modification and tuning information is provided to help
you debug your application software.

Warning: Do not use this diagnosis, modification, and tuning information as a


programming interface because it is subject to change.

Trademarks and service marks


IBM, the IBM logo, and ibm.com are trademarks or registered trademarks of
International Business Machines Corporation in the United States, other countries,
or both. These and other IBM trademarked terms are marked on their first
occurrence in this information with the appropriate symbol (® or ™), indicating US
registered or common law trademarks owned by IBM at the time this information
was published. Such trademarks may also be registered or common law
trademarks in other countries. A current list of IBM trademarks is available on the
Web at www.ibm.com/legal/copytrade.html.

Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the
United States, other countries, or both.

Linux is a trademark of Linus Torvalds in the United States, other countries, or


both.

Microsoft and Windows are trademarks of Microsoft Corporation in the United


States, other countries, or both.

UNIX is a registered trademark of The Open Group in the United States and other
countries.

Other company, product or service names, may be trademarks or service marks of


others.

Appendix. Notices 611


612 EGL Programmer’s Guide
Index
A build descriptors (continued)
runtime SQL database
code generation
EGL
add EGL keyword connections 203 data access 183
records 184 build files debugging 591
Ajax description 89 JSF data table properties 463
defined 327 EGL 94 JSF image sizes 461
AJAX requests build order JSF input functions 462
EGL Web pages 432 Eclipse 85 source code editor 127
external requests 442 build parts SQL statements 190
refresh requests 436 overview 120 code snippets
submit requests 439 build paths inserting 165
applications editing in EGL 84 overview 164
debugging in EGL 573, 579, 587 overview 83 retrieving row values 417
EGL artifacts 67 build projects setting focus 418
EGL cheat sheets 166 Java source code 84 testing for session variables 425
EGL Console UI 513, 528 button widgets updating table rows 423
EGL deployment descriptor files 94 EGL Console UI elements 520 code templates
argument stack creating 160
C functions 141 disabling 159
ArrayDictionary EGL data part 102
arrays C editing 161
enabling 159
EGL data parts 103 C
exporting 162
asynchronous tasks (EGL) 266 mapping data to EGL 132
importing 162
C data types
naming considerations 158
EGL primitive types compared 145
overview 158
B C functions
invoking 136
removing 163
basic programs restoring defaults 163
using with EGL 133
in IMS (EGL) 308 combination boxes
C functions in EGL
BasicLibrary EGL Console UI elements 524
BIGINT 138
Library stereotype 111 commands
DATE 139
bidirectional language text EGL debugger 580
DATETIME 139
conversion 245 COMMAREA pointer parameter
DECIMAL 140
BIGINT data type format 256
INTERVAL 139
C functions 138 COMMDATA parameter format 257
pop functions 141
binding functions comments
return functions 144
EGL shortcuts 407 EGL source code
calls
bindings code lines 128
Java from EGL 128
JSF controls to EGL elements 394 COMMPTR parameter format 256
cancelOnPageTransition EGL
JSPs 389 Console UI
property 411
variables to services 491 building EGL applications 513
capabilities
BIRT reports creating 516
enabling for EGL 11
adding support to projects 553 EGL elements 513
catcher program (EGL) 301
breakpoints elements
character encoding
EGL debugger 584 button widgets 520
EGL debugger options 603
build control part check boxes 522
character types
description 120 user input 524
EGL primitives 98
build descriptor options modes
cheat sheets
EGL version 7.0 changes 35 running EGL applications 529
opening in EGL 166
EGL version 7.1 changes 16 rich client widgets 519
check boxes
genReturnImmediate (EGL) 261 running EGL applications 528
EGL Console UI elements 522
IMS generation (EGL) 310 constant fields
user input in EGL 404
spaADF in IMSADF II (EGL) 293 creating in EGL
CICS
spaSize (EGL) 276 Text UI 502
asynchronous tasks (EGL) 266
spaStatusBytePosition (EGL) 276 container-managed security 452
RETURN IMMEDIATE 265
synchOnPgmTransfer (EGL) 262 content assist
START 264
build descriptor part EGL overview 157
CICSOSLINK (EGL) 258
description control transfer
clients
description 120 JSF Handlers 569
EGL binding 487
build descriptors create function
COBOL
EGL debugger 583 add EGL keyword 184
CALLs (EGL) 268
preferences 174

© Copyright IBM Corp. 1996, 2008 613


curses mode debugger (continued) EGL version 7.0 (continued)
overview 529 starting a Web session 594 manual changes after migration 54
starting EGL programs 590 migration 42, 43
starting in EGL 588 migration tool 44
D stepping through programs 575
viewing variables in EGL 585
new features 18
parts 28
data
debugging services 36
forwarding between Web pages 410
DL/I 596 validation changes 24, 26
data access
IMS 596 EGL version 7.1
EGL code 183
services 595 build descriptor option changes 16
data access applications
DECIMAL data type interface updates 17
creating with EGL 208
C functions 140 language changes 14
data conversion
deferred message switch new features 13
bidirectional language text 245
in IMSADF II (EGL) 293 parts 14
data parts
Delegate parts eglpath EGL build path 83
EGL arrays 103
syntax 117 ELAISVN (EGL) 301
EGL miscellaneous 102
delete EGL keyword ELAISVN7 (EGL) 301
EGL overview 97
basic I/O functions 184 ELATSGET (EGL) 292
EGL version 7.0 28
delete function ELATSPUT (EGL) 292
EGL version 7.1 14
delete EGL keyword 184 elements
data processing tasks
deployment descriptor files EGL Console UI applications 513
overview 183
adding information 496 encryption
data table check boxes
EGL applications 94, 120 passwords in EGL 146
selecting rows in EGL 404
EGL Web projects 389 event handlers
data tables
shared protocols 497 JSF controls 460
retrieving row values 417
design document for reports exceptions
data types
JasperReports 534 handling
mapping EGL to C 132
development workbench EGL version 7.0 36
database connections
overview 1 overview 148
preferences 219
device input format (DIF) exporting files
SQL
estimating size 318 Eclipse workbench 81
changing 205
device output format (DOF) exporting projects
creating 197
estimating size 318 Project Interchange 81
runtime connections 203
Dictionary EGL data part 102 external services
database options
DL/I exposing 493
EGL specifications 189
basic concepts (EGL) 221 providing access 493
databases
debugging 596 ExternalType EGL logic part
creating EGL data access
examples (EGL) 227 description 105
applications 208
secondary index (EGL) 230 ExternalType EGL part 117
EGL SQL support 200
DLI
DataItem parts
starting debug servers 601
editing 167
dataItems EGL data parts 97 F
DataTable EGL data part 102 facets
DATE data type E adding 76
C functions 139 editors overview 76
date types EGL projects 76
EGL primitives 98 content assist 157 FastPath in IMS
DATETIME data type overview 155 generating programs for (EGL) 308
C functions 139 locating source files 172 features
debug servers preferences adding 76
DLI 601 folding 176 overview 76
debugger imports 178 projects 76
breakpoints in EGL 584 setting 175, 177 file I/O
build descriptors 583 EGL migration writing and reading 186
character encoding options in previous version 38 File Search view
EGL 603 EGL source file EGL 168
creating a launch configuration 588 creating 90 files
creating a Listener launch EGL version 6.0 iFix 001 build
configuration 589 migration 56 overview 89
EGL commands 580 migration tool changes 57 comma-separated value files 186
EGL overview 573, 579 property changes 60 EGL
EGL preferences 604 EGL version 7.0 searches 168
EGL Web projects 592 build descriptor option changes 35 source code editor 127
hotswapping 587 exception handling 36 EGL application artifacts 67
invoking from EGL generated interface updates 37 sequential files 186
code 591 language changes 19 sharing in EGL 79
preparing servers 592 manual changes 54

614 EGL Programmer’s Guide


folders I4GL data types JavaServer Faces (JSF) (continued)
creating source folders in EGL 87 EGL primitive types compared 145 controls (continued)
EGL application artifacts 67 IFP (IMS FastPath) style changes with EGL code 458
folding generating programs for (EGL) 308 creating Web pages 392
preferences 176 immediate message switch data tables
fonts in IMSADF II (EGL) 293 check boxes in EGL 404
preferences 176 import organization properties in EGL code 463
form fields EGL editor 178 EGL Web pages
setting focus 418 import statements elements 389
form parts description 124 navigation function 408
creating 502 importing files handler part properties
editing 500 Eclipse workbench 81 Web page data 410
filtering 509 importing projects handler parts
templates 505 Project Interchange 81 forwarding control in EGL 569
form variables IMS Handler parts
creating with EGL parts BMP program generation (EGL) 309 changing style classes in EGL 459
Text UI 503 calling programs in (EGL) 267 EGL preferences 465
FormGroup EGL data part 102 debugging 596 input functions in EGL code 462
FormGroup parts FastPath program generation link target changes in EGL 457
editing 500 (EGL) 308 JavaServer Pages (JSP)
bidirectional text preferences 511 MFS message input descriptor (MID) EGL Web applications 389
display options 510 (EGL) 289 JSP pages
palette preferences 512 MFS message output descriptor changing JSF image size with EGL
preferences 510 (MOD) (EGL) 289 code 461
forms program-to-program message switches
displaying records in EGL 507 (EGL) 275
inserting variables with EGL
Text UI 503
runtime support (EGL) 307
scratch pad area (SPA) (EGL) 286
L
language changes
popup forms in EGL 506 IMS Connect (EGL) 301
EGL version 7.0 19
popup menus in EGL 507 IMSADF II programs
EGL version 7.1 14
functions transferring to and from (EGL) 293
language elements
binding JSF buttons in EGL 395 interface EGL logic part
EGL external mappings 117
EGL description 105
large object types
binding JSF controls 394 Interface part
EGL primitives 98
commands when pages load 411 creating from service or external
launch configurations
overloaded 107 type 116
explicit 588
overview 107 overview 115
Listener 589
INTERVAL data type
viewing implicitly created
C functions 139
configurations 590
G LDAP
generatable parts EGL support 190
EGL J library EGL logic part
description 96 Jasper reports description 105
generation adding support to projects 549 Library part
eglpath 83 application elements in EGL 533 overview 110
preferences 180 JasperReports stereotypes
generation process XML design document 534 BasicLibrary 111
controlling 120 Java link edit part
get EGL keyword EGL calls 128 description 120
handling records 184 ExternalType EGL part 117 linkage options
GSAM files JavaScript functions in transfer of control 251
PCB associations (EGL) 309 JSF control event handlers 460 linkage options part
JavaServer Faces (JSF) description 120
binding buttons to EGL linkage options parts
H functions 395
binding controls to EGL
and IMS transaction codes (EGL)
list boxes
301
handler parts
elements 394 EGL Console UI elements 524
creating 541, 555
binding single-select controls to EGL List view
Handler parts
variables 401 EGL parts 170
creating Web pages in EGL 392
changing image sizes with EGL local services
handlers EGL logic parts
code 461 calling 483
overview 105
component interface support 464 localization
controls resource bundles 430
accessing in EGL 454 Web applications 426
I binding to services in EGL 407 logic parts
I/O functions EGL variables 397 Delegate syntax 117
EGL records 184 event handlers 460 EGL functions 107

Index 615
logic parts (continued)
EGL overview 105
O preferences (continued)
Rich UI appearance 347
EGL version 7.0 28 onConstructionFunction EGL services 498
Interface function 411 source styles 179
creating from service or external onPostRenderFunction EGL function 411 SQL database connections 219
type 116 onPreRenderFunction EGL function 411 SQL retrieve 220
remote services 115 OSLINK parameter format 257 text
JSF Handler overloaded functions 107 EGL overview 180
EGL preferences 465 Text UI
Library editor 510
sharing functions 110 P editor bidirectional text 511
service packages editor palette 512
service oriented architecture 113 creating 89 primitive types
Service import statements 124 C data types compared 145
creating from called program 114 overview 87 mapping EGL to C 132
creating WSDL from 119 Page Designer primitives
bindings 389 EGL data parts 97
support 389 EGL data types 98
M page lifecyles print forms
displaying records in EGL 507
manual changes EGL functions 411
pages procedures
EGL version 7.0 54
commands when pages load 411 calling in EGL 212
menus
parts Program Communication Block (PCB)
creating popups in EGL 507
EGL in DL/I (EGL) 221
enabling capabilities in EGL 11
ExternalType 117 program EGL logic part
message input descriptor (MID)
Record parts 100 description 105
estimating size 318
searches 168 program parts
format (EGL) 289
version 7.0 28 Interface 115
message output descriptor (MOD)
version 7.1 14 service 113
estimating size 318
generatable in EGL Program Specification Block (PSB)
format (EGL) 289
description 96 in DL/I (EGL) 221
message queues
introduction 95 scheduling (EGL) 301
print files as (EGL) 322
properties program-to-program message switches
serial files as (EGL) 320
introduction 122 in IMS/VS (EGL) 275
message switches
references 171 in IMSADF II (EGL) 293
in IMS/VS (EGL) 275
renaming in EGL 120 programming tasks
in IMSADF II (EGL) 293
searching for 168 completing in EGL 127
migrating
viewing lists in EGL 170 programs
EGL previous version 38
Parts List view EGL debugger 575
migrating EGL code
EGL 168 starting in the EGL debugger 590
version 6.0 iFix 001 56
Parts Reference view Project Explorer view
version 7.0 43
EGL EGL 168
manual changes after
generatable logic parts 171 Project Interchange
migration 54
searches 168 project sharing 81
migration
passwords projects
preferences
encryption in EGL 146 adding BIRT reports support 553
EGL-to-EGL 42
pop functions adding Jasper reports support 549
migration tool
C 141 converting to EGL plug-in 74
EGL version 7.0 44
popup forms creating
migration tool changes
creating in EGL 506 EGL plug-in 74
EGL version 6.0 iFix001 57
popup menus EGL Web 73
move statements
creating in EGL 507 overview 71
EGL version 7.0 migration 44
preferences debugging in EGL 588
moving parts
build descriptors 174 EGL application artifacts 67
EGL 121
EGL EGL database options 189
MPP (message processing program)
debugger 604 facets 76
generating programs for (EGL) 307
setting 173 features 76
Web applications 465 features and facets 76
EGL editor linking in the EGL build path 84
N folding 176 new EGL projects 173
navigation rules formatter 177 overview 70
EGL Web pages 408 import organization 178 renaming 75
null overview 175 sharing in EGL
testing for in SQL (EGL) 196 fonts 176 overview 79
numeric types generation 180 repositories 82
EGL primitives 98 overview 172
Rich UI 345

616 EGL Programmer’s Guide


properties resource bundles service oriented architecture
changes in EGL version 6.0 iFix 001 creating 430 EGL logic parts 113
migration 60 locales 431 service parts
changing JSF data tables with EGL overview 426 creating from called programs 114
code 463 retrieval creating WSDL 119
EGL data processing tasks 183 overview 113
cancelOnPageTransition 411 retrieve feature services
introduction 122 SQL 205 binding from WSDL files 489
JSF Handler for data transfer 410 retrieve preferences binding JSF controls in EGL 407
PSB SQL 220 calling
scheduling (EGL) 301 return functions local 483
C 144 remote 486
Rich Client Platform (RCP) mode debugging 595
R EGL overview 529
rich client widgets
EGL client binding information 487
EGL code 491
radio button group widget
EGL Console UI 519 EGL version 7.0 36
EGL Console UI 524
Rich UI elements 478
read function
applications 357 exposing 493
get EGL keyword 184
authentication 353, 359, 367 overview 475
record arrays
authorization 353, 368 providing access 493
binding JSF controls to EGL
confidentiality 355 shared protocols 497
variables 401
criteria 369, 371 types 481
Record EGL part 100
EGL preferences 345 session objects
Record parts
errors 374 EGL Web pages 424
SQL
example 369 session variables
using (EGL) 193
IBM Rational AppScan 386 detecting 425
Record stereotype
JEE 369, 374 EGL Web pages 424
EGL parts 100
JSF 357, 362 setCursorFocus
records
overview 327, 352 code snippets 418
displaying in EGL forms 507
proxy 359, 360 shared protocols
EGL data parts 97
resources 355 creating 497
EGL read/write functions 184
security 352, 353, 355, 357, 358, 359, snippets
refactoring
360, 361, 362, 364, 366, 367, 368, 369, inserting 165
deleting EGL source files 93
371, 372, 373, 374, 376, 377, 378, 380, overview 164
moving EGL parts 121
381, 385, 386 retrieving row values 417
moving EGL source files 92
SSL 377, 378, 380, 381, 385, 386 setting focus 418
renaming EGL parts 120
threats 376 testing for session variables 425
renaming EGL projects 75
Tomcat 373 updating table rows 423
renaming EGL source files 91
URL patterns 358 SOA
remote services
user 364, 366 overview 475
calling 486
Web services 361 source assistant
renaming parts
WebSphere 372, 373, 374 JSF controls in EGL 454
EGL 120
Rich UI appearance overview 167
replace EGL keyword 184
EGL preferences 347 source code
report design files
right justification building projects 84
compiling in EGL 533
variables 146 comments 128
report driver program
runtime messages source control
functions in EGL 533
customizing EGL system sharing EGL projects 82
report handler
messages 152 source file
creating 541, 555
EGL
subreports 547
creating 90
report handler EGL logic part 533
reports S source files
comments 128
code for invoking reports 538 Search view
content assist 157
creating Jasper reports with EGL 532 EGL 168
deleting 93
creating with EGL 531 searches
description 89
exported file formats 538 EGL items 168
locating in the Project Explorer
exporting 538 secondary index
view 172
running 545 in DL/I (EGL) 230
moving 92
templates for 546 security
renaming 91
writing report-driver code 538 container managed 452
source folders
repositories LDAP 190
creating in EGL 87
sharing EGL projects 82 Web applications 452
source style
resource associations servers
preferences 179
setting up in EGL 186 EGL Web page previews 448
SPA (scratch pad area) (EGL) 286
resource associations part preparing for debugging 592
spaADF
description 120 service EGL logic part
in IMSADF II (EGL) 293
description 105

Index 617
spaSize (EGL) 276 templates (continued) user interface
spaStatusBytePosition (EGL) 276 removing in EGL 163 EGL version 7 updates 37
SQL restoring defaults in EGL 163 EGL version 7.1 updates 17
connection preferences 219 text user interface (UI) parts
database connections localizing 426 editing 500
changing 205 preferences JSF Handler
creating 197 setting in EGL 180 EGL preferences 465
runtime connections 203 Text Form editor user interfaces
EGL supported database filtering EGL console 516
managers 200 Text UI 509 user sessions
explicit 211 overview 500 data storage for EGL Web pages 424
explicit statements (EGL) 195 Text UI
implicit statements bidirectional text preferences 511
description (EGL) 194
null (EGL) 196
display options 510
palette preferences 512
V
validation
Record parts (EGL) 193 preferences 510
changes in EGL version 7.0 24, 26
retrieve feature 205 text forms
validation changes
retrieve preferences 220 displaying records in EGL 507
EGL version 7.0 24, 26
SELECT statements text strings
variable fields
validating 217 constant fields in EGL
creating with EGL parts
statements Text UI 502
Text UI 503
working with 211 Text UI
variables
stored procedures in EGL 212 editor
binding JSF controls to EGL
working with data in EGL 190 bidirectional text preferences 511
elements 394
SQLRecord parts display options 510
binding JSF controls to EGL
in prepare statements 215 palette preferences 512
variables 401
stereotypes preferences 510
binding to services 491
EGL Record 100 Text UI programs
EGL
storage in IMS (EGL) 307
arrays 103
data processing tasks 183 time types
binding to Web page controls 397
STRING arrays EGL primitives 98
viewing in the EGL debugger 585
binding JSF controls to EGL trademarks 611
VGWebTransactions EGL part
variables 401 transferring control
forwarding control 569
style classes CICS environment
VisualAge Generator
changing from EGL JSF using call (EGL) 254
compatibility preferences 173
Handlers 459 using transfer statement
VisualAge Generator Web transactions
styles (EGL) 261
forwarding control in EGL 569
changing JSF controls with EGL IMS BMP environment
code 458 using transfer statement
subreports (EGL) 270
creating 547 IMS BMP environments W
substrings using call (EGL) 267 Web applications
creating 146 IMS/VS environments debugging in EGL 588
Swing mode using call (EGL) 267 EGL debugger 592
overview 529 using transfer statement EGL elements 389
system functions (EGL) 275 EGL preferences 465
EGL version 7.0 32 in IMS/VS (EGL) 291 EGL tasks 391
EGL version 7.0 migration 44 in z/OS batch (EGL) 267 Page Designer 389
system libraries iSeries environment (EGL) 299, 300 security 452
EGL version 7.0 32 Java programs (EGL) 300 Web diagrams
system messages overview 251 EGL Web projects 389
EGL runtime customization 152 z/OS batch environment Web page controls
system variables using transfer statement binding to EGL variables 397
EGL version 7.0 32 (EGL) 270 Web pages
EGL version 7.0 migration 44 type-ahead AJAX requests 432
Web applications 413 external requests 442
refresh requests 436
T submit requests 439
templates U creating in EGL 392
EGL commands when pages
creating in EGL 160 UNIX screen options
load 411
disabling in EGL 159 EGL Console UI 529
forwarding data 410
editing in EGL 161 UNIX users
navigation rules in EGL 408
EGL naming considerations 158 EGL Console UI screen options 529
previewing EGL pages 448
EGL overview 158 update function
session data storage with EGL 424
enabling in EGL 159 replace EGL keyword 184
Web projects
exporting from EGL 162 use statements
EGL elements 389
importing in EGL 162 description 124

618 EGL Programmer’s Guide


Web projects (continued)
JSF component interface support 464
JSF link targets in EGL 457
Web services
binding
EGL services 487
WSDL 489
calling
local 483
remote 486
deployment information 496
EGL code 491
elements 478
exposing 493
providing access 493
shared protocols 497
types 481
Web transaction applications
EGL overview 561
work database (EGL) 291
workbench
overview 1
WSDL
biding 489
WSDL files
creating 119

X
XML report design document
creating 534

Index 619
620 EGL Programmer’s Guide


Printed in USA

You might also like