Professional Documents
Culture Documents
EGL Programmers Guide PDF
EGL Programmers Guide PDF
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
Using EGL with the Eclipse IDE . . . . . . . . 1
A typical EGL development workbench . . . . 2
Other windows EGL developers commonly use. . 4
Other views and editors EGL developers
commonly use . . . . . . . . . . . . . 5
How the workbench is organized . . . . . . 9
Other information on the workbench . . . . . 11
Enabling EGL capabilities. . . . . . . . . . 11
Whats new in EGL V7.5 . . . . . . . . . . 12
Whats new in EGL V7.1 . . . . . . . . . . 13
Language changes in EGL V7.1 . . . . . . . 14
Changes to parts in EGL V7.1 . . . . . . . 14
Changes to system libraries and variables in EGL
V7.1 . . . . . . . . . . . . . . . . 15
Changes to build descriptor options in EGL V7.1 16
User interface changes in EGL V7.1 . . . . . 17
Whats new in EGL V7.0 . . . . . . . . . . 18
Language changes in EGL V7.0 . . . . . . . 19
Validation changes in EGL V7.0 . . . . . . 24
Validation changes in EGL V7.0 . . . . . . 26
Changes to parts in EGL V7.0 . . . . . . . 28
Changes to system libraries and variables in EGL
V7.0 . . . . . . . . . . . . . . . . 32
Changes to build descriptor options in EGL V7.0 35
Changes to exception handling in EGL V7.0 . . 36
Changes to services in EGL V7.0 . . . . . . 36
User interface changes in EGL V7.0 . . . . . 37
Migrating from a previous version of EGL . . . . 38
Setting EGL-to-EGL migration preferences . . . 42
Migrating EGL code to EGL V7.0 . . . . . . 43
Migrating EGL code to EGL V6.0 iFix 001 . . . 56
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
parts
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
70
71
73
74
75
76
79
83
86
87
87
89
89
90
91
92
93
94
94
95
96
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 97
105
120
120
121
122
124
127
128
128
131
133
146
146
148
152
155
157
158
164
165
166
167
168
168
169
171
172
172
173
174
175
176
176
177
178
179
180
180
. . .
. . .
. . .
creation
. . .
. . .
. . .
. . .
. . .
. 183
. 184
. 186
189
. 190
. 190
. 191
. 192
. 193
iii
Compatibility . . . . . . . . . . . .
Creating an SQL database connection . . . .
Supported SQL database managers . . . . .
Using an SQL database connection at run time
Editing or deleting an SQL database connection
Retrieving SQL table data . . . . . . . .
Creating a data access application . . . . .
Working with SQL statements . . . . . . .
Setting preferences for SQL database
connections . . . . . . . . . . . . .
Setting preferences for SQL retrieve . . . . .
Working with DL/I data . . . . . . . . .
Example DL/I database . . . . . . . . .
DL/I examples . . . . . . . . . . . .
Working with MQ message queues . . . . . .
Defining messages in EGL . . . . . . . .
Defining resource associations for message
queues . . . . . . . . . . . . . .
Reading from and writing to message queues
Using direct MQ API calls . . . . . . . .
Using linkage options for MQ run-time library
selection . . . . . . . . . . . . . .
Working with iSeries objects . . . . . . . .
Working with bidirectional data . . . . . . .
Creating a bidirectional runtime file . . . . .
Creating a bidirectional conversion table . . .
219
220
221
223
227
235
236
237
238
240
242
244
245
247
249
251
iv
196
197
200
202
205
205
208
211
252
252
253
253
254
256
259
259
261
261
262
263
265
265
267
268
268
268
269
270
271
271
. 271
. 272
. 272
275
276
.
.
.
.
.
281
284
286
293
294
. 295
. 299
. 300
. 300
. 300
. 300
. 301
. 301
. 301
. 301
307
307
308
308
309
310
310
313
315
317
318
319
319
320
321
321
322
322
322
324
324
329
334
337
339
340
344
345
347
349
351
352
352
355
357
357
362
367
368
369
374
376
377
386
389
.
.
.
.
389
391
392
426
. 432
. 448
. 449
. 452
.
.
.
.
.
.
.
.
454
457
458
459
460
461
462
463
. 464
. 465
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
467
468
468
468
469
Inter-Portlet Communication . . .
J2EELib . . . . . . . . . .
Creating a Web Page . . . . . .
Adding a Portlet to the Application .
Adding Support for Additional Portlet
. . .
. . .
. . .
. . .
Modes
.
.
.
.
.
.
.
.
.
.
470
471
471
472
473
Overview of service-oriented
architecture (SOA) . . . . . . . . . 475
Elements of a service-oriented application . . . .
Types of services . . . . . . . . . . . .
Calling a local service . . . . . . . . . .
Calling a remote service . . . . . . . . . .
Adding service client binding information for an
EGL service . . . . . . . . . . . . . .
Adding service client binding information from a
WSDL file . . . . . . . . . . . . . .
Creating a service-access variable and binding it to
a service . . . . . . . . . . . . . . .
Exposing a service to other applications . . . .
Adding Web service deployment information to
the deployment descriptor . . . . . . . .
Creating and using a shared protocol . . . . .
Setting preferences for service generation . . . .
478
481
483
485
487
489
491
493
496
497
498
499
500
500
502
502
503
505
509
510
510
511
512
.
.
. 513
. 516
.
.
.
.
.
.
.
.
.
.
.
.
519
520
522
524
528
529
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
531
531
531
532
Contents
533
. 534
.
.
.
.
.
.
.
.
.
.
538
541
545
546
547
549
551
553
555
556
557
558
. 561
.
.
.
.
.
.
562
563
564
564
566
567
. 569
. 570
vi
.
.
.
. 575
. 579
. 580
. 583
584
585
585
585
585
586
587
588
588
589
590
591
592
592
594
595
595
595
596
596
597
599
601
603
604
605
606
.
.
.
.
.
.
.
.
. 611
. 611
Index . . . . . . . . . . . . . . . 613
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.
Whats new in EGL V7.1 on page 13
Whats new in EGL V7.0 on page 18
Migrating from a previous version of EGL on page 38
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
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 files 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
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.
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
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.
Introduction
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
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
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
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
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.
Introduction
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 perspectives 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
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.
Editors
Enabling EGL capabilities
Setting general preferences on page 173
Working with EGL code on page 127
Overview of EGL Rich UI on page 327
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.
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.
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.
12
Related information
Whats new in EGL V7.1
Related concepts
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
14
v
v
v
v
v
handleHardIOErrors
i4glItemsNullable
localSQLScope
textLiteralDefaultIsString
throwNrEofExceptions
ConverseLib
ConverseVar
DLILib
DLIVar
See the EGL Language Reference for information on these libraries and variables.
15
oneFormItemCopybook
printDestination
restartTransactionID
setFormItemFull
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
v
v
v
spaADF
spaSize
spaStatusBytePosition
synchOnPgmTransfer
16
genResourceBundle
genVGUIRecords
msgTablePrefix
resourceBundleLocale
Introduction
17
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.
18
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 pages 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
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?;
19
v
v
v
v
v
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)
NIL is no longer a valid literal to represent a null value. Use NULL
instead.
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.
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.
The nullable modifier on function parameters is now sqlNullable.
The isNullable property is now isSQLNullable.
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.
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
20
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");
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};
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
22
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
psb
psbParm
redefines
segmentRecord
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"
};
24
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
recordType;
any;
function main()
foreach(from myRecord into myVariable);// validation error
end
end
end
record recordType type SQLRecord
item1 int;
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
26
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
recordType;
any;
function main()
foreach(from myRecord into myVariable);// validation error
end
end
end
record recordType type SQLRecord
item1 int;
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
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
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 users 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
propertys 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
onPostRenderFunction
cancelOnPageTransition
onValueChangeFunction
selectType
selectFromListItem
selectedRowItem
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
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
v Program
v Handler
v Library
v Service
v Program
v Handler
v Library
v Record
Related Concepts
Whats 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
32
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()
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
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
34
35
36
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.
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
Whats 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.
38
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 codes 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 arguments 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 arguments 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.
40
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.
41
2.
3.
4.
5.
e. Click OK.
f. Click OK again.
Click Window Preferences.
Expand EGL and click Migration. This page shows the settings for the
migration tool.
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.
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.
42
10. The migration tool can add Web service deployment information to the
projects 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
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
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
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
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
Introduction
45
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");
46
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 );
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 );
Migrated code
result = round(x);
assign(x, result);
No change.
Migrated code
result = abs(x);
assign(abs(x), result);
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()
Migrated code
(byte)myVar
myVar as "java:byte"
(objId)myVar
myVar as "objId:java"
(null)"java.lang.Integer"
null as "java.lang.Integer"
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];
Migrated code
newForm consoleFormType;
newForm consoleFormType{};
The migration tool initializes the following reference variables in this way:
v ArrayDictionary
48
v
v
v
v
BLOB
CLOB
Record parts with the stereotype consoleForm
Dictionary
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;
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
Migrated code
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
norefresh
externallyDefined;
50
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 )
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
projects 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 projects 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
{displayUse = hyperlink,
action="myPage.jsp"};
myLink string
{displayUse = hyperlink,
action="myPage.faces"};
Migrated code
item1 string
{ value = "item1ValueProp" }
= "item1Initializer";
item1 string
{} = "item1ValueProp";
item2 string
{ value = "item3ValueProp" };
item2 string
{} = "item3ValueProp";
The migration tool makes this change for the following tags:
<h:selectManyCheckboxlist>
52
<h:selectManyListbox>
<h:selectManyMenu>
<h:selectOneListbox>
<h:selectOneMenu>
<h:selectOneRadio>
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
54
55
56
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
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
58
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()
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
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" }
60
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
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" }
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
highlight
indexOrientation
intensity
outline
protect
selectType
sign
After migration
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"
After migration:
{ defaultSelectCondition =
#sqlCondition{ // no space between #sqlCondition and the brace
hostVar02 = 4
}
}
64
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
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 others 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
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
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.
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
70
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
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.
12.
13.
14.
15.
v If you selected a target runtime that does not support EAR projects on the
previous page, the EAR Project Name field is disabled.
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.
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.
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.
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.
74
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.
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
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 project
EGL Web
project
EGL plug-in
project
EGL portlet
project
Jasper report
support
Yes
No
Yes
No
BIRT report
support
Yes
Yes
Yes
No
Yes
Yes
Yes
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
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
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 files 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
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.
82
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 Ds 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.
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
84
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
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
87
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
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
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
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.
92
93
94
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.
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
DataTable parts
Record parts with the stereotype ConsoleForm
Record parts with the stereotype VGUIRecord
Program parts with the stereotype VGWebTransaction
FormGroup parts
EGL deployment descriptors
96
v The generatable part must have the same name as the source file, minus the
source files .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.
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;
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
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 doesnt 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
98
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;
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.
99
Primitive large object types: Large object types store unformatted data. EGL
simply passes them through without changing themgenerally 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
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
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);
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 fields 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:
101
record
10
10
10
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.
102
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
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:
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"
Its 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);
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
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.
105
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
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
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)
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
110
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
p2
p3
p4
end
end
112
ANY in,
ANY in,
ANY out,
CLOB inOut)
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.
114
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.
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
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.
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
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.
119
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
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 parts file, but it does not
change the name of the JSP file.
v For JSF Handlers, EGL updates references to the parts 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
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 parts file, but it does not
change the name of the JSP file.
v For JSF Handlers, EGL updates references to the parts 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
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
123
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 variables 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
124
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/
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.*;
125
126
127
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
128
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");
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");
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
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
131
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
132
EGL primitive
C type
INT
SMALLINT
BIGINT
NUM
NUMC
DECIMAL, MONEY
PACF
FLOAT
double
SMALLFLOAT
float
BOOLEAN
HEX
unsigned char
CHAR
char
MBCHAR, DBCHAR
UNICODE, STRING
C type
DATE
TIME
TIMESTAMP
INTERVAL
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 elements data
b. The data of the element
c. If the element is nullable, a SHORT representing the elements 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 fields data
b. The fields data
c. If the field is nullable, a SHORT representing the fields 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
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
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
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
135
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
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
138
Description
ifx_int8add( )
ifx_int8cmp( )
ifx_int8copy( )
ifx_int8cvasc( )
ifx_int8cvdbl( )
ifx_int8cvdec( )
ifx_int8cvflt( )
ifx_int8cvint( )
ifx_int8cvlong( )
ifx_int8cvlong_long( )
ifx_int8div( )
ifx_int8mul( )
ifx_int8sub( )
ifx_int8toasc( )
ifx_int8todbl( )
ifx_int8todec( )
ifx_int8toflt( )
ifx_int8toint( )
ifx_int8tolong( )
ifx_int8tolong_long( )
For more information about the individual functions, see the following: IBM
Informix ESQL/C Programmers 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
Description
rdatestr( )
rdayofweek( )
rdefmtdate( )
rfmtdate( )
rjulmdy( )
rleapyear( )
rmdyjul( )
rstrdate( )
rtoday( )
For more information about the individual functions, see the following: IBM
Informix ESQL/C Programmers 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
139
Function Name
Description
dtaddinv( )
dtcurrent( )
dtcvasc( )
dtcvfmtasc( )
dtextend( )
dtsub( )
dsubinv()
dttoasc( )
dttofmtasc( )
incvasc( )
incvfmtasc( )
intoasc( )
intofmtasc( )
invdivdbl( )
invdivinv( )
invextend( )
invmuldbl( )
For more information about the individual functions, see the following: IBM
Informix ESQL/C Programmers 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
140
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( )
dectoasc( )
deccvint( )
dectoint( )
deccvlong( )
dectolong( )
deccvflt( )
dectoflt( )
deccvdbl( )
dectodbl( )
decadd( )
decsub( )
decmul( )
decdiv( )
deccmp( )
deccopy( )
dececvt( )
decfcvt( )
For more information about the individual functions, see the following: IBM
Informix ESQL/C Programmers 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
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
v
v
v
v
extern
extern
extern
extern
extern
void
void
void
void
void
ibm_lib4gl_popInt4(int *liv)
ibm_lib4gl_popFloat(float *fv)
ibm_lib4gl_popDouble(double *dfv)
ibm_lib4gl_popDecimal(dec_t *decv)
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
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 Programmers 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)
142
popquote
ibm_lib4gl_popQuotedStr
popstring
ibm_lib4gl_popString
popvchar
ibm_lib4gl_popVarChar
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 Programmers 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
poplocator
ibm_lib4gl_popBlobLocator
The structure type loc_t defines a BYTE or TEXT value, and is discussed in the
IBM Informix ESQL/C Programmers 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
extern
extern
extern
extern
extern
void
void
void
void
void
ibm_lib4gl_returnMInt(int iv)
ibm_lib4gl_returnInt2(short siv)
ibm_lib4gl_returnInt4(int lv)
ibm_lib4gl_returnFloat(float *fv)
ibm_lib4gl_returnDouble(double *dfv)
144
retint
ibm_lib4gl_returnMInt
retshort
ibm_lib4gl_returnInt2
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
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
dec_t
DEC or DECIMAL(p,s,)
or NUMERIC(p)
DECIMAL(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
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"
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
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 systems 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 systems PATH environment variable, add the location of the Java
SDK. See your operating systems 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
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.
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
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
149
Meaning
duplicate
endOfFile
noRecordFound
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
try
get myCustomer;
end
if (myCustomer is noRecordFound)
add myCustomer;
end
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
programs 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
151
myErrorHandler2();
else
myErrorHandler3();
end
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
152
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.
153
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 projects 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
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 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.
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
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.
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.
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
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.
159
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
161
162
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
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
database update
Related concepts
Content assist on page 157
Code templates on page 158
164
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.
165
166
167
168
2.
3.
4.
5.
If you do not see Search EGL, click Search Search and switch to the EGL
Search tab.
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.
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.
In the Limit To section, select the option to limit your search to part
declarations, part references, or any occurrence of the search string.
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.
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.
170
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.
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
173
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
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
change the fonts and colors used in the EGL editor, follow these steps:
Click Window Preferences.
In the Preferences window, click General Appearance Colors and fonts.
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 computers
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
176
177
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
179
180
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
181
182
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 receivewhether 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
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
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 dont 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:
185
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.
Prerequisites
v An EGL project
186
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:
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.
187
import myProject.myData.mySerialRecord;
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.
3. In an EGL logic part, declare a variable that is based on your serial record:
variableRecord mySerialRecord;
6. Save, generate, and run the program. The program reads the sequential file and
displays the data from the record in the console:
Hello!
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
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
189
190
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 with reusable Place the custom WHERE clause in the
custom WHERE clause.
defaultSelectCondition property.
SQL SELECT statements with custom
WHERE clause.
Stored procedure.
191
EGL approach
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
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.
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
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.
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
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
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.
195
To test for a null value, use a standard EGL if statement, as in the following
example:
if (myEmpRecord.empDeptNo == null)
...
end
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
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
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.
197
198
Host
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
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 projects 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.
200
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
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
iSeries
v JDBC driver
v JDBC driver class
v Class location
v Connection URL
v User ID
v Password
DB2 UDB
zSeries
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
201
Versions
Setup Information
Informix
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.
202
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.
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 projects 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 projects 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.
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.
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
.
204
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
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
206
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
BIGINT
BIGINT
n/a
BIT
SMALLINT
n/a
BLOB
BLOB
n/a
n/a
BOOLEAN
BOOLEAN
n/a
CHAR
CHAR
132767
132767
CLOB
CLOB
n/a
n/a
DATE
DATE
n/a
DECIMAL
DECIMAL
1-18
110
DOUBLE
FLOAT
n/a
FLOAT
FLOAT
n/a
GRAPHIC
DBCHAR
116383
232766
INTEGER
INT
n/a
LONG VARBINARY
HEX
65534
32767
LONG VARCHAR
CHAR
>4000
>4000
LONG VARGRAPHIC
DBCHAR
>2000
>4000
NUMERIC
DECIMAL
1-18
110
REAL
SMALLFLOAT
n/a
SMALLINT
SMALLINT
n/a
TIME
TIME
n/a
TIMESTAMP
TIMESTAMP
n/a
14
VARBINARY
HEX
265534
132767
VARCHAR
CHAR
4000
4000
VARGRAPHIC
DBCHAR
2000
4000
207
Compatibility
Table 35. Compatibility considerations for SQL data
Platform
Issue
Java generation
COBOL generation
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
Prerequisites
Before you begin, connect to an SQL database. See Creating an SQL database
connection on page 197.
208
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 users 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
209
210
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
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
Prerequisites
v An EGL project and program or other logic part
v An SQL database with a stored procedure
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;
212
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;
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;
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 (Oracles 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
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.
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.
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;
In this case, you can change the using myCustomerID clause to use different
variables in different situations.
216
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
customerName STRING
customerAddr1 STRING
customerAddr2 STRING
customerAddr3 STRING
customerBalance MONEY
{column="C_NUMBER", maxLen=6};
{column="C_NAME", isSQLNullable=yes, maxLen=25};
{column="C_ADDR1", isSQLNullable=yes, maxLen=25};
{column="C_ADDR2", isSQLNullable=yes, maxLen=25};
{column="C_ADDR3", isSQLNullable=yes, maxLen=25};
{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
};
218
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
219
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
220
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
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
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
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
LOCATION
(STSCLOC)
CREDIT
STATUS
(STSCSTA)
CUSTOMER
HISTORY
(STSCHIS)
CUSTOMER
ORDER
(STPCORD)
ITEM
(STLCITM)
224
v There is only one credit segment per customer so no key field is necessary.
v The history segment is a variable length segment.
};
};
};
};
};
//key field
};
};
};
};
};
//key field
};
};
};
};
//key field
225
10
10
10
10
end
historyReference char(25)
historyItemCount smallint
historyAmount decimal(12,2)
historyStatus char(77)
{
{
{
{
dliFieldName
dliFieldName
dliFieldName
dliFieldName
=
=
=
=
"STFCHRF"
"STFCHIC"
"STQCHAM"
"STQCLOS"
};
};
};
};
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.
ELAALT
ELAEXP
STDCDBL
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
226
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
v
v
v
v
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
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) };
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
Then you can use implicit DL/I I/O without having to first assign
customerParm.customerNo to myCustomer.customerNo as follows:
get myCustomer;
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.
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;
229
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
programs 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
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.
230
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;
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:
231
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.
232
// it was a customer
// it was a location
// 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
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
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
programs 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
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
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
235
236
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
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.
238
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.
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.
240
To
1.
2.
3.
4.
5.
use direct MQ API calls, you must enable an EGL Project Feature:
Right-click the project name in the Project Explorer view.
Select Properties.
Click EGL Project Features in the left side of the Properties dialog.
Check the box next to EGL with low-level MQ API support.
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
MQGMO_INIT
MQINTATTRS
MQINTATTRS_INIT
MQMD
MQMD_INIT
241
Description
Initializer function
MQMD1
MQMD1_INIT
MQMDE
MQMDE_INIT
MQOD
MQOD_INIT
MQOR
Object record
MQOR_INIT
MQPMO
MQPMO_INIT
MQRMH
MQRMH_INIT
MQRR
Response record
MQRR_INIT
MQSELECTORS
MQSELECTORS_INIT
MQTM
MQTM_INIT
MQTMC2
MQTMC2_INIT
MQXQH
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
MQCONNX
Extended connect
MQDISC
MQOPEN
MQCLOSE
MQGET
MQPUT
MQPUT1
MQINQ
MQSET
MQBEGIN
MQCMIT
MQBACK
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.
242
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
Environment description
MQ library
Wrapper DLL
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,
threaded
environment
libmqm_r.a
csomqmr
libmqm_r.lkg
AIX
MQ client,
threaded
environment
libmqic_r.a
csomqicr
libmqic_r.lkg
HP-UX
MQ manager
libmqm.sl
csomqm
libmqm.lkg
HP-UX
MQ client
libmqic.sl
csomqic
libmqic.lkg
HP-UX
MQ manager,
threaded
environment
libmqm_r.sl
csomqicr
libmqm_r.lkg
HP-UX
MQ client,
threaded
environment
libmqic_r.sl
csomqmr
libmqic_r.lkg
Solaris
MQ manager
libmqm.so
csomqm
libmqm.lkg
Solaris
MQ client
libmqic.so
csomqic
libmqic.lkg
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
243
244
245
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
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).
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
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
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
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
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
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
Language
COBOL generation
Arabic
Cp1256
Cp864
COBOL generation
Hebrew
Cp1255
Cp1255
Arabic
Cp1256
Cp420
Hebrew
Cp1255
Cp424
Arabic
Cp1256
Cp1256
Hebrew
Cp1255
Cp1255
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
251
8 bytes
6 bytes
2-byte length
Figure 1. Format of the form area passed using the call statement
252
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.
PSB Name
Pointer to
dliLib.psbData
Pointer to UIB
.
.
.
PCB Number n
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).
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
254
COMMDATA OSLINK
CICSOSLINK CHANNEL
DYNAMICValid
Valid
Valid
Valid
No
STATIC
Valid
Valid
Valid
Valid
No
CICSLINK Valid
Valid
No
No
Valid
No
No
Valid
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.
Register 1
Address of EIB
Address of COMMAREA
.
.
.
High Order
Byte,
Bit 0 = 1
1 to 30
Parameter
pointers
List End
(optional - see
note)
When you set the endCommarea build descriptor option to YES for the calling
program, the calling program adds the xFFFFFFFF 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
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.
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).
257
Register 1
.
.
.
1 to 30 parameter
pointers
Register 1
Address of EIB
Address of COMMAREA
4 Byte Parm Pointer
.
.
.
1 to 30 parameter
pointers
258
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
EGL-PARM-2
EGL-PARM-3
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.
PARMPTR,DFHEICAP
PARMAREA,PARMPTR
PARM1PTR,PARM1A
PARM1,PARM1PTR
PARM2PTR,PARM2A
PARM2,PARM2PTR
PARM3PTR,PARM3A
PARM3,PARM3PTR
F
F
F
*
L10
L20
L200
L5
*
L5
L5
260
USAGE IS POINTER.
USAGE IS POINTER.
USAGE IS POINTER.
PIC X(10).
PIC X(20).
PIC X(200).
And so on
.
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
.
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
261
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.
262
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.
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
264
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.
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.
265
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";
266
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.
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
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.
Register 1
.
.
.
High Order Byte,
Bit 0 = 1
1 to 30 parameter
pointers
268
If you need to link your program with other modules (such as a PL/I program, for
example), see Link edit part examples.
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
v
v
v
v
pgmName = calledExci
remotePgmType = EGL | EXTERNALLYDEFINED (has no effect)
serverID = ABCD (default is CSMI)
type = REMOTE
conversiontable (has no effect)
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
270
EGL Statement
From Program
To Program
How Implemented
transfer to program
EGL
EGL
COBOL CALL
Non-EGL
OS XCTL
transfer to
transaction
Non-EGL
EGL
EGL
EGL
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.
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.
272
Register 1
High order byte
must have
bit 0 = 1
Pointer to
Working Storage
Pointer to
dliLib.psbData
Length (2 bytes)
Filler (8 bytes)
Working Storage Data
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.
273
Register 1
PCB
Address
List
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.
274
275
Coding and
generating
Performing the
transfer
Using an input
form
Passing a record
Specifying
segmentation
status byte
If spaStatusBytePosition is
specified, the segmentation status
byte is always placed in the last
byte of the SPA. The target
program always ignores the value
of the segmentation status byte.
If spaStatusBytePosition=n is
specified, the segmentation status
byte is placed in either position 15
or the last byte of the SPA, based
on the value of n. The target
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.
Action
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.
276
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.
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
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:
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
Coding and
generating
Performing the
transfer
Using an input
form
Passing a record
Action
281
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
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.
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.
284
Length in
bytes
Type of data
Description
Segment length
Binary
Reserved (ZZ)
Binary
Reserved.
IMS transaction
name
Character
Variable
Programdefined fields
Variable
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.
285
286
Length in
bytes
Type of data
Description
SPA length
Binary
SPA ID
Binary
IMS transaction
name
Character
Segmentation
Status Byte
(Optional)
Hexadecimal
Program data
Variable
Variable
Length in
bytes
Type of data
Description
Hexadecimal
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
05 SPA-ID
05 IMS-TRAN-NAME
05 CSP-OPTIONAL-SSM-BYTE
05 CSP-APPL-WS-DATA.
10 data-item-1
10 data-item-2
.
.
.
05 CSP-OPTIONAL-SSM-BYTE
PIC
PIC
PIC
PIC
S9(4) COMP.
S9(9) COMP.
X(8).
X(1).
See Note 1.
PIC ........................
PIC ........................
PIC X(1).
See Note 2.
287
record for the target program are related for conversational processing.
Table 47. Relationship of IMS SPA to transfer record
Function
Results
transfer to
transaction
transfer to
transaction
The size of the program data Extra bytes of the EGL record are
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
in the SPA exceeds the size of the SPA are truncated when it is moved
target
into the input record.
programs
EGL record named as input
record for the target program.
input record
Initialization of Size of the program data area
in the SPA is less than that of
target
the EGL record named as
programs
input record for the target
input record
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.
Length in
bytes
Type of data
Description
Segment length
Binary
Reserved
Binary
IMS transaction
name
Character
Variable
Program data
Variable
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
01 CSP-APPL-WS-RECORD.
05 CSP-IMS-SEG-LENGTH
05 CSP-ZZ
05 CSP-IMS-TRANNAME
05 CSP-APPL-WS-DATA.
10 data-item-1
10 data-item-2
PIC ........................
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.
Length in
bytes
Type of data
Description
Segment length
Binary
Reserved
Binary
IMS transaction
name
Character
Reserved
Character
Form name
Character
Additional
Rational
COBOL
Runtime for
zSeries fields
51
Variable
Program form
fields
Variable
Variable
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
10 EZEMAP-ZZ
15 EZEMAP-Z1
15 EZEMAP-Z2
10 EZEMAP-ZZ-BIN
10 EZEMAP-MID-TRANCODE.
15 EZEMAP-MOD-MAP
10 FILLER
10 EZEMAP-MOD-TRANCODE.
15 EZEMAP-MID-MAP
10 EZEMAP-STRUCTURE-TYPE
88 EZEMAP-IS-A-MAP
10 EZEMAP-SCA
10 EZEMAP-SCA-BIN
10 EZEMAP-EZEAID
10 EZEMAP-HELP-PF-KEY
10 EZEMAP-BYPASS-PF-KEYS.
15 EZEMAP-BYPASS-PF-KEY
10 EZEMAP-HELP-MAP-NAME
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
.
.
.
290
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
Read successful
12
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
v
v
v
v
v
Meaning
12
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.
293
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
294
A constant.
cc The cluster code (SOMTX) operand used to generate the transaction that causes
the switch to the EGL program.
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
input form)
Coding and
generating
Performing the
transfer
Using an input
form
The target program can optionally The target program must have an
have an input form.
input form.
Passing a record
Specifying
segmentation
status byte
If spaStatusBytePosition was
specified, the target program
always ignores the value of the
segmentation status byte that is
located in the SPA at the offset
specified.
If spaStatusBytePosition was
specified, the target program uses
the value of the segmentation status
byte at the offset specified when
there is an input form integrity
problem caused by the program user
pressing PA1 or PA2.
Action
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.
296
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.
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
299
300
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
302
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
303
304
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
305
306
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 users input by processing the statement that
follows the converse statement. For an overview of the runtime behavior, refer to
the EGL Language Reference.
307
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 programs 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.
308
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.
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.
mfsExtendedAttr
mfsIgnore
mfsUseTestLibrary
formServicePgmType
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
310
311
312
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.
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.
314
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
315
Output
Queue
Message
From
Terminal 1
To printer
or other transaction
Input
Queue
Transaction
Program
Message
From
Terminal 2
Queue
Message
Relational
or DL/I
Database
Back to
original terminal
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
Start
Application
Terminal
End
Database
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
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).
318
=
* Number of printer forms in the formGroup)
* Number of display forms in the formGroup)
* Number of variable field occurrences on printer
=
* Number of display forms in the formGroup)
* Number of printer forms in the formGroup)
* Number of variable field occurrences in the formGroup)
Related concepts
Developing EGL programs for the IMS environment on page 307
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.
320
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
Severity
endOfFile
QC
Soft
noRecordFound
QD
Soft
ioError
Hard or soft
hardIOError
Severity
endOfFile
GB
Soft
ioError
Hard or soft
hardIOError
Hard
322
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;
// declare variables
myTransaction myTransactionPart;
mypsb addToQueue;
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>
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.
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.
324
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 USER1s response to the converse statement.
The EGL-generated control logic determines that this response is a continuation
of USER1s processing, and does the following:
v Restores USER1s 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 USER1s
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
325
326
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.
328
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 handlers 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
329
330
331
332
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 handlers 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
334
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 treeadding,
changing, and removing widgetsin response to runtime events such as a users
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 typesButton for buttons, TextField for text fields,
and so forthand 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 handlers 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
337
338
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
339
2.
v To
1.
2.
3.
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
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 handlers 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
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 handlers 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
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 handlers 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 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.
344
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 handlers 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
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
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
348
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.
349
350
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.
351
352
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..
354
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:
355
356
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
358
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
360
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.
3.
4.
5.
6.
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
Securing
Securing
Securing
361
362
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
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:
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
364
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
To close the window after authentication completes, the JSF page can invoke a
JavaScript window.close.
Related concepts
366
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
HTML
file
3*
EGL
Rich UI
Proxy
Web
service
5*
6*
x
x
8*
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
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
369
370
371
372
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
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
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
374
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
376
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
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
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
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
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 owners
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
380
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.
381
382
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.
383
384
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
386
Related concepts
Overview of Rich UI security on page 352
Authentication and Authorization on page 353
Confidentiality and Integrity on page 355
387
388
389
390
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.
391
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.
392
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.
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.
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
394
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 pages 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.
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 pages 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
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
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 pages 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
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"};
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};
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
function onPreRender()
selectionOptions[1].displayOption
selectionOptions[1].optionValue =
selectionOptions[2].displayOption
selectionOptions[2].optionValue =
selectionOptions[3].displayOption
selectionOptions[3].optionValue =
end
= "Option one";
"first option";
= "Option two";
"second option";
= "Option three";
"third option";
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};
string;
outputMessage
string;
function onPreRender()
selectionOptions[1].displayOption
selectionOptions[1].optionValue =
selectionOptions[2].displayOption
selectionOptions[2].optionValue =
selectionOptions[3].displayOption
selectionOptions[3].optionValue =
= "Option one";
"first option";
= "Option two";
"second option";
= "Option three";
"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 pages 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
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.
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 pages behavior. This means binding, or connecting,
elements on the Web page to variables and functions in the JSF Handler.
406
407
7.
8.
9.
10.
11.
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 pages 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
408
browsers 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 users 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>
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";
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";
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
myInteger int = 5;
myChar
char(100) = "Hello";
forward myInteger, myChar to "myPage";
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
412
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
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 variables 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.
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
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
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
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
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.
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
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
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
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();">
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
419
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}
420
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);
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"]);
421
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);
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
JSF can also set the values of error message components as part of user input
validation. See Display Errors.
Related reference
422
setError()
setErrorForComponentID()
msgResource
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
423
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
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 users 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.
Also, you can remove all EGL-controlled session variables from the users 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
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 users 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 users session on page 424
426
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.
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.
428
<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>
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
429
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
431
432
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:
433
434
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")
435
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()
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
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>
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.
d.
e.
f.
On the properties view, go to the Ajax tab under the type of panel control.
On the Ajax tab, select the Allow Ajax updates check box.
Click Refresh as the type of request.
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 controls 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
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 Handlers 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
439
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>
440
b.
c.
d.
e.
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
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 Handlers 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
442
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
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:
443
4. Create the request by specifying the panel to update and the parameters for the
request:
On the target page, select the panel control.
With the panel selected, open the Properties view.
On the properties view, go to the Ajax tab under the type of panel control.
On the Ajax tab, select the Allow Ajax updates check box.
Click External as the type of request.
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.
a.
b.
c.
d.
e.
f.
444
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:
445
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
behaviors 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 tags
target attribute points to the panel control, indicating that this request will run
when the panels 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
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
pages 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 pages 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
448
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
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.
449
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
2. Create a directory in i5/OS to store the WAR file. For example, make a folder
in the network drive z:
>> md
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
// 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.
452
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 users 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 users 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()
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
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 Handlers file automatically.
v Add the following import statement:
import com.ibm.egl.jsf.*
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 controls text to red with the code
myComponent.setStyle("color: red"); and then set the same controls 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 controls text to bold
and red, without overwriting any previous changes to that controls 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
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
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
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
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
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
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");
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
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:
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
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
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);
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
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
464
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
465
466
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
468
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 projects 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
Related concepts
469
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
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
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 projects 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.
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
472
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
474
475
Web
application
Service-oriented application
Integration
service
Business
service
Business
service
Data-access
service
Data-access
service
Data-access
service
Databases
The topmost level contains one or more integration services, each of which controls
a flow of activities such as processing an applicants 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.
476
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
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
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
479
480
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.
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.
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
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 projects 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
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
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
485
486
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:
487
If the EGL service part that you want to use is either in your project or in a
project in your projects 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.
488
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.
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
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
v
v
v
An EGL project
Client binding information for a Web service or an EGL service.
An Interface part or Service part.
Any EGL logic part, such as a Program, Library, Service, or Handler
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);
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;
492
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.
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.
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
returns (int)
return(intOne - intTwo);
end
private function getAbsoluteValueInteger(intOne int in)
returns(int)
return(MathLib.abs(intOne));
end
end
495
Prerequisites
v An EGL project
v A Service part
v An EGL deployment descriptor file
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
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.
497
498
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
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 groups 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
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. SeeCreating 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. SeeDisplay 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
5.
6.
7.
create a form in the EGL Text Form editor, follow these steps:
Open a form group in the Text Form editor.
On the Palette view, click either Text Form or Print Form.
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.
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.
Click OK.
Click the form and edit its properties in the Properties view.
Add fields to the form as appropriate. SeeCreating 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
Creating
Creating
Creating
a
a
a
a
502
Table 54. Constant fields that are available in the Palette view
Field name
Default color
Default
intensity
Default
highlighting
Default
protection
Title
Blue
Bold
None
Skip
Column
Heading
Blue
Bold
None
Skip
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
Default color
Default
intensity
Default
highlighting
Default
protection
Input
Green
Normal
Underlined
No
Output
Green
Normal
None
Skip
Message
Red
Bold
None
Skip
503
Table 55. Variable fields that are available in the Palette view (continued)
Field name
Default color
Default
intensity
Default
highlighting
Default
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 arrays 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
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 fields 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 fields 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
505
506
a
a
a
a
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 fields 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
create a new filter in the EGL Text Form editor, follow these steps:
Open a form group in the Text Form editor.
In the Text Form editor, click the Filters button. The Filters window opens.
In the Filters view, click the New button. The New Filter dialog box opens.
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
This drop-down list allows you to select a new size for the form.
510
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
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
512
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.
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
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.
515
ConsoleForm
Console UI parts
openUI
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.
516
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.
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
"Choose an option",
= "One",labelText = "Option One"},
= "Two",labelText = "Option Two"},
= "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
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.
A mnemonic that you will use later to link the button to an event
handler
text
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 buttons
PUSHED event:
520
onEvent(ConsoleButton.PUSHED : "simpleButton")
SysLib.writeStderr("You pushed the button.");
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.
521
A mnemonic that you will use later to link the check box to an event
handler
text
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
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 boxs
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
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
524
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 widgets
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
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
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 widgets 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
528
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
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.
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.
532
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
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
534
<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
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).
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
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>
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>
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
Because the backslash character (\) is used in escape sequences, you must use a
double backslash in path names.
538
Explanation
SQLLib.defineDatabaseAlias("customer",
"jdbc:derby:C:\\databases
\\CustomerDatabase");
SQLLib.connect("customer",
"admin", "admin");
myReportData ReportData =
new ReportData();
myReport.reportDesignFile =
location;
myReport.reportDestinationFile =
location;
myReport.reportExportFile =
location;
myReportData.connectionName =
"customer";
myReportData.sqlStatement =
SQL statement;
myReport.reportData = myReportData;
reportLib.fillReport(myReport,
DataSource.sqlStatement);
reportLib.exportReport(myReport,
ExportFormat.pdf);
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
ExportFormat.html
ExportFormat.pdf
ExportFormat.text
ExportFormat.xml
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
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.
542
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
You must match variable types in the report handler with those in your XML
source file.
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
544
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
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
add a report handler template to your source file, follow these steps:
Open a new file in your text editor.
Type handler, then press Ctrl+space
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
1.
2.
3.
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
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
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 systems PATH environment variable, add the location of the Java SDK.
See your operating system documentation for instructions.
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
551
v You invoke a function that creates the output, as in the following example:
myReport.createReportFromDesign();
552
553
In the Project Explorer view, right-click your project and then click Properties.
In the Properties window, click Java Build Path.
On the Libraries tab, click Add External JARs.
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.
2.
3.
4.
5.
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
554
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 EGLs 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 Programmers Guide.
556
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 Users 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
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
557
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
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.
{column="C_NUMBER", maxLen=6};
{column="C_NAME", isSQLNullable=yes, maxLen=25};
{column="C_ADDR1", isSQLNullable=yes, maxLen=25};
{column="C_ADDR2", isSQLNullable=yes, maxLen=25};
{column="C_ADDR3", isSQLNullable=yes, maxLen=25};
{column="C_BALANCE", isSQLNullable=yes};
559
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
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).
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.
562
v Jar files are added to the folder WebContent\WEB_INF\lib and to the projects
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 projects 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
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
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.
564
The following table shows how to create each of the specified HTML controls.
Table 56. HTML controls
uiType
Field length
selectedIndexItem
Field value
input or
inputOutput
<=80 chars
n/a
Initial display
Text area
input or
inputOutput
> 80 chars
n/a
Initial display
(between
<textarea> and
</textarea>
tags)
Radio
buttons
input or
inputOutput
n/a
Numeric field
Not used
Check boxes
input or
inputOutput
n/a
Singleselection
combo box
output
n/a
Numeric field
Multipleselection
combo box
output
n/a
HTML
control
Field is
array?
Text box
Entries in
combo box
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
};
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
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
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
application
The bean is stored in the servlet context.
568
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
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";
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
570
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.
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
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.
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
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
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
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";
577
578
579
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
call
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.
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
583
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.
584
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).
Prerequisites
v An EGL project
v An EGL program or other logic part that needs debugging
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.
586
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.
Compatibility
Table 57. Compatibility considerations for hot swapping
Platform
Issue
Rich UI
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
588
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.
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.
590
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.
591
592
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.
594
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.
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.
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
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.
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
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.
To
Add a jobcard
SYSLIB
#dbctlid
XXXX
MAXTHRD=99
CNBA=0
(FPBUF+FPBOF)*MAXTHREAD **
FPBUF=0
FPBOF=0
TIMEOUT=60
AGN=IVP
//SYSLMOD DD
DSN=ELA.V6ROM1.SELADBGL
NAME DFSIVP10(R)
597
X
X
X
X
X
X
X
X
X
X
X
X
X
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
//
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))
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 dont 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
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
-V
-n
-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
601
//*
//STDOUT
//STDERR
//CCUBLOG
DD SYSOUT=*
DD SYSOUT=*
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=*
602
Code
Brazilian Portugese
ptb
Chinese, simplified
chs
Chinese, traditional
cht
English, USA
enu
French
fra
German
deu
Language
Code
Italian
ita
Japanese
jpn
Korean
kor
Spanish
esp
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.
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
604
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
systems 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 environments 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.
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.
606
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
dont 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
607
608
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 users 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
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 IBMs 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
If you are viewing this information softcopy, the photographs and color
illustrations may not appear.
Appendix. Notices
611
612
Index
A
add EGL keyword
records 184
Ajax
defined 327
AJAX requests
EGL Web pages 432
external requests 442
refresh requests 436
submit requests 439
applications
debugging in EGL 573, 579, 587
EGL artifacts 67
EGL cheat sheets 166
EGL Console UI 513, 528
EGL deployment descriptor files 94
argument stack
C functions 141
ArrayDictionary EGL data part 102
arrays
EGL data parts 103
asynchronous tasks (EGL) 266
B
basic programs
in IMS (EGL) 308
BasicLibrary
Library stereotype 111
bidirectional language text
conversion 245
BIGINT data type
C functions 138
binding functions
EGL shortcuts 407
bindings
JSF controls to EGL elements 394
JSPs 389
variables to services 491
BIRT reports
adding support to projects 553
breakpoints
EGL debugger 584
build control part
description 120
build descriptor options
EGL version 7.0 changes 35
EGL version 7.1 changes 16
genReturnImmediate (EGL) 261
IMS generation (EGL) 310
spaADF in IMSADF II (EGL) 293
spaSize (EGL) 276
spaStatusBytePosition (EGL) 276
synchOnPgmTransfer (EGL) 262
build descriptor part
description
description 120
build descriptors
EGL debugger 583
preferences 174
Copyright IBM Corp. 1996, 2008
520
C
C
mapping data to EGL 132
C data types
EGL primitive types compared 145
C functions
invoking 136
using with EGL 133
C functions in EGL
BIGINT 138
DATE 139
DATETIME 139
DECIMAL 140
INTERVAL 139
pop functions 141
return functions 144
calls
Java from EGL 128
cancelOnPageTransition EGL
property 411
capabilities
enabling for EGL 11
catcher program (EGL) 301
character encoding
EGL debugger options 603
character types
EGL primitives 98
cheat sheets
opening in EGL 166
check boxes
EGL Console UI elements 522
user input in EGL 404
CICS
asynchronous tasks (EGL) 266
RETURN IMMEDIATE 265
START 264
CICSOSLINK (EGL) 258
clients
EGL binding 487
COBOL
CALLs (EGL) 268
code generation
EGL
data access 183
debugging 591
JSF data table properties 463
JSF image sizes 461
JSF input functions 462
source code editor 127
SQL statements 190
code snippets
inserting 165
overview 164
retrieving row values 417
setting focus 418
testing for session variables 425
updating table rows 423
code templates
creating 160
disabling 159
editing 161
enabling 159
exporting 162
importing 162
naming considerations 158
overview 158
removing 163
restoring defaults 163
combination boxes
EGL Console UI elements 524
commands
EGL debugger 580
COMMAREA pointer parameter
format 256
COMMDATA parameter format 257
comments
EGL source code
code lines 128
COMMPTR parameter format 256
Console UI
building EGL applications 513
creating 516
EGL elements 513
elements
button widgets 520
check boxes 522
user input 524
modes
running EGL applications 529
rich client widgets 519
running EGL applications 528
constant fields
creating in EGL
Text UI 502
container-managed security 452
content assist
EGL overview 157
control transfer
JSF Handlers 569
create function
add EGL keyword 184
613
curses mode
overview
529
D
data
forwarding between Web pages 410
data access
EGL code 183
data access applications
creating with EGL 208
data conversion
bidirectional language text 245
data parts
EGL arrays 103
EGL miscellaneous 102
EGL overview 97
EGL version 7.0 28
EGL version 7.1 14
data processing tasks
overview 183
data table check boxes
selecting rows in EGL 404
data tables
retrieving row values 417
data types
mapping EGL to C 132
database connections
preferences 219
SQL
changing 205
creating 197
runtime connections 203
database options
EGL specifications 189
databases
creating EGL data access
applications 208
EGL SQL support 200
DataItem parts
editing 167
dataItems EGL data parts 97
DataTable EGL data part 102
DATE data type
C functions 139
date types
EGL primitives 98
DATETIME data type
C functions 139
debug servers
DLI 601
debugger
breakpoints in EGL 584
build descriptors 583
character encoding options in
EGL 603
creating a launch configuration 588
creating a Listener launch
configuration 589
EGL commands 580
EGL overview 573, 579
EGL preferences 604
EGL Web projects 592
hotswapping 587
invoking from EGL generated
code 591
preparing servers 592
614
debugger (continued)
starting a Web session 594
starting EGL programs 590
starting in EGL 588
stepping through programs 575
viewing variables in EGL 585
debugging
DL/I 596
IMS 596
services 595
DECIMAL data type
C functions 140
deferred message switch
in IMSADF II (EGL) 293
Delegate parts
syntax 117
delete EGL keyword
basic I/O functions 184
delete function
delete EGL keyword 184
deployment descriptor files
adding information 496
EGL applications 94, 120
EGL Web projects 389
shared protocols 497
design document for reports
JasperReports 534
development workbench
overview 1
device input format (DIF)
estimating size 318
device output format (DOF)
estimating size 318
Dictionary EGL data part 102
DL/I
basic concepts (EGL) 221
debugging 596
examples (EGL) 227
secondary index (EGL) 230
DLI
starting debug servers 601
E
editors
EGL
content assist 157
overview 155
locating source files 172
preferences
folding 176
imports 178
setting 175, 177
EGL migration
previous version 38
EGL source file
creating 90
EGL version 6.0 iFix 001
migration 56
migration tool changes 57
property changes 60
EGL version 7.0
build descriptor option changes
exception handling 36
interface updates 37
language changes 19
manual changes 54
35
facets
adding 76
overview 76
projects 76
FastPath in IMS
generating programs for (EGL) 308
features
adding 76
overview 76
projects 76
file I/O
writing and reading 186
File Search view
EGL 168
files
build
overview 89
comma-separated value files 186
EGL
searches 168
source code editor 127
EGL application artifacts 67
sequential files 186
sharing in EGL 79
folders
creating source folders in EGL 87
EGL application artifacts 67
folding
preferences 176
fonts
preferences 176
form fields
setting focus 418
form parts
creating 502
editing 500
filtering 509
templates 505
form variables
creating with EGL parts
Text UI 503
FormGroup EGL data part 102
FormGroup parts
editing 500
bidirectional text preferences 511
display options 510
palette preferences 512
preferences 510
forms
displaying records in EGL 507
inserting variables with EGL
Text UI 503
popup forms in EGL 506
popup menus in EGL 507
functions
binding JSF buttons in EGL 395
EGL
binding JSF controls 394
commands when pages load 411
overloaded 107
overview 107
G
generatable parts
EGL
description 96
generation
eglpath 83
preferences 180
generation process
controlling 120
get EGL keyword
handling records 184
GSAM files
PCB associations (EGL)
309
H
handler parts
creating 541, 555
Handler parts
creating Web pages in EGL
handlers EGL logic parts
overview 105
I
I/O functions
EGL records
184
392
Jasper reports
adding support to projects 549
application elements in EGL 533
JasperReports
XML design document 534
Java
EGL calls 128
ExternalType EGL part 117
JavaScript functions
JSF control event handlers 460
JavaServer Faces (JSF)
binding buttons to EGL
functions 395
binding controls to EGL
elements 394
binding single-select controls to EGL
variables 401
changing image sizes with EGL
code 461
component interface support 464
controls
accessing in EGL 454
binding to services in EGL 407
EGL variables 397
event handlers 460
L
language changes
EGL version 7.0 19
EGL version 7.1 14
language elements
EGL external mappings 117
large object types
EGL primitives 98
launch configurations
explicit 588
Listener 589
viewing implicitly created
configurations 590
LDAP
EGL support 190
library EGL logic part
description 105
Library part
overview 110
stereotypes
BasicLibrary 111
link edit part
description 120
linkage options
in transfer of control 251
linkage options part
description 120
linkage options parts
and IMS transaction codes (EGL)
list boxes
EGL Console UI elements 524
List view
EGL parts 170
local services
calling 483
localization
resource bundles 430
Web applications 426
logic parts
Delegate syntax 117
EGL functions 107
Index
301
615
M
manual changes
EGL version 7.0 54
menus
creating popups in EGL 507
enabling capabilities in EGL 11
message input descriptor (MID)
estimating size 318
format (EGL) 289
message output descriptor (MOD)
estimating size 318
format (EGL) 289
message queues
print files as (EGL) 322
serial files as (EGL) 320
message switches
in IMS/VS (EGL) 275
in IMSADF II (EGL) 293
migrating
EGL previous version 38
migrating EGL code
version 6.0 iFix 001 56
version 7.0 43
manual changes after
migration 54
migration
preferences
EGL-to-EGL 42
migration tool
EGL version 7.0 44
migration tool changes
EGL version 6.0 iFix001 57
move statements
EGL version 7.0 migration 44
moving parts
EGL 121
MPP (message processing program)
generating programs for (EGL) 307
N
navigation rules
EGL Web pages 408
null
testing for in SQL (EGL)
numeric types
EGL primitives 98
616
196
O
onConstructionFunction EGL
function 411
onPostRenderFunction EGL function 411
onPreRenderFunction EGL function 411
OSLINK parameter format 257
overloaded functions 107
P
packages
creating 89
import statements 124
overview 87
Page Designer
bindings 389
support 389
page lifecyles
EGL functions 411
pages
commands when pages load 411
parts
EGL
ExternalType 117
Record parts 100
searches 168
version 7.0 28
version 7.1 14
generatable in EGL
description 96
introduction 95
properties
introduction 122
references 171
renaming in EGL 120
searching for 168
viewing lists in EGL 170
Parts List view
EGL 168
Parts Reference view
EGL
generatable logic parts 171
searches 168
passwords
encryption in EGL 146
pop functions
C 141
popup forms
creating in EGL 506
popup menus
creating in EGL 507
preferences
build descriptors 174
EGL
debugger 604
setting 173
Web applications 465
EGL editor
folding 176
formatter 177
import organization 178
overview 175
fonts 176
generation 180
overview 172
Rich UI 345
preferences (continued)
Rich UI appearance 347
services 498
source styles 179
SQL database connections 219
SQL retrieve 220
text
EGL overview 180
Text UI
editor 510
editor bidirectional text 511
editor palette 512
primitive types
C data types compared 145
mapping EGL to C 132
primitives
EGL data parts 97
EGL data types 98
print forms
displaying records in EGL 507
procedures
calling in EGL 212
Program Communication Block (PCB)
in DL/I (EGL) 221
program EGL logic part
description 105
program parts
Interface 115
service 113
Program Specification Block (PSB)
in DL/I (EGL) 221
scheduling (EGL) 301
program-to-program message switches
in IMS/VS (EGL) 275
in IMSADF II (EGL) 293
programming tasks
completing in EGL 127
programs
EGL debugger 575
starting in the EGL debugger 590
Project Explorer view
EGL 168
Project Interchange
project sharing 81
projects
adding BIRT reports support 553
adding Jasper reports support 549
converting to EGL plug-in 74
creating
EGL plug-in 74
EGL Web 73
overview 71
debugging in EGL 588
EGL application artifacts 67
EGL database options 189
facets 76
features 76
features and facets 76
linking in the EGL build path 84
new EGL projects 173
overview 70
renaming 75
sharing in EGL
overview 79
repositories 82
properties
changes in EGL version 6.0 iFix 001
migration 60
changing JSF data tables with EGL
code 463
EGL
cancelOnPageTransition 411
introduction 122
JSF Handler for data transfer 410
PSB
scheduling (EGL) 301
R
radio button group widget
EGL Console UI 524
read function
get EGL keyword 184
record arrays
binding JSF controls to EGL
variables 401
Record EGL part 100
Record parts
SQL
using (EGL) 193
Record stereotype
EGL parts 100
records
displaying in EGL forms 507
EGL data parts 97
EGL read/write functions 184
refactoring
deleting EGL source files 93
moving EGL parts 121
moving EGL source files 92
renaming EGL parts 120
renaming EGL projects 75
renaming EGL source files 91
remote services
calling 486
renaming parts
EGL 120
replace EGL keyword 184
report design files
compiling in EGL 533
report driver program
functions in EGL 533
report handler
creating 541, 555
subreports 547
report handler EGL logic part 533
reports
code for invoking reports 538
creating Jasper reports with EGL
creating with EGL 531
exported file formats 538
exporting 538
running 545
templates for 546
writing report-driver code 538
repositories
sharing EGL projects 82
resource associations
setting up in EGL 186
resource associations part
description 120
resource bundles
creating 430
locales 431
overview 426
retrieval
data processing tasks 183
retrieve feature
SQL 205
retrieve preferences
SQL 220
return functions
C 144
Rich Client Platform (RCP) mode
EGL overview 529
rich client widgets
EGL Console UI 519
Rich UI
applications 357
authentication 353, 359, 367
authorization 353, 368
confidentiality 355
criteria 369, 371
EGL preferences 345
errors 374
example 369
IBM Rational AppScan 386
JEE 369, 374
JSF 357, 362
overview 327, 352
proxy 359, 360
resources 355
security 352, 353, 355, 357, 358, 359,
360, 361, 362, 364, 366, 367, 368, 369,
371, 372, 373, 374, 376, 377, 378, 380,
381, 385, 386
SSL 377, 378, 380, 381, 385, 386
threats 376
Tomcat 373
URL patterns 358
user 364, 366
Web services 361
WebSphere 372, 373, 374
Rich UI appearance
EGL preferences 347
right justification
variables 146
runtime messages
customizing EGL system
messages 152
S
532
Search view
EGL 168
searches
EGL items 168
secondary index
in DL/I (EGL) 230
security
container managed 452
LDAP 190
Web applications 452
servers
EGL Web page previews 448
preparing for debugging 592
service EGL logic part
description 105
617
T
templates
creating in EGL 160
disabling in EGL 159
editing in EGL 161
EGL naming considerations
EGL overview 158
enabling in EGL 159
exporting from EGL 162
importing in EGL 162
618
templates (continued)
removing in EGL 163
restoring defaults in EGL 163
text
localizing 426
preferences
setting in EGL 180
Text Form editor
filtering
Text UI 509
overview 500
Text UI
bidirectional text preferences 511
display options 510
palette preferences 512
preferences 510
text forms
displaying records in EGL 507
text strings
constant fields in EGL
Text UI 502
Text UI
editor
bidirectional text preferences 511
display options 510
palette preferences 512
preferences 510
Text UI programs
in IMS (EGL) 307
time types
EGL primitives 98
trademarks 611
transferring control
CICS environment
using call (EGL) 254
using transfer statement
(EGL) 261
IMS BMP environment
using transfer statement
(EGL) 270
IMS BMP environments
using call (EGL) 267
IMS/VS environments
using call (EGL) 267
using transfer statement
(EGL) 275
in IMS/VS (EGL) 291
in z/OS batch (EGL) 267
iSeries environment (EGL) 299, 300
Java programs (EGL) 300
overview 251
z/OS batch environment
using transfer statement
(EGL) 270
type-ahead
Web applications 413
U
158
529
user interface
EGL version 7 updates 37
EGL version 7.1 updates 17
user interface (UI) parts
editing 500
JSF Handler
EGL preferences 465
user interfaces
EGL console 516
user sessions
data storage for EGL Web pages
424
V
validation
changes in EGL version 7.0 24, 26
validation changes
EGL version 7.0 24, 26
variable fields
creating with EGL parts
Text UI 503
variables
binding JSF controls to EGL
elements 394
binding JSF controls to EGL
variables 401
binding to services 491
EGL
arrays 103
binding to Web page controls 397
viewing in the EGL debugger 585
VGWebTransactions EGL part
forwarding control 569
VisualAge Generator
compatibility preferences 173
VisualAge Generator Web transactions
forwarding control in EGL 569
W
Web applications
debugging in EGL 588
EGL debugger 592
EGL elements 389
EGL preferences 465
EGL tasks 391
Page Designer 389
security 452
Web diagrams
EGL Web projects 389
Web page controls
binding to EGL variables 397
Web pages
AJAX requests 432
external requests 442
refresh requests 436
submit requests 439
creating in EGL 392
EGL commands when pages
load 411
forwarding data 410
navigation rules in EGL 408
previewing EGL pages 448
session data storage with EGL 424
Web projects
EGL elements 389
464
X
XML report design document
creating 534
Index
619
620
Printed in USA