Professional Documents
Culture Documents
Com Ibm Etools Egl PG PDF
Com Ibm Etools Egl PG PDF
Com Ibm Etools Egl PG PDF
This edition applies to version 7.1 of Rational Business Developer and to all subsequent releases and modifications
until otherwise indicated in new editions.
© Copyright International Business Machines Corporation 1996, 2008.
US Government Users Restricted Rights – Use, duplication or disclosure restricted by GSA ADP Schedule Contract
with IBM Corp.
Contents
Introduction . . . . . . . . . . . . . 1 Introduction to data parts . . . . . . . . 97
Using EGL with the Eclipse IDE . . . . . . . . 1 Introduction to logic parts . . . . . . . . 105
A typical EGL development workbench . . . . 2 Introduction to build parts . . . . . . . . 120
Other windows EGL developers commonly use. . 4 Renaming parts . . . . . . . . . . . 120
Other views and editors EGL developers Moving parts . . . . . . . . . . . . 121
commonly use . . . . . . . . . . . . . 5 Properties . . . . . . . . . . . . . . 122
How the workbench is organized . . . . . . 9 Import and use statements . . . . . . . . . 124
Other information on the workbench . . . . . 11
Enabling EGL capabilities. . . . . . . . . . 11 Working with EGL code . . . . . . . 127
What’s new in EGL V7.5 . . . . . . . . . . 12 Common programming tasks . . . . . . . . 127
What’s new in EGL V7.1 . . . . . . . . . . 13 Turning lines of code into comment lines . . . 128
Language changes in EGL V7.1 . . . . . . . 14 Calling Java . . . . . . . . . . . . . 128
Changes to parts in EGL V7.1 . . . . . . . 14 Calling C functions with the call statement . . 131
Changes to system libraries and variables in EGL Calling C functions through EGL libraries . . . 133
V7.1 . . . . . . . . . . . . . . . . 15 Working with substrings . . . . . . . . 146
Changes to build descriptor options in EGL V7.1 16 Encrypting passwords . . . . . . . . . 146
User interface changes in EGL V7.1 . . . . . 17 Handling errors . . . . . . . . . . . 148
What’s new in EGL V7.0 . . . . . . . . . . 18 Customizing runtime messages . . . . . . 152
Language changes in EGL V7.0 . . . . . . . 19 The EGL editor . . . . . . . . . . . . . 155
Validation changes in EGL V7.0 . . . . . . 24 Content assist . . . . . . . . . . . . . 157
Validation changes in EGL V7.0 . . . . . . 26 Code templates. . . . . . . . . . . . 158
Changes to parts in EGL V7.0 . . . . . . . 28 Code snippets . . . . . . . . . . . . . 164
Changes to system libraries and variables in EGL Inserting code snippets into EGL and JSP files 165
V7.0 . . . . . . . . . . . . . . . . 32 Using cheat sheets. . . . . . . . . . . . 166
Changes to build descriptor options in EGL V7.0 35 Editing DataItem parts with the source assistant 167
Changes to exception handling in EGL V7.0 . . 36 Searching for EGL files and parts . . . . . . . 168
Changes to services in EGL V7.0 . . . . . . 36 Searching for parts . . . . . . . . . . 168
User interface changes in EGL V7.0 . . . . . 37 Viewing lists of parts . . . . . . . . . . 169
Migrating from a previous version of EGL . . . . 38 Viewing part references . . . . . . . . . 171
Setting EGL-to-EGL migration preferences . . . 42 Locating an EGL source file in the Project
Migrating EGL code to EGL V7.0 . . . . . . 43 Explorer view . . . . . . . . . . . . 172
Migrating EGL code to EGL V6.0 iFix 001 . . . 56 Preferences . . . . . . . . . . . . . . 172
Setting general preferences . . . . . . . . 173
Contents of an EGL application . . . . 67 Setting build descriptor preferences . . . . . 174
Introduction to EGL projects . . . . . . . . . 70 Setting preferences for the EGL editor . . . . 175
Creating an EGL project . . . . . . . . . 71 Setting the fonts used in the EGL editor . . . 176
Creating an EGL Web project . . . . . . . 73 Setting preferences for folding in the EGL editor 176
Creating an EGL plug-in project . . . . . . 74 Setting preferences for formatting in the EGL
Renaming an EGL project. . . . . . . . . 75 editor . . . . . . . . . . . . . . . 177
Features and facets of EGL projects . . . . . 76 Setting preferences for organizing import
Sharing projects . . . . . . . . . . . . 79 statements in the EGL editor . . . . . . . 178
The EGL build path . . . . . . . . . . 83 Setting preferences for source styles . . . . . 179
Source folders . . . . . . . . . . . . . 86 Setting generation preferences . . . . . . . 180
Creating source folders . . . . . . . . . 87 Setting preferences for EGL text . . . . . . 180
Introduction to EGL packages . . . . . . . . 87
Creating an EGL package . . . . . . . . . 89 Accessing data with EGL code . . . . 183
Introduction to EGL files . . . . . . . . . . 89 Common data access tasks . . . . . . . . . 183
Creating EGL source files . . . . . . . . . 90 Reading and writing records . . . . . . . 184
Renaming a source file . . . . . . . . . 91 Writing and reading to files . . . . . . . 186
Moving a source file . . . . . . . . . . 92 Specifying database options at project creation 189
Deleting a source file . . . . . . . . . . 93 Accessing an LDAP-compliant server . . . . 190
Creating EGL build files . . . . . . . . . 94 Working with SQL data . . . . . . . . . . 190
Creating a deployment descriptor . . . . . . 94 Best practices . . . . . . . . . . . . 191
Introduction to EGL parts . . . . . . . . . 95 Result-set processing . . . . . . . . . . 192
Generatable parts and non-generatable parts . . 96 SQL records and their uses . . . . . . . . 193
Contents v
Elements of an EGL JasperReport application 533 Using breakpoints in the EGL debugger . . . . 584
Creating the JasperReport design file . . . . 534 Viewing variables in the EGL debugger . . . . 585
Writing code to drive a report of type Prerequisites. . . . . . . . . . . . . 585
JasperReport. . . . . . . . . . . . . 538 Variables and breakpoints . . . . . . . . 585
Creating an EGL JasperReport handler . . . . 541 Displaying and changing values . . . . . . 585
Running a report of type JasperReport . . . . 545 Buttons in the Variables view . . . . . . . 586
Using JasperReport templates . . . . . . . 546 Making code updates while debugging an
Creating JasperReport subreports . . . . . . 547 application . . . . . . . . . . . . . . 587
Adding support for Jasper reports to a project 549 Starting the EGL debugger for EGL projects . . . 588
Creating reports with BIRT . . . . . . . . . 551 Creating a launch configuration in the EGL
Adding support for BIRT reports to a project 553 debugger . . . . . . . . . . . . . . 588
Creating an EGL BIRT handler . . . . . . 555 Creating an EGL Listener launch configuration 589
Creating EGL text reports . . . . . . . . . 556 Starting a non-JEE application in the EGL
Handler events for a text report . . . . . . 557 debugger . . . . . . . . . . . . . . 590
Writing code to print a text report . . . . . 558 Invoking the EGL debugger from generated
Java code . . . . . . . . . . . . . . 591
Working with Web transaction Debugging Web projects with the EGL debugger 592
applications in EGL. . . . . . . . . 561 Configuring a server for EGL Web debugging 592
Starting an EGL Web debugging session . . . 594
Customizing JSP files . . . . . . . . . . . 561
Debugging services with the EGL debugger . . . 595
Adding Web transaction support to an EGL Web
Prerequisites. . . . . . . . . . . . . 595
project. . . . . . . . . . . . . . . . 562
Debugging a local service . . . . . . . . 595
Web transaction configuration files . . . . . . 563
Debugging IMS and DL/I applications . . . . . 596
Running VGWebTransaction programs . . . . . 564
Prerequisites. . . . . . . . . . . . . 596
Using VGUIRecord properties . . . . . . . . 564
Host configuration . . . . . . . . . . 597
Other controls . . . . . . . . . . . . 566
Local workspace configuration . . . . . . 599
Using JavaServer pages with Web transactions . . 567
Starting the DLI Debug Server on the z/OS host 601
Transferring control between JSF Handlers and
Character encoding options for the EGL debugger 603
Web transactions . . . . . . . . . . . . 569
Setting preferences for the EGL debugger . . . . 604
UI record bean API . . . . . . . . . . . 570
General preferences . . . . . . . . . . 605
Debug behavior mapping . . . . . . . . 606
Debugging EGL applications . . . . . 573
Stepping through an application in the EGL
Appendix. Notices . . . . . . . . . 609
debugger . . . . . . . . . . . . . . . 575
Programming interface information . . . . . . 611
Debugging an EGL batch program . . . . . . 579
Trademarks and service marks. . . . . . . . 611
EGL debugger commands . . . . . . . . . 580
How build descriptor settings affect the EGL
debugger . . . . . . . . . . . . . . . 583 Index . . . . . . . . . . . . . . . 613
While developing EGL applications, you use the workbench to manage your files,
write your code, and test and deploy your application. The workbench includes
code editors similar to editors for other programming languages, but it also
includes a range of graphical tools for working with EGL code and the many other
types of code and files that the workbench understands.
Eclipse gives you the ability to change the set of tools that it offers and choose
which tools appear in the interface. Each different tool set is called a perspective,
and the windows within a perspective are called views and editors. You will learn
more about these concepts later in this topic.
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
Introduction 3
In the previous image, the Generation Results view is ″stacked,″ or hidden behind
the Problems view. You can switch to a hidden view by clicking the tab with the
name of the view you want, which brings that view to the top of the stack. You
can also double-click the name of a view to expand that view to fill the
workbench. Double-clicking the name again will return the view to its original
size.
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
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 5
EGL Parts Reference view
The EGL Parts Reference view shows a hierarchical view of the parts
referenced in a generatable logic part. To open a part in the Parts Reference
view, right-click the file that contains the part in the Project Explorer view and
then click Open in Parts Reference. See “Viewing part references” on page 171
for details.
EGL Parts List view
The Properties view provides detailed information on a specific object that you
have selected in an editor. For example, if you have a Web page open in Page
Designer and you select a text output field on that Web page, the Properties
Introduction 7
view shows you information such as the style applied to the field, where its
content comes from, and its other characteristics.
Palette view
The Palette view works alongside WYSIWYG editors. The Palette lists objects
that you can drag into the editor, creating new objects in the open file.
Snippets view
The Snippets view works alongside code editors. The Snippets view holds
reusable pieces of code that you can drag into your code. You can also create
new snippets for code that you use often.
Console view
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 9
available, which in turn makes tools available for working with EGL code.
See “Enabling EGL capabilities” on page 11.
Perspectives
A perspective is a group of views and editors that are all shown on the
screen at once. For example, when you open the Web perspective by
clicking Window → Open Perspective → Other → Web, you see tools for
building Web sites. There are other perspectives for working with data
sources, debugging code, and testing.
The perspectives available to you depend on the capabilities enabled in
your workbench. For example, if the Tester capability is disabled, you will
not see the Test perspective as an option in Window → Open Perspective →
Other.
You can switch perspectives at any time without losing your work, and
you can have as many perspectives open as you want. Often, developers
switch between perspectives as they perform different tasks. To switch
between perspectives, open the perspectives you want with Window →
Open Perspective → Other or click a perspective’s icon in the Perspectives
bar, which is typically at the top right corner of the workbench.
You can also create customized perspectives that show only the tools you
want. To create a customized perspective, open an already existing
perspective and tailor it to your needs by repositioning its views and
editors and opening or closing views and editors. Then, click Window →
Save Perspective As and type a name.
Views When you open a perspective, the views associated with that perspective
are displayed in the workbench. Each view performs a specific purpose,
such as displaying certain information or giving access to a specific tool.
The purpose of each view varies widely, but in general, views give you
access to a specific area of your workspace. Some views, such as the
Project Explorer, Navigator, and Package Explorer views, show the files,
projects, and packages in your workspace, enabling you to open files or
reorganize projects. Other views, such as the Outline and Properties views,
give information about a file you are currently viewing in an editor.
Finally, some views, such as the Problems view and the Console view,
display information about the status of your projects.
Views are flexible; you can move them around the workbench, resize them,
minimize or maximize them, stack them on top of other views, or close
them. To close a view, click the X at the top of the view. To open a view,
either open a perspective that contains that view or click Window → Show
View and click the name of a view. You can have as many views open as
you want, but it is best to organize your views into one or more
perspectives.
Editors
Editors look like views, but editors are designed to change a particular
type of file. Some editors, like the EGL code editor, look and work just like
code editors for many other programming languages, although the EGL
code editor has additional features for working with EGL code.
Other editors are graphical, with drag-and-drop tools or
what-you-see-is-what-you-get (WYSIWYG) preview tools. For example,
with Page Designer you can edit a Web page by clicking and typing
directly in the Web page. You can also drag Web page elements onto the
page from views such as the Palette view.
For EGL, capabilities hide the EGL-related views and the EGL perspective, items in
the pop-up menus and menus for creating new files, and the code templates
available when you use content assist.
Introduction 11
d. Click OK.
5. Normally, the workbench warns you before you use functionality that belongs
to a disabled capability. If you clear the check box labeled Prompt when
enabling capabilities, the workbench will automatically enable any capabilities
that you try to use.
6. To save your changes, click Apply, then click OK.
Some capabilities have prerequisites. For this reason, enabling EGL capabilities
may automatically enable other capabilities that are required to develop and debug
EGL applications.
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
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.
EGL generated programs for CICS can be called with channels and containers.
Batch applications can now use remote CICSEXCI calls to communicate with CICS.
VSE support
You can purchase an extension that enables the generation of EGL as COBOL
source that can be compiled and deployed to z/VSE™.
The following areas of functionality that were removed in V7.0 are returned in this
version:
v Text User Interface, including FormGroups, the Text Form editor, the system
library ConverseLib, and the ConverseVar system variable
v DL/I, IMS™, and GSAM data access, including the system library DLILib and
the DLIVar system variable
v WebSphere MQ data access
v Web transactions
v VisualAge® Generator migration tool
v The statement exit stack
v Java™ wrapper generation, including the ejbCall type of the callLink element of
the linkage options part
Build descriptor options related to these areas of functionality are returned; see
“Changes to build descriptor options in EGL V7.1” on page 16.
System libraries and variables related to these areas of functionality are returned;
see “Changes to system libraries and variables in EGL V7.1” on page 15.
EGL assumes that EGL V6 users with forms did not migrate to V7, so there is no
migration program to move from V7 to V7.1. However, if you use forms and you
migrated to V7, you must make the following changes in your code by hand:
v Add the @ operator to all printFloatingArea and screenFloatingArea properties.
v Place all of the @printFloatingArea complex properties for a form inside the
new printFloatingAreas property.
v Place all of the @screenFloatingArea complex properties for a form inside the
new screenFloatingAreas property.
BIRT reports
EGL can now generate reports with BIRT. See “Creating reports with BIRT” on
page 551.
J2EE security
Introduction 13
LDAP data access
EGL provides a code sample that you can customize to retrieve security or other
details from a server accessed by way of Lightweight Directory Access Protocol
(LDAP). See Sample: EGL LDAP access.
Related concepts
“Language changes in EGL V7.1”
This topic lists the changes to the EGL language in version 7.1.
“Changes to build descriptor options in EGL V7.1” on page 16
“Changes to system libraries and variables in EGL V7.1” on page 15
“Changes to parts in EGL V7.1”
This topic lists the major changes to EGL parts in this version.
“User interface changes in EGL V7.1” on page 17
The syntax for floating area properties in FormGroups has changed. A new
property, printFloatingAreas, now contains multiple @printFloatingArea complex
properties. Similarly, the new screenFloatingAreas property now contains multiple
@screenFloatingArea complex properties.
The following system libraries and variables are available in this version. See
“Return of features that were unsupported in V7.0” on page 13.
v ConverseLib
v ConverseVar
v DLILib
v DLIVar
See the EGL Language Reference for information on these libraries and variables.
Introduction 15
“Changes to system libraries and variables in EGL V7.0” on page 32
The following build descriptor options were not available in version 7.0 but are
available in version 7.1. For details on the functionality that was returned, see
“Return of features that were unsupported in V7.0” on page 13.
Introduction 17
What’s new in EGL V7.0
Several new features have been added in this version:
v Language enhancements
v Expanded support for services, including iSeries® COBOL and CICS services
v Support for model-driven development, including the ability to transform UML
to EGL
v Addition of rich client widgets to EGL Console UI
v Improvements to the user interface
v Improvements to the documentation
v Improved performance, particularly for building projects, generating Java or
COBOL, and Java runtime.
v Libraries can now be generated for iSeries COBOL
v Support for AJAX requests (version 7.0.0.3)
Model-driven development
This version of EGL allows you to plan an application with a UML model and
then create starter EGL code from the UML model. Generally, model-driven
development with EGL follows these steps:
1. You plan your application with a UML model. EGL does not include
functionality for editing UML models graphically.
2. You associate the UML model with a transformation parameters model (TPM)
file. This file specifies which transformations will be used on the UML model
and how those transformations will be applied. The EGL Application
Transformation allows you to transform UML into EGL. Depending on what
products you have installed, you may have other transformations available, but
these transformations will not create EGL code.
3. Using the transformation parameters editor, you edit the parameters associated
with the EGL application transformation to describe what the resulting EGL
code will look like. Depending on what products you have installed, you may
have other transformations available, but these transformations will not create
EGL code.
4. You run the transformation to apply the transformation parameters to the UML
model and create EGL code.
In this release, EGL contains support for rich client widgets in Console UI. These
widgets allow you to add mouse support to your Console UI applications, as well
as graphical input fields like check boxes and buttons. Developing an application
with these widgets is similar to developing an ordinary Console UI application,
but you must run the application in RCP mode, rather than the standard mode for
AJAX support
Beginning with version 7.0.0.3, EGL-controlled Web pages can issue AJAX requests,
allowing you to update a portion of a page without refreshing the entire page. To
create an AJAX request, you indicate an area on the page to be updated, specify a
user action to trigger the update, and add code to the page’s JSF Handler to
process the update. See “Updating portions of a Web page with AJAX requests” on
page 432.
The following topics deal with major changes in this version of EGL.
Related Concepts
“Language changes in EGL V7.0”
This topic lists the changes to the EGL language in version 7.0.
“Validation changes in EGL V7.0” on page 24
“Changes to parts in EGL V7.0” on page 28
This topic lists the EGL parts and describes their major changes in this version.
“Changes to system libraries and variables in EGL V7.0” on page 32
“Changes to build descriptor options in EGL V7.0” on page 35
“Changes to exception handling in EGL V7.0” on page 36
This topic covers changes to the way EGL deals with exceptions in version 7.0.
“Changes to services in EGL V7.0” on page 36
“User interface changes in EGL V7.0” on page 37
Documentation changes in EGL V7.0
Related tasks
“Migrating from a previous version of EGL” on page 38
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?;
Introduction 19
Similarly, you can test to see whether a variable is null by comparing it
to the value NULL:
if (myVar == NULL)
...
end
Because you can now assign a null value and compare to a null value,
the following expressions are no longer used:
– SET myVar NULL
– if (myVar is NULL)
v NIL is no longer a valid literal to represent a null value. Use NULL
instead.
v The itemsNullable build descriptor option is no longer used. In its place
is the I4GLItemsNullable property, which can be put on programs,
libraries, handlers, and records for migration purposes. This property
places an implicit question mark on each primitive variable, constant,
and parameter in the part, making them all nullable.
v When a variable is made nullable with an explicit question mark, that
variable is initially null. When a variable is made nullable by
I4GLItemsNullable, the initial value of that variable depends on the
type of variable.
v The nullable modifier on function parameters is now sqlNullable.
v The isNullable property is now isSQLNullable.
v System functions have rules to deal with nullable variables. In most
cases, if you pass a null variable to a system function, the function will
return a null value. However, the behavior of each function differs with
respect to nullable parameters and return values. See the reference
information for the specific function for information on how it deals
with nullable variables.
v When concatenating string variables, a null value is treated as an empty
string.
For more information on nullable variables, see the topics ″Null values and
the nullable type″ and ″i4glItemsNullable″ in the EGL Language Reference.
Statements
New operators
v The new concatenation operator (::) concatenates two variables as
though those variables were strings. When used with text variables, it
works like the + operator:
myString1 string = "Hello ";
myString2 string = "everyone!";
SysLib.writeStderr(myString1 :: myString2);
SysLib.writeStderr(myString1 + myString2);
//writes "Hello everyone!" to the console twice
The following example shows the new syntax for the same task:
if(a in myArray from 4)
Conversion enhancements
You can now assign a STRING directly to a DECIMAL, FLOAT, or INT.
This ability removes the need for functions such as
MathLib.stringAsDecimal().
Change in rounding behavior
In previous versions, when you assigned a variable to a target variable
with fewer decimal places, EGL truncated the source variable to fit into the
target variable. In EGL V7.0, these extra decimal places are rounded, not
truncated, when either of the following criteria is true:
v The truncateExtraDecimals build descriptor option is set to NO
v The type of the source variable is FLOAT or SMALLFLOAT, and the
type of the target variable is not FLOAT or SMALLFLOAT
If both of these criteria are false, EGL truncates the source variable to the
number of decimal places available in the target variable, as it did in
V6.0.1.1.
In previous versions, for the MathLib.round() system function, the second
argument (the power of 10) was optional. In EGL V7.0, the second
argument is required.
The migration tool uses the MathLib.assign() system function to replace
MathLib.round() in situations in which the power of 10 parameter was not
used.
Changes to syntax of call, transfer, and show
You can now specify the name of the target program or transaction in
these statements as a direct program reference, as a literal (in quotes), or as
a variable. The statements also use braces to group their keyword
modifiers. In addition, the call statement now uses parentheses to group
arguments. For example:
call "xxx" (1, 2) { IsNoRefresh = yes, IsExternal = yes };
transfer to program "xxx" passing yyy { IsExternal = yes};
Introduction 21
Variables
Scope of variables within functions
In previous versions of EGL, if you declared a variable within a function,
that variable was in scope for the entire function, even for statements that
preceded the variable declaration. Now, variables are in scope only for
statements that follow their declaration.
Format specifiers for INTERVAL variables
You must include a format specifier when creating an INTERVAL variable:
intval1 interval("yyyyMM");
Default representation for text literals
By default, text literals (such as "Hello!") are treated as of the type
STRING in the generated source. If you want EGL to interpret these as a
different type instead, set the new textLiteralDefaultIsString property to
NO. See textLiteralDefaultIsString.
ANY type is no longer limited to the type of its first assigned value
In previous versions of EGL, if you created a variable of the ANY type and
assigned a value to that variable, the ANY variable was permanently
limited to the type of that value. The ANY variable could store only values
compatible with that first value. In this version, the ANY variable can
accept any EGL type, regardless of what you have assigned to it
previously. You can use the as operator to cast an ANY variable
temporarily to another type, and you can use the isa operator to test what
type of data the ANY variable contains.
Web applications
Validating variables when their values change
With the onValueChangeFunction property, you can specify a function to
validate user input for a variable in a JSF Handler automatically when the
value of the variable changes. For example, the following code creates a
variable and specifies its validation function:
myInteger int {onValueChangeFunction = validateMyInt};
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
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
Introduction 23
v THROW
v WITHV60COMPAT
Importing from the default package is no longer allowed
In previous versions, you could define a part in the default package (that
is, a part in the root of an EGL source folder, with no named package
containing it) and import that part for use in a part in another package.
Now you can import parts in the default package only into other parts in
the default package.
Naming conflicts between functions and variables
Within a part, no function may have the same name as a variable.
Name resolution between fields and properties
You can use the ″at″ symbol (@) to distinguish between fields and
properties with the same name.
For example, assume an EGL Dictionary part, which a list of name-value
pairs. You use a set-value block to assign those name-value pairs; you can
use the same set-value block to assign values to properties of the
dictionary itself. The following is a declaration of a new Dictionary part:
myRef Dictionary {
displayName = "myNewDictionary"
};
Because of part resolution rules, EGL assumes that displayName =
"myNewDictionary" is a name-value pair in the new dictionary. If you want
to assign a value to the displayName property for the dictionary, you must
use an @ operator, as in the following example:
myRef Dictionary {
@displayName {"myNewDictionary"}
};
See EGL part resolution rules for more information.
Related Concepts
“What’s new in EGL V7.0” on page 18
“Validation changes in EGL V7.0”
“Changes to parts in EGL V7.0” on page 28
This topic lists the EGL parts and describes their major changes in this version.
“Changes to system libraries and variables in EGL V7.0” on page 32
“Changes to build descriptor options in EGL V7.0” on page 35
“Changes to exception handling in EGL V7.0” on page 36
This topic covers changes to the way EGL deals with exceptions in version 7.0.
“Changes to services in EGL V7.0” on page 36
“User interface changes in EGL V7.0” on page 37
Documentation changes in EGL V7.0
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
end
into clauses with ANY types
You cannot use into to put data into an ANY variable:
program myProgram
myRecord recordType;
myVariable any;
function main()
foreach(from myRecord into myVariable);// validation error
end
end
end
function main()
msInterval = msInterval + ssInterval; //validation error
end
end
Introduction 25
Parts
Service parts must have a function for every function prototype in the interfaces
it implements
When a Service part implements an Interface part, the Service part must
contain a function matching each function prototype in the Interface part.
The function names, parameter lists, and return values must match.
position property required on consoleForms that do not specify segments
property
If a Record part with the stereotype consoleForm does not specify the
position property, that Record part must specify the segments property.
JSF Handlers
Variables in JSF Handler parts with insufficient length to be displayed
Validation now recognizes variables in JSF Handlers that are not long
enough to fit the pattern specified in properties such as dateFormat and
timeFormat, as in this example:
handler myPage type JSFHandler
{view="myPage.jsp"}
myField decimal(1)
{dateFormat = "MM/dd/yyyy"}; //validation error
end
BLOB and HEX used as the value of selectFromListItem
Validation now recognizes an attempt to use BLOB and HEX variables as
the value of the selectFromListItem property in a JSF Handler.
selectFromListItem specifying a variable in another part
Validation now recognizes an attempt to use a variable in a library rather
than a variable in the same JSF Handler part as the value of the
selectFromListItem property.
Value of fillCharacter for DBCHAR and UNICODE variables
Validation now requires that the fillCharacter property be set to null or
blank on DBCHAR and UNICODE variables used in a JSF Handler
Type matching between variables in a JSF Handler and validation tables
Validation now ensures that the variables in a JSF Handler match the type
of the first column in their validation tables.
Related Concepts
“What’s new in EGL V7.0” on page 18
“Language changes in EGL V7.0” on page 19
This topic lists the changes to the EGL language in version 7.0.
“Changes to parts in EGL V7.0” on page 28
This topic lists the EGL parts and describes their major changes in this version.
Related tasks
“Migrating from a previous version of EGL” on page 38
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
end
into clauses with ANY types
You cannot use into to put data into an ANY variable:
program myProgram
myRecord recordType;
myVariable any;
function main()
foreach(from myRecord into myVariable);// validation error
end
end
end
function main()
msInterval = msInterval + ssInterval; //validation error
end
end
Introduction 27
Parts
Service parts must have a function for every function prototype in the interfaces
it implements
When a Service part implements an Interface part, the Service part must
contain a function matching each function prototype in the Interface part.
The function names, parameter lists, and return values must match.
position property required on consoleForms that do not specify segments
property
If a Record part with the stereotype consoleForm does not specify the
position property, that Record part must specify the segments property.
JSF Handlers
Variables in JSF Handler parts with insufficient length to be displayed
Validation now recognizes variables in JSF Handlers that are not long
enough to fit the pattern specified in properties such as dateFormat and
timeFormat, as in this example:
handler myPage type JSFHandler
{view="myPage.jsp"}
myField decimal(1)
{dateFormat = "MM/dd/yyyy"}; //validation error
end
BLOB and HEX used as the value of selectFromListItem
Validation now recognizes an attempt to use BLOB and HEX variables as
the value of the selectFromListItem property in a JSF Handler.
selectFromListItem specifying a variable in another part
Validation now recognizes an attempt to use a variable in a library rather
than a variable in the same JSF Handler part as the value of the
selectFromListItem property.
Value of fillCharacter for DBCHAR and UNICODE variables
Validation now requires that the fillCharacter property be set to null or
blank on DBCHAR and UNICODE variables used in a JSF Handler
Type matching between variables in a JSF Handler and validation tables
Validation now ensures that the variables in a JSF Handler match the type
of the first column in their validation tables.
Related Concepts
“What’s new in EGL V7.0” on page 18
“Language changes in EGL V7.0” on page 19
This topic lists the changes to the EGL language in version 7.0.
“Changes to parts in EGL V7.0”
This topic lists the EGL parts and describes their major changes in this version.
Related tasks
“Migrating from a previous version of EGL” on page 38
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
New parts
Changed parts
Introduction 29
For more information, see the following topics:
v “Executing commands when a page loads” on page 411
v JSF Handler part
v onConstructionFunction
v onPreRenderFunction
v onPostRenderFunction
v cancelOnPageTransition
v onValueChangeFunction
v selectType
v selectFromListItem
v selectedRowItem
v selectedValueItem
Service
The way EGL uses services has changed significantly in this version. See
“Changes to services in EGL V7.0” on page 36
The properties of the Service part have changed as follows:
v The @WSDL property is no longer used. Use @XML to interact with
WSDL files.
v The @XSD property is no longer used.
v The properties allowUnqualifiedItemReferences and
includeReferencedFunctions are now valid on Service parts.
For more information, see the following topics:
v “Changes to services in EGL V7.0” on page 36
v Service part
v Overview of EGL deployment descriptor file
v “Overview of service-oriented architecture (SOA)” on page 475
v @xml
v @bindService
Library
The serviceBindingLibrary type of Library part is no longer used. The
runtimeBind property, which was used only on this type of Library part, is
no longer needed. See the information on services and the Service part, or
one of the following topics:
v Library part
v Service part
v “Overview of service-oriented architecture (SOA)” on page 475
Interface
The Interface part no longer has stereotypes such as BasicInterface and
JavaObject. Instead of BasicInterface, use an Interface part with no
stereotype. Instead of JavaObject, use an ExternalType part. For more
information, see the following topics:
v Interface part
v ExternalType part
New properties
The following table lists new properties that can be used on multiple parts:
Table 1. New properties
Property Applicable parts
The v60ExceptionCompatibility property v Program
specifies whether the logic part uses a form
v Handler
of exception handling for compatibility with
a previous version. See v Library
v60ExceptionCompatibility. v Service
The textLiteralDefaultIsString property tells v Program
EGL how to deal with text literals to
v Handler
promote compatibility with VisualAge
Generator. See textLiteralDefaultIsString. v Library
v Service
v Record
The i4glItemsNullable property determines v Program
whether a record emulates the behavior of
v Handler
I4GL in creating variables as nullable by
default. It replaces the itemsNullable build v Library
descriptor option. See i4glItemsNullable. v Record
Related Concepts
“What’s new in EGL V7.0” on page 18
“Language changes in EGL V7.0” on page 19
This topic lists the changes to the EGL language in version 7.0.
“Changes to services in EGL V7.0” on page 36
Introduction 31
“Changes to exception handling in EGL V7.0” on page 36
This topic covers changes to the way EGL deals with exceptions in version 7.0.
Related tasks
“Migrating from a previous version of EGL” on page 38
Most system functions have been updated to accept null values for parameters. In
general, if you pass a null value to a system function, it returns a null value.
However, each function behaves differently; see the help topic on the specific
function for information.
Some system functions and libraries were removed from V7.0 but are returned in
V7.1; see “Changes to system libraries and variables in EGL V7.1” on page 15.
The following system functions are no longer necessary because you can now
assign a string directly to a decimal, floating-point, or integer type:
v MathLib.stringAsDecimal
v MathLib.stringAsFloat
v MathLib.stringAsInt
The new system library sqlLib contains some functions moved from sysLib and
consoleLib that deal with SQL data access. For more information on sqlLib, see
EGL library sqlLib.
Similarly, the SQL-related system variables in sysVar and VGVar have been moved
into the new sqlLib.sqlData and sysVar.sqlData system variables, which are both
structured records. sqlLib.sqlData contains information that is global to the entire
application, while sysVar.sqlData contains information that is local to the program.
See sysVar system variable (core fields) and sqlLib.sqlData (EGL system variable).
The following system functions and variables are new in this version:
j2eeLib.clearApplicationAttr
See clearApplicationAttr()
j2eeLib.clearEGLSessionAttrs
See clearEGLSessionAttrs()
j2eeLib.getApplicationAttr
See getApplicationAttr()
j2eeLib.setApplicationAttr
See setApplicationAttr()
MathLib.decimals
See decimals()
Introduction 33
Table 2. Renamed system functions (continued)
Old name New name
SysLib.beginDatabaseTransaction SqlLib.beginDatabaseTransaction
SysLib.connect SqlLib.connect
SysLib.defineDatabaseAlias SqlLib.defineDatabaseAlias
SysLib.disconnect SqlLib.disconnect
SysLib.disconnectAll SqlLib.disconnectAll
SysLib.loadTable SqlLib.loadTable
SysLib.queryCurrentDatabase SqlLib.queryCurrentDatabase
SysLib.setCurrentDatabase SqlLib.setCurrentDatabase
SysLib.startTransaction VGLib.startTransaction
SysLib.unloadTable SqlLib.unloadTable
Some other build descriptor options were removed from V7.0 but are returned in
V7.1; see “Changes to build descriptor options in EGL V7.0.”
Introduction 35
“Changes to build descriptor options in EGL V7.1” on page 16
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
“What’s new in EGL V7.0” on page 18
“Language changes in EGL V7.0” on page 19
This topic lists the changes to the EGL language in version 7.0.
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.
Follow the steps below to migrate EGL code to the current version, using the
section that represents your code’s current version:
Version 5.1.2, up to but not including version 6.0 with iFix 001
1. Migrate the code to version 6.0 iFix 001 as explained in “Migrating EGL code to
EGL V6.0 iFix 001” on page 56.
2. Make the following changes to the code manually to migrate the code to
version 6.0.1:
Introduction 39
v Make sure that none of your identifiers (such as variable or part names)
begins with the at symbol (@), which is now an operator.
v Change invocations of the following system functions, but only if the last
argument in the invocation is a numeric value, as evidenced by an error
message that indicates a problem with the argument’s primitive type.
Table 3. Manual changes to system functions
Old function New function
StrLib.compareStr VGLib.compareBytes
StrLib.CopyStr VGLib.copyBytes
StrLib.concatenate VGLib.concatenateBytes
3. Migrate the code from version 6.0.1 to version 7.0 as explained in “Migrating
EGL code to EGL V7.0” on page 43.
Version 6.0 with iFix 001, up to but not including version 6.0.1
1. Make the following changes to the code manually to migrate the code to
version 6.0.1:
v Make sure that none of your identifiers (such as variable or part names)
begins with the at symbol (@), which is now an operator.
v Change invocations of the following system functions, but only if the last
argument in the invocation is a numeric value, as evidenced by an error
message that indicates a problem with the argument’s primitive type.
Table 4. Manual changes to system functions
Old function New function
StrLib.compareStr VGLib.compareBytes
StrLib.CopyStr VGLib.copyBytes
StrLib.concatenate VGLib.concatenateBytes
2. Migrate the code from version 6.0.1 to version 7.0 as explained in “Migrating
EGL code to EGL V7.0” on page 43.
No program is available to automate the migration from version 7.0 to version 7.1,
and in most cases no migration is necessary. Here are two exceptions:
v If you use forms and you migrated to V7, you must make changes in your code
by hand before you run V7.1. Most users with forms did not migrate to V7,
because forms are not supported in that version.
v If you are working with a Web project that was generated for V7.0 to 7.0.0.3 and
whose code will run in WebSphere Application Server and will access Web
services on any platform, you must change the project. However, no change is
necessary if the project is to run on a server other than WebSphere Application
Server.
The following changes are required to migrate forms from EGL V7 to V7.1:
v Add the @ operator to all printFloatingArea and screenFloatingArea properties.
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.
When you launch the product, all projects will be checked to see if migration is
needed. This check is also performed when you import a project or check a project
out of a source code manager. If you need to migrate, the Workspace will display a
message to that effect. You can then select the specific projects and resources to
migrate.
The following code changes require some files or projects to migrate from EGL
version 7.1 to version 7.5:
v ExternalType function parameters require the in modifier.
v The path to Apache jar files has changed.
v BIRT report files need ICU4J (International Components for Unicode for Java)
support.
Related concepts
“What’s new in EGL V7.0” on page 18
“Changes made by the V7.0 migration tool” on page 44
“Changes to exception handling in EGL V7.0” on page 36
This topic covers changes to the way EGL deals with exceptions in version 7.0.
“Changes to services in EGL V7.0” on page 36
“Changes not made by the V7.0 migration tool” on page 54
After migrating your code to V7.0, you might need to make manual changes.
Related tasks
“Setting EGL-to-EGL migration preferences” on page 42
“Migrating EGL code to EGL V6.0 iFix 001” on page 56
“Migrating EGL code to EGL V7.0” on page 43
Introduction 41
Setting EGL-to-EGL migration preferences
Preferences for the EGL-to-EGL migration wizard control how EGL code from prior
versions is migrated to the current version. Some of these preferences are
meaningful for both the version 6 and version 7 migration, and others apply only
to one migration. Follow these steps to set EGL migration preferences:
1. Enable the EGL V7.0 migration capability:
a. Click Window → Preferences.
b. Expand General and click Capabilities.
c. Click Advanced.
d. In the Advanced window, expand EGL Developer and select the EGL V7.0
Migration check box.
e. Click OK.
f. Click OK again.
2. Click Window → Preferences.
3. Expand EGL and click Migration. This page shows the settings for the
migration tool.
4. Choose how to resolve a naming conflict with a new reserved word by
clicking a radio button:
v Add suffix sets the migration tool to add a suffix to any words in the
source code that are now reserved words. In the text box by this radio
button, type the suffix you want the migration tool to add to the changed
word.
v Add prefix sets the migration tool to add a prefix to any words in the
source code that are now reserved words. In the text box by this radio
button, type the prefix you want the migration tool to add to the changed
word.
5. If your project has standalone functions, that is, functions that are not
contained by any other logic part, and those functions contain variables that
are now reference types (such as arrays), select the check box labeled Convert
assignment statements to move statements. See “Changes made by the V7.0
migration tool” on page 44 for more information on converting from
assignment statements to move statements for reference variables.
6. As explained in the section on nullable types in “Language changes in EGL
V7.0” on page 19, the itemsNullable build descriptor option has been
replaced with the I4GLItemsNullable property. The migration tool can add
this property to your logic parts automatically. Select the Add property
I4GLItemsNullable=yes if you want the migration tool to add this property.
7. The migration tool can set the new textLiteralDefaultIsString property to NO
for each part to preserve previous behavior in the way EGL treats text literals
(such as "Hello!"). See textLiteralDefaultIsString.
8. The migration tool can delete the Java files from your projects so that the Java
files can be re-generated from the EGL source. Select Prompt, Always, or
Never. This change affects only the Java files in the same project as EGL code
that you are migrating. If you are generating the EGL code into a different
project, delete those Java files manually.
9. The migration tool can set the deploymentDescriptor build descriptor option
to the name of an EGL deployment descriptor file in the project. It can update
all build descriptor files, just the default build descriptors, or none at all.
Select a radio button under Project build descriptors to update with the
deployment descriptor name.
Follow these steps to run the migration tool to migrate code from EGL version
6.0.1 or later to version 7.0:
Note: Do not use the migration tool on code that has already been updated to
EGL V7.0. Doing so can create errors in your code.
1. Enable the EGL V7.0 migration capability:
a. Click Window → Preferences.
b. Expand General and click Capabilities.
c. Click Advanced.
d. In the Advanced window, expand EGL Developer and select the check box
labeled EGL V7.0 Migration.
e. Click OK.
f. Click OK again.
2. Set the preferences for the migration process as described in “Setting
EGL-to-EGL migration preferences” on page 42.
Introduction 43
3. In the Project Explorer view, select the EGL projects, packages, folders, or files
that you want to migrate. You can select any number of EGL resources to
migrate. To select more than one resource at once, press and hold CTRL while
clicking the resources.
4. Right-click on a selected resource and then click EGL V7.0 Migration →
Migrate.
5. Inspect your code for errors and for places that do not comply with EGL V7.0.
You might need to make manual changes to your code as explained in
“Changes not made by the V7.0 migration tool” on page 54, “Changes to
services in EGL V7.0” on page 36, and “Changes to exception handling in EGL
V7.0” on page 36.
6. Optionally, you can disable the V7.0 migration capability to avoid migrating the
same code twice.
To review the changes that the tool made to the source code, do as follows:
1. In the Project Explorer view, right-click an EGL source file that has been
migrated and then click Compare With → Local History.
2. Examine the differences between the file in the workspace and the previous
version.
3. When you are finished reviewing the changes, click OK.
Related concepts
“Changes made by the V7.0 migration tool”
“Changes not made by the V7.0 migration tool” on page 54
After migrating your code to V7.0, you might need to make manual changes.
Related tasks
“Migrating from a previous version of EGL” on page 38
“Setting EGL-to-EGL migration preferences” on page 42
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
Properties
Changes to existing properties
The migration tool changes the values of properties that are no longer
quoted strings. See the section ″Some property values are no longer quoted
strings″ in “Language changes in EGL V7.0” on page 19. This change
includes the pcbParms property, in which case the migration tool changes
empty strings ("") to NULL.
The migration tool changes the keyItem property on records with the
stereotype relativeRecord to the recordNumItem property.
The migration tool changes the isNullable property to isSQLNullable.
The migration tool changes the value of the protect and outline property
on Text UI form fields to the ProtectKind and OutlineKind enumeration.
It puts the value of outline in brackets because this property is now an
array. The migration tool does not change the value of protect on fields in
a ConsoleForm record.
Table 5. Changes to the protect and outline properties on Text UI form fields
Old property and value New property and value
protect = yes protect = ProtectKind.protect
protect = no protect = ProtectKind.noProtect
protect = skip protect = ProtectKind.skipProtect
outline = box outline = [OutlineKind.box]
outline = noOutline outline = [OutlineKind.noOutline]
Exception compatibility
The migration tool sets v60ExceptionCompatibility to YES on the
following logic parts:
v Program
v Library
v Handler
v Service
Text literals
Depending on the preferences, the migration tool adds the code
textLiteralDefaultIsString = NO to the following parts to preserve
behavior from previous versions:
v Program
v Library
v Handler
v Service
v Records
Introduction 45
enableJavaWrapperGen build descriptor option. If enableJavaWrapperGen
is set to YES or ONLY, migration adds the wrapperCompatibility build
descriptor option and sets it to V6.
For more information on wrapperCompatibility, see wrapperCompatibility.
Variables
Variable scope within code blocks
As explained in ″Scope of variables within functions″ in “Language
changes in EGL V7.0” on page 19, variables are now in scope only after
their declaration, not before. The migration tool moves all local variable
declarations to the beginning of the code block. If that variable was
initialized, the migration tool converts the initializer into an assignment
statement and leaves the assignment statement where the original location
of the variable declaration was. If the variable was already at the beginning
of the code block, the migration tool moves its initializer into an
assignment statement and puts that assignment statement at the end of the
variable declarations.
Default specifier for INTERVAL variables
The migration tool adds a default format specifier to INTERVAL variables
without a specified format:
Table 6. Changes to INTERVAL variable declaration
Old code Migrated code
intval1 interval; intval1 interval("yyyyMM");
Introduction 47
– MathLib.sin()
– MathLib.sinh()
– MathLib.sqrt()
– MathLib.tan()
– MathLib.tanh()
Casting with system library JavaLib
In previous versions, certain arguments in certain functions in JavaLib
could accept a casting operator in parentheses. The migration tool changes
this casting to use the syntax variable as "type", as in these examples:
Table 10. Changes to casts in JavaLib functions
Old code Migrated code
(byte)myVar myVar as "java:byte"
(objId)myVar myVar as "objId:java"
(null)"java.lang.Integer" null as "java.lang.Integer"
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];
The migration tool initializes the following reference variables in this way:
v ArrayDictionary
The migration tool makes this change only for arrays and only if the arrays
have the out modifier.
Assignment statements for reference types
When one reference variable is assigned to another, the migration tool
changes the assignment statement to a move statement to keep the
behavior consistent with previous versions. The following example
assumes that the variables array1 and array2 are arrays or other reference
variables:
Table 14. Changes to assignment statements for reference types
Old code Migrated code
array1 = array2; move array2 to array1;
The migration tool makes this change for the following types of variables:
v Array
v Dictionary
v ArrayDictionary
v Any
v Record parts with the stereotype ConsoleForm
For assignment statements in a standalone function part, that is, a function
that is not within a logic part, the migration tool attempts to change
assignment statements to move statements under the following conditions:
v If the migration tool can resolve both sides of an assignment statement
(that is, it can determine that the variables on both sides of the
assignment statement are created from a reference type), it changes the
assignment statement to a move statement as it does in any function.
v If the migration tool cannot resolve both sides of an assignment
statement, the associated migration preference takes effect. In this case, if
the migration preference is enabled, the tool changes the assignment
statement to a move statement as above. If the migration preference is
disabled, the tool makes no change to the assignment statement.
Nullable variables
Expressions with null values
The migration tool changes expressions with null values to the new
Introduction 49
nullability rules explained in “Language changes in EGL V7.0” on page 19.
Table 15. Migration of expressions with null values
Old code Migrated code
set myVar NULL; myVar = NULL;
myVar is NULL myVar == NULL
nullable modifier
The migration tool changes uses of the nullable modifier on function
parameters to sqlNullable.
itemsNullable build descriptor option
Depending on the preferences, the migration tool adds the
I4GLItemsNullable property to the following parts to replace the
itemsNullable build descriptor option:
v Program
v Handler
v Library
v Record
Other statements
move statements
To preserve the default behavior of the move statement in previous
versions, the migration tool adds the byName option to move statements
between two record or form variables.
For statements within a standalone function, the migration tool tries to
resolve the variables on both sides of the move statement before making a
change:
v If the migration tool can resolve both sides of a move statement (that is,
it can determine that the variables on both sides of the statement are
records or forms), it adds byName as it does in any function.
v If the migration tool cannot resolve both sides of the move statement, it
adds withV60Compat instead of byName to maintain compatibility with
the previous version.
The migration tool makes this change only if it can resolve both sides of
the assignment statement, or if the associated migration preference is
enabled. If it cannot resolve both sides of the assignment statement, and
the migration preference is disabled, the migration tool makes no change.
Changes to syntax of call, transfer, and show
The migration tool changes the uses of these three statements to comply
with their new syntax:
Table 16. Changes to call and transfer
Old code Migrated code
call xxx 1, 2 call "xxx" (1, 2)
norefresh {IsNoRefresh = yes,
externallyDefined; IsExternal = yes};
transfer to program xxx transfer to program "xxx"
passing yyy passing yyy
externallyDefined; {IsExternal = yes};
Services
@WSDL and @XSD properties
The migration tool converts the @WSDL property to the @XML property
and removes the @XSD property. In the process, the tool converts the
elementName property field of the @WSDL property to the name property
field of the @XML property. The isLastParamReturnValue property field of
the @WSDL property is discarded.
Services and Service Binding Libraries
The migration tool removes the serviceBindingLibrary stereotype from
Library parts.
If the preference to add Web service elements to the deployment descriptor
is enabled, the migration tool creates an EGL deployment descriptor in the
project’s EGLSource folder and converts @EGLBinding and @WebBinding
properties from the interfaces in the service binding libraries into service
client binding information in that deployment descriptor. The tool copies
the WSDL file specified in the @WebBinding property to the EGLSource
folder of the current project
If the preference to add the deployment descriptor to the project’s build
descriptors is enabled, the migration tool sets the deploymentDescriptor
build descriptor option to the name of the new deployment descriptor,
which by default has the same name as the project.
If the preference to remove Web service references from the J2EE
deployment descriptor is enabled, the migration tool removes these
references.
The tool updates ServiceLib.getWebEndPoint and
ServiceLib.setWebEndPoint to ServiceLib.getWebServiceLocation and
ServiceLib.setWebServiceLocation, respectively.
PageHandler parts
Conversion to JSFHandler parts
v The migration tool changes pageHandler parts to Handler parts with the
stereotype JSFHandler.
v The tool converts the pageHandler onPageLoadFunction property to the
JSF Handler onConstructionFunction property.
v The tool adds cancelOnPageTransition = YES to all pageHandler parts
that do not have this property defined.
v The tool changes links to pages with the extension .jsp to .faces in
forward to URL statements and action properties. In forward to URL
Introduction 51
statements, the tool makes this change only if the target of the forward
to URL statement is a quoted string that ends with .jsp. In uses of the
action property, the tool makes this change only if the displayUse
property is set to hyperlink and the action property is a quoted string
that ends with .jsp. See “Running a Web page on a server” on page 448
for more information on file extensions of JSP files. Following are
examples of these changes:
Table 18. Changes to links in pageHandlers
Old code Migrated code
myLink string myLink string
{displayUse = hyperlink, {displayUse = hyperlink,
action="myPage.jsp"}; action="myPage.faces"};
forward to URL "myPage.jsp"; forward to URL "myPage.faces";
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
Important: Do not use the migration tool on code that has already been updated
to EGL V6.0 iFix001. Doing so can create errors in your code.
The migration tool can be used on an entire project, a single file, or a selection of
files. Running the tool on a package or folder converts all of the EGL source files
in that package or folder. For more information on the code that is changed by the
migration tool, see “Changes made by the V6.0 iFix 001 migration tool” on page
57.
The migration tool converts the selected EGL source files to comply with EGL V6.0
iFix001. To review the changes that the tool made to the source code, do as follows:
1. In the Project Explorer view, right-click an EGL source file that has been
migrated and then click Compare With → Local History.
2. Examine the differences between the file in the workspace and the previous
version.
3. When you are finished reviewing the changes, click OK.
Related concepts
“Changes made by the V6.0 iFix 001 migration tool” on page 57
Related tasks
“Migrating from a previous version of EGL” on page 38
“Setting EGL-to-EGL migration preferences” on page 42
Important: Do not use the migration tool on code that has already been updated
to EGL V6.0 iFix 001. Doing so can create errors in your code.
The migration tool can add comments to each file it changes. It can also add
comments to the project’s log file. See “Setting EGL-to-EGL migration preferences”
on page 42.
The migration tool changes EGL code in these ways to comply with EGL V6.0 iFix
001 :
v The migration tool makes changes to the way properties are specified. For
information about the changes to properties, see “Changes to properties during
EGL V6.0 iFix 001 migration” on page 60.
v The migration tool searches for variables and part names that conflict with
reserved words. The migration tool changes those variable and part names by
adding a prefix or suffix as defined in the migration preferences. By default, the
tool adds the suffix _EGL to any name that is now a reserved word. The
migration tool does not rename objects of the CALL statement, and it does not
update references in EGL Build Part files. The following are examples of code
before and after using the migration tool.
Before migration:
Library Handler
boolean Bin(4);
End
After migration:
Library Handler_EGL
boolean_EGL Bin(4);
End
v The migration tool replaces the single equals sign (=) with the double equals
sign (==) when the single sign is used as a comparison operator. It does not
change the single equals sign when it is used as an assignment operator.
Before migration:
Function test(param int)
a int;
If(param = 3)
a = 0;
End
End
After migration:
Function test(param int)
a int;
If(param == 3)
a = 0;
End
End
v The migration tool adds level numbers to records that do not have level
numbers.
Before migration:
Record MyRecord
item1 int;
item2 int;
End
Introduction 57
After migration:
Record MyRecord
10 item1 int;
10 item2 int;
End
v The migration tool changes the declaration syntax of constants.
Before migration:
intConst 3;
After migration:
const intConst int = 3;
v The migration tool changes variables and function names that have been moved
to different libraries or renamed. This change affects variables and functions
from the sysLib and sysVar libraries.
Before migration:
sysLib.java();
clearRequestAttr();
After migration:
javaLib.invoke();
j2eeLib.clearRequestAttr();
A list of changed variables and function names from the sysLib and sysVar
libraries follows:
Table 20. Changed variable and function names from the sysLib and sysVar libraries
Before migration After migration
sysLib.dateValue dateTimeLib.dateValue()
sysLib.extendTimestampValue dateTimeLib.extend()
sysLib.formatDate strLib.formatDate()
sysLib.formatTime strLib.formatTime()
sysLib.formatTimestamp strLib.formatTimestamp()
sysLib.intervalValue dateTimeLib.intervalValue()
sysLib.timeValue dateTimeLib.timeValue()
sysLib.timestampValue dateTimeLib.timestampValue()
sysLib.java javaLib.invoke()
sysLib.javaGetField javaLib.getField()
sysLib.javaIsNull javaLib.isNull()
sysLib.javaIsObjID javaLib.isObjID()
sysLib.javaRemove javaLib.remove()
sysLib.javaRemoveAll javaLib.removeAll()
sysLib.javaSetField javaLib.setField()
sysLib.javaStore javaLib.store()
sysLib.javaStoreCopy javaLib.storeCopy()
sysLib.javaStoreField javaLib.storeField()
sysLib.javaStoreNew javaLib.storeNew()
sysLib.javaType javaLib.qualifiedTypeName()
sysLib.clearRequestAttr j2eeLib.clearRequestAttr()
sysLib.clearSessionAttr j2eeLib.clearSessionAttr()
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
v The migration tool adds double quotes to property values that are used as string
literals.
Before migration:
{ alias = prog }
After migration:
{ alias = "prog" }
The following properties are affected:
– alias
– column
– currency
– displayName
– fileName
– fillCharacter
– help
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
v The migration tool changes the values of the dateFormat and timeFormat
properties to be case sensitive. For more information, see ″Date, time, and
timestamp format specifiers″ in the EGL Language Reference.
v If the Add qualifiers to enumeration property values check box is selected in
the preferences menu, the migration tool adds the name of the enumeration to
the value of the property.
Before migration:
color = red
outline = box
After migration:
color = ColorKind.red
outline = OutlineKind.box
Introduction 63
This change affects the following properties:
– align
– color
– deviceType
– displayUse
– highlight
– indexOrientation
– intensity
– outline
– protect
– selectType
– sign
v The migration tool changes the values of the tableNames property to be an
array of arrays of strings. Each array of strings must have either one or two
elements. The first element is the table name, and the second element, if present,
is the table label. The following table gives some examples of how the migration
tool changes the tableNames property.
Table 23. Changes to the tableNames property
Before migration After migration
{ tableNames = (table1, table2) } { tableNames = [["table1"], ["table2"]] }
{ tableNames = (table1 t1, table2) } { tableNames = [["table1", "t1"],
["table2"]] }
{ tableNames = (table1 t1, table2 t2) } { tableNames = [["table1", "t1"],
["table2", "t2"]] }
v The migration tool changes the way dates, times and timestamps are specified,
including changing the values of the dateFormat and timeFormat properties to
be case sensitive. Following are some examples:
Table 24. Changes to dates, times, and timestamps
Before migration After migration
dateFormat = "yy/mm/dd" dateFormat = "yy/MM/dd"
dateFormat = "YYYY/MM/DD" dateFormat = "yyyy/MM/dd"
dateFormat = "YYYY/DDD" dateFormat = "yyyy/DDD"
timeFormat = "hh:mm:ss" timeFormat = "HH:mm:ss"
Introduction 65
66 EGL Programmer’s Guide
Contents of an EGL application
This topic describes the artifacts found in a typical EGL application.
Projects
An EGL application contains one or more projects to hold and organize your code
in folders and files. A project is contained in a single physical folder in your
workspace, and that folder contains other folders, as described below.
You can have as many projects as you want, and those projects can be independent
or they can reference each other and use parts from each other’s packages. The
needs of your organization and design of the application that you are creating
determines your use of projects, packages, and files. There are no set guidelines for
how to use them. See “The EGL build path” on page 83 for information on
references between projects.
Folders
An EGL project can contain several folders. Some of these folders have default
names; for example, the EGL source files go in a folder named EGLSource by
default. The documentation often refers to these folders by their default name, but
be aware that they might have different names in your project.
Source code folder
EGL projects have at least one source code folder, named EGLSource by
default. The source folder contains all of the EGL source files, build files,
and deployment descriptor files for the project. EGL generates output code
only for files within a source code folder.
You can create packages within source folders or additional source code
folders to organize your files. See “Creating an EGL package” on page 89
or “Creating source folders” on page 87.
Generated code folder
When you are generating to Java, the EGL project has a folder to hold the
files that are created by the generation process. By default, the generated
code folder is named src, but in most cases (such as in the Project Explorer
view), it is labeled Java Resources, regardless of the actual folder name on
disk. Do not edit the files in the generated code folder, because they are
overwritten each time you generate the project.
For COBOL output, EGL puts the generated code into a directory outside
the workspace as specified by the genDirectory build descriptor option.
EGL then transfers the outputs to the target system based on the destHost
and other related build descriptor options.
EGLBin folder
The EGLBin folder is used to store internal representation files, which are
used by EGL in the generation and debugging processes.
Web content folder
For EGL Web projects, the Web content folder contains the Web pages,
style sheet files, and other files that control how the Web project will
display in a browser. By default, the Web content folder is named
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
EGL plug-in projects contain several files that are not, strictly speaking, EGL files.
Instead, these files are part of the standard definition of an Eclipse plug-in, or the
smallest independent unit of functionality in the Eclipse workbench. The
workbench itself is composed largely of a collection of plug-ins; you can extend the
workbench by adding additional plug-ins, either from a commercial product, an
open-source project, or plug-ins you create yourself. When you create an EGL
plug-in project, EGL adds the files necessary for the project to function as a
plug-in. EGL also adds the files necessary to define a run-time configuration of the
workbench.
plugin.xml
The plugin.xml file describes the extensions that your project adds to the
Eclipse framework. More specifically, this file contains an entry for the EGL
″player″ that controls the runtime operations of Console UI applications
that are running in rich client platform (RCP) mode. Also, when you
generate a project, EGL adds a reference in the plugin.xml file for each
Console UI program in the project. This reference is needed only when
running a Console UI program in RCP mode. You will rarely need to edit
the reference. The plugin.xml file is created when you generate a program
within an EGL plug-in project.
EGL projects can also have additional features and facets added to them to add
support for more granular pieces of functionality. See “Features and facets of EGL
projects” on page 76.
Depending on the target server for the project, EGL Web projects can be connected
to an Enterprise Application Resource (EAR) project. EAR projects contain
information for deployment in the J2EE application framework. See J2EE
Applications.
Related tasks
“Creating an EGL project”
This topic covers how to create an EGL project.
“Creating an EGL Web project” on page 73
This topic covers how to create an EGL Web project.
“Creating an EGL plug-in project” on page 74
EGL plug-in projects, also called RCP projects, are useful for Console UI
applications that you want to run in rich client platform (RCP) mode. You can
create a new EGL plug-in project or convert an existing EGL project or EGL
Web project to an EGL plug-in project.
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
“Features and facets of EGL projects” on page 76
EGL projects can have additional abilities, added through features and facets.
The steps for creating an EGL Web project are similar to those for creating an EGL
project, but include additional steps for the target runtime, or the server that the
project will be deployed to. To set up a new EGL Web project:
1. From the menu bar, click File → New → Project The New Project window
opens.
2. In the New Project window, expand EGL and click EGL Project Wizard. If
you do not seeEGL Project Wizard, select the Show All Wizards check box.
3. Click Next.
4. Type a name for the project in the Project name field.
5. Under EGL Project Types, select Web project.
6. Click Next.
7. Choose a target runtime for the project in the Target Runtime list.
You are not required to choose a runtime right now, but you will need to
choose a runtime before you can run the project on a server or deploy the
project. It is best to choose a runtime now; you can change the target runtime
later.
8. Under Build Descriptor Options, choose where the default build descriptor
for the project will be located or created:
v Create a new build descriptor means that EGL provides a new build
descriptor and writes it to a new build file (extension .eglbld) that has the
same name as the project.
To specify a default database connection in that build descriptor, click
Options. To change those values later, change the build file that is created
for you.
v Use the build descriptor specified in the EGL preferences means that EGL
points to a build descriptor that you created and identified as an EGL
preference.
v Select an existing build descriptor enables you to specify a build
descriptor from those that are available in your workspace.
9. If you want to configure other options for the project, such as adding it to an
EAR application or adding additional facets, select Show Advanced Settings
and then click Next. Otherwise, click Finish.
10. Under Project location, you can choose to place the project in your
workspace, as is the default, or you can choose a different location.
11. Under EAR Membership, specify whether to include the project as a module
within an Enterprise Application Resource (EAR) project in the workspace:
v If you clear the Add project to an EAR check box, the project is not added
to an EAR project. You can add the new project to an EAR project later.
v If you select the Add project to an EAR check box and choose an existing
EAR project in the EAR Project Name list, the new project will be added to
that EAR project. The new project will use the EAR project’s target runtime,
regardless of your choice of runtime on the previous page.
v If you select the Add project to an EAR check box and type a name for a
new EAR project in the EAR Project Name list, the new EAR and EGL Web
For more information on the files in an EGL plug-in project, see “Contents of an
EGL application” on page 67
Converting a project
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.
You can also choose the features that are applied to your new EGL projects by
default:
1. Click Window → Preferences. The Preferences window opens.
2. Click EGL.
3. Under Default EGL Project Features Choices, select the features to you add to
each new project by default.
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
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
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:
Regardless of the type of project, do not share derived files. Derived files are
generated from source files and are not original data, so it is usually unnecessary
to share them. In the context of EGL Java generation, derived files include the Java
source files that are created during the generation process as well as the Java class
files created from those Java source files. EGL source files and build files are not
considered derived, but .ir files created from the source files are derived.
Including derived files increases the size of the artifacts that you share. Moreover,
including derived files might not be useful because they can be regenerated and
overwritten when the files are imported into another workspace. However, you
may want to share derived files if the person you are sharing the project with
cannot generate the derived files, or if you are trying to diagnose problems with
the derived files.
The workbench maintains a flag on each file to specify whether the file is derived
or not. For example, class files created from Java files and .ir files created from
EGL source files are automatically marked as derived. However, the workbench
does not mark Java source files as derived, even if they are generated from EGL
source files. In EGL, these Java source files are still considered derived because
they are created from EGL source files.
You can see whether a file is marked as derived by right-clicking the file in the
Project Explorer view or Navigator view, clicking Properties and moving to the
Info page. (You may want to use the Navigator view to examine derived files
because the Project Explorer view filters out some types of derived files, such as
EGL .ir files.) If the Derived check box on the file’s Properties window is selected,
the file is marked as derived. However, many sharing methods (including Project
Interchange files and some types of repositories) do not retain the derived flag. If
you share a derived file and someone else checks out the file, that file will no
longer be marked as derived.
For more information on which files are considered derived and why you would
or would not want to include them, see Derived resources.
Possible errors
When sharing projects, dependencies and links within the projects can break as the
projects are moved to different locations. The following are some common tasks
that you might need to perform to correct errors that you encounter while sharing
projects:
v Correct project dependencies, if it has other projects in its build path.
v Make sure that the project can find imported parts in the new location, if any
source files use import statements to refer to other EGL parts.
v Verify that links between Web pages still work.
Related concepts
“Introduction to EGL projects” on page 70
Related tasks
“Importing and exporting projects” on page 81
The workbench includes several ways to import projects and files from your
local file system and export them to your local file system.
Project Interchange files are archive files that contain one or more projects, making
them appropriate for sharing entire projects at once. Follow these steps to export
one or more of your projects as a Project Interchange file:
1. Click File → Export. The Export window opens.
2. Under Select an export destination, expand Other and click Project
Interchange.
3. Click Next.
4. On the Export Projects page, select the check boxes next to the projects that you
want to export in the Project Interchange file.
5. In the To zip file field, select the name and location for the exported file.
6. If you want to include derived files in the exported file, select the Include
derived files check box.
See “Sharing projects” on page 79 for information on derived files. Derived files
generated from source files and are not original data, so it is typically
unnecessary to include them when sharing projects.
7. Click Finish.
Follow these steps to import one or more of the projects in a Project Interchange
file:
1. Click File → Import. The Import window opens.
2. Under Select an import source, expand Other and click Project Interchange.
3. Click Next.
4. On the Import Projects page, select the projects you want to import.
5. Click Finish.
With the workbench, you can also import and export individual files as separate
files or as a single archive file. Follow these steps to export individual files from
your workspace to your local file system:
1. Click File → Export.
2. In the Export window, expand General and choose a format for your output
files. These are some of the common formats:
v File System exports files to your local file system as individual files, the
same as they are within the workbench.
v Archive File compresses files into an archive file and saves that archive file
to your local files system.
3. Click Next.
4. Select the files that you want to export and select a location for the exported
file or files.
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.
The way that you share your projects in a repository or source-control system
depends on the type of repository or source-control system. In general, share
source files and build files but not derived files, files that are created from other
files. This way, the files in the repository are limited to only those necessary for the
application. (If you edit a file directly, it is probably not derived.) For a discussion
of derived files in the context of EGL, see “Sharing projects” on page 79.
Also, when you share projects in a repository, be aware of these possible problems:
v If derived files are checked into a repository, they often lose their derived flags.
In this case, files that you normally wouldn’t check into a repository may appear
to need to be stored in a repository.
v Checking files into a repository can break connections between files. For
example, if you check a UML model and a TPM file into a repository and then
check them back out again, the workbench might not know that the two are
associated. For information on this problem, see Linking a UML model to an
existing TPM file.
v When sharing projects in a repository, the projects are subject to the same
potential errors as described in “Sharing projects” on page 79.
Related concepts
“Introduction to EGL projects” on page 70
For example, suppose project A contains a Record part and you want to create a
variable based on that Record part in project B. You could copy the source file
from project A into project B, but that would mean duplicating the file. Instead,
you can add project A to the build path of project B. Then, you can use the Record
part in project B as though the definition were in project B. Scoping rules still
apply, however, so you might need to import the part to bring it into scope.
Adding other projects to the build path is useful only while you are coding; for
example, the EGL build path enables content assist to find other parts and insert
correct import statements. The EGL build path also provides a way for validation
to flag unknown parts and functions. If you are generating to Java, to allow your
project to use parts in another project at run time, you must make that project
available at run time. See “Editing the build path” on page 84.
The order of the items in the build path is significant because EGL searches for
parts based on the order of the folders and projects in the build path. See Name
resolution in an expression. For this reason, the source folders of the current
project are usually the first items in the build path.
You can also choose to export a project or source folder in your build path. In this
case, the exported project or source folder is available to all projects that refer to
the current project. For example, take the following project build paths:
v Project C
C, D, Y
v Project D
D, E, Z
If, in the build path for project D, you choose to export project E but not project Z,
the effective build path for project C is as follows:
C, D, E, Y
In this case, project D can use project Z, because Z is in D’s build path. However,
project C cannot use project Z because Z, is not exported along with project D.
Project C can use project E, because project E is exported along with project D.
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”
If you are generating to Java and want to use parts in a referenced project at run
time, you must make the referenced project available at run time. You can either
Eclipse maintains a build order for projects that share code (such as record
definitions), share variables, or call each other’s programs.
A key concept here is project cycles. A project cycle involves two or more projects
with mutual dependencies. For example, assume that Project1 contains parts A and
C, and Project2 contains parts B and D. A depends on B, B depends on C, and C
depends on D. If EGL builds Project1 first, it finds errors in parts A and C because
it cannot resolve references to parts B and D. After building Project2, which
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.
Packages prevent name conflicts by separating files into different contexts. Two
parts with the same name cannot be defined in the same package, but two
different packages can each have a part with the same name. Likewise, you should
prevent conflicts between packages by not creating packages with the same name,
even if those packages are in different projects or source folders.
The parts in an EGL source file all belong to the same package. The package
statement in the file, if any, specifies the name of that package. If you do not
specify a package statement, the parts are stored in the root of the source folder
and are considered to be in the default package. Because files in the default package
cannot be shared by parts in other packages or projects, it is best to specify a
package statement.
Package names are case sensitive. For more information on naming conventions for
packages, see package.
When you want a part to reference another part that is in the same package, you
do not need to specify the location of the second part. The following example
shows two parts in the same package: a Record part and a Program part that uses
the record part:
package com.companyb.firstpackage;
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;
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;
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
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
Follow these steps to create a source file that contains an EGL part:
1. You must specify a project or folder when you create an EGL source file. You
can do this in one of two ways:
v Right-click a project or folder in your workspace and click New → Other.
v With a project or folder selected in your workspace, click File → New → Other
If you have not yet created a project or folder, you must do so before creating
parts. See “Creating an EGL project” on page 71
2. From the Select a wizard window, expand EGL, and click the type of part you
want to create. If you do not see the part type you are looking for, click Show
All Wizards. The following instructions cover any of these parts:
v DataTable
v EGL Source File (generic wizard)
v FormGroup
v Interface
v JSF Handler
v Library
v Program
v Report Handler
v Service
Click Next
3. EGL displays a new part wizard. In the Source folder field, EGL shows the
project or folder you previously selected. You can change this name to that of
another existing project or folder if you chose the wrong one initially.
4. In the Package field, select a package to hold the new file. If the package name
you enter here does not exist, EGL creates it for you. To ensure that you use the
correct name of an existing package, click Browse and locate the package name.
5. In the EGL source file name field, type a name for the new file. The file name
must be same as the part name. For example, assume your file will define a
program named checkCustomerBalance:
Program checkCustomerBalance type BasicProgram
...
end
In this case you must name the file checkCustomerBalance. EGL will add the
.egl extension to file name automatically.
File names that contain EGL parts must conform to EGL part naming
conventions. For more information, see Naming conventions
6. Some wizards require further information. You can learn about these options in
the appropriate topic for the specific part:
v DataTable part
With refactoring, you can rename EGL source files or JSP files that are controlled
by a JSF Handler.
1. In one of the following places, select the file you want to rename:
v Right-click the file in the Project Explorer view
v For files that contain a generatable part, right-click the generatable part in
the Outline view, Parts List view, or Parts Reference view
v For files that contain a generatable part, place the cursor on the generatable
part’s name in the EGL editor and right-click
2. From the pop-up menu, click Refactor → Rename. The Rename Part window
opens.
3. In the Rename Part window, type a new name for the file, following EGL
naming conventions.
4. You can click Preview for a list of the changes EGL will make if you proceed.
5. If you clear the Update references check box, EGL will not search other files
for references to change. In most instances, select this check box.
6. Click OK.
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.
With refactoring, you can move EGL source files to a new location in an EGL
package in your workspace.
1. In the Project Explorer view, right-click the file and then click Refactor → Move.
The Move window opens.
2. In the Move window, select a destination for the file. You can create a new
package for the file with the Create Package button.
3. You can click Preview for a list of the changes that EGL will make if you
proceed.
4. If you clear the Update references to the moved elements check box, EGL will
not search other files for references to change. In most instances, select this
check box.
5. Click OK.
You might still need to check for other changes that refactoring causes.
Related concepts
“Introduction to EGL files” on page 89
Related tasks
“Renaming a source file” on page 91
You can use the refactoring function of the workbench to rename source files
and correct references to those files.
“Renaming parts” on page 120
You can use the refactoring function of the workbench to rename parts and
correct references to those parts.
“Moving parts” on page 121
You can use the refactoring function of the workbench to move parts between
source files and correct references to those parts.
“Deleting a source file”
You can delete a source file using the workbench.
In most cases, EGL does not correct references to the file as it does when you
rename or move a source file. However, if the project is an EGL plug-in project and
the file you are deleting contains a Program part, EGL removes the reference to
that program in the plugin.xml file.
Related concepts
“Introduction to EGL files” on page 89
Related tasks
“Renaming a source file” on page 91
You can use the refactoring function of the workbench to rename source files
and correct references to those files.
“Moving a source file” on page 92
You can use the refactoring function of the workbench to move source files and
correct references to those files.
The EGL deployment descriptor is distinct from JEE deployment descriptors. For
information on JEE deployment descriptors, see Defining JEE enterprise
applications (EARs).
You can have as many deployment descriptors in your EGL project as you want,
but only one can be selected as the main deployment descriptor in the
deploymentDescriptor build descriptor option. That main deployment descriptor
can include entries from other deployment descriptor files, linking the main
deployment descriptor to the other deployment descriptors without directly
copying their information. Alternately, you can copy the information from one
deployment descriptor directly into another deployment descriptor.
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.
Generatable parts are the parts on which you can begin the generation process. For
example, you cannot start the generation process on a DataItem part or a Record
part with the BasicRecord stereotype. Instead, you must start the generation
process on a generatable part such as a Program part; in the process, any
non-generatable parts used in that Program part, such as Records and DataItems,
are generated as well.
You can find a complete list of primitives in ″Primitive data types″ in the
EGL Language Reference. See “Commonly used primitives” on page 98 for
the primitives you are most likely to work with.
DataItems
A dataItem part is a customized primitive. To create a dataItem, choose
one primitive and add properties that adjust the behavior of the part. The
properties that a dataItem can accept depend on its primitive type and the
context in which it is used. Here are a few examples of dataItem parts:
DataItem myZipCodeItem int
{validValues = [00000,99999]} end
DataItem myAddressItem char(50)
{upperCase = YES} end
In this case, the first dataItem is built from an integer primitive, but is
limited with the validValues property to include only the integers between
0 and 99999. The second dataItem is built from the character primitive with
50 characters, and it is set to convert any user input into its value to upper
case.
When you create a variable in a logic part, you can use a dataItem part as
the variable type instead of the primitive. The following example creates a
variable from a dataItem part in the previous example:
zipVar myZipCodeItem;
The following variable is equivalent to the previous one:
zipVar int {validValues = [00000,99999]};
In this way, a dataItem part is simply an alias for a primitive type that has
specific property settings.
Records
Record parts are structured collections of other data parts, such as
primitives, dataItems, or other records. These other data parts within the
This record has four fields: one integer, two strings, and one floating-point
number. These fields could just as easily be dataItems or other records.
Strictly speaking, the data part itself doesn’t store data; a variable created from that
data part stores the data. In this way, you can think of a data part as a pattern for
a variable. You can declare a variable simply by naming the variable and then
specifying the data part that you want to use:
myVariable1 int;
myVariable2 myDataItemPart;
myVariable3 myRecordPart;
These are only the most common types of data part. For the others, see “Other
data parts” on page 102.
Related concepts
“Contents of an EGL application” on page 67
This topic describes the artifacts found in a typical EGL application.
“Other data parts” on page 102
These data parts are not used as often as the others.
“Commonly used primitives”
This topic lists and describes the primitives that you are most likely to use.
“Introduction to Record parts” on page 100
Record parts are collections of other data parts. The data parts within the
Record part are referred to as fields. A Record part can contain any number of
fields, and the fields can be primitives, data items, or other records.
Related reference
Primitive data types
DataItem part
Record part
Not all primitives are listed here; for the complete list, see ″Primitive data types″ in
the EGL Language Reference.
Primitive numeric types: The following numeric primitives are the most often
used:
INT
This is a basic four-byte integer, the workhorse of internal calculations, used
also for key numbers, stock quantities, or anywhere else that a whole number
is appropriate. The range of values you can put in an INT is -2,147,483,648 to
+2,147,483,647.
DECIMAL
Use decimals for any numbers that need a decimal point—currency amounts,
for example, or employee hours (if you allow fractions). When you declare a
Primitive character types: The most common character primitives are STRING
and CHAR.
STRING
A STRING variable holds a group of characters such as a name or an address.
EGL automatically makes all strings Unicode, which means that each character
is two bytes long and can handle any international language that the Unicode
standard can render. STRING variables, by default, are variable in length. The
length of a STRING at any given moment is the length of the data that it
holds, and that length can change at run time. For some uses you might want
to limit the size of the STRING variable. To limit the length of the STRING
variable, specify a maximum number of characters (not bytes) at declaration
time, as in the following example:
myUSState STRING(2) = "TX";
Note that when you assign a STRING value, you place it inside double quotes.
CHAR
A CHAR primitive is also available, mostly to provide compatibility with older
programs and data. A variable declared as CHAR(4) would hold four bytes of
character data.
Primitive date and time types: To store dates and times, you typically use the
following types:
DATE
A DATE variable stores month, day, and year in Gregorian format, using eight
bytes.
TIME
A TIME variable stores hours, minutes, and seconds in six bytes.
TIMESTAMP
A TIMESTAMP variable holds both date and time, and has a maximum of 20
digits.
For variables based on any of these date and time types, you can specify formats
for input and output. See ″Date, time, and timestamp format specifiers″ in the EGL
Language Reference for more information.
At the simplest level, a Record part is a group of other data parts. In this example,
three different primitives are grouped into a single Record part:
Record primitiveRec type BasicRecord
integerField int;
stringField string;
charField char(30);
end
Creating a variable based on this Record part is similar to creating a variable based
on a DataItem part or primitive:
myRecVar primitiveRec;
The record variable itself does not contain a value, but the fields within the record
do contain values. After you have a variable based on a Record part, you can
access the fields within the record as though they were individual variables:
myRecVar.integerField = 6;
myRecVar.stringField = "Hello";
myRecVar.charField = "Character field";
However, the record still behaves as a single unit, so you can pass it to functions
as a single parameter, for example:
myFunction(myRecVar);
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 field’s relationship to other fields.
The fields in unstructured records do not have level numbers, so each field is
considered to be at the same level. Structured records can also behave this way,
with each field at the same level number:
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.
An array is an ordered series of variables of the same type. For example, you can
define an array of integer variables:
myInts int[] = [1,2,3,4,5];
In this case, the array is a series of five integer variables. In EGL, arrays begin
numbering with the number one, so this array has elements numbered one
through five.
You can access each of the integers in the array as though they were individual
variables by specifying the index number of the integer in brackets:
myInts[1] = 5+5;
myInts[2] = 16;
myInts[3] = myInts[1] + myInts[2];
You can also assign values to the array more than one at a time using one of these
two methods:
v You can use a set-value block:
myStrings string[2];
myStrings {"Hello", "Goodbye"};
Note that this syntax uses braces ({) and no equals sign (=). This is not an
assignment statement but a method of assigning values to the array as though
the elements were its properties. This method offers better performance at run
time than the other method, which entails an array literal to the array.
Also, this method works only when the array has sufficient elements to accept
the new values in braces; EGL does not automatically add more elements. For
this reason, you must specify a starting length for the array or otherwise add
elements to it before you can assign values to elements with a set-value block.
v You can assign an array literal to the array:
This method is a little slower than the set-value method because the generated
code must create two arrays: one for the variable and one for the literal.
You can also use either of these two methods to assign values to the array when
you create it:
myStringsInit string[] {"Hello", "Goodbye"};
myBigIntsInit bigint[] = [10, 40];
If you want to assign properties to the array as well as specifying starting values
in the set-value block, put the property name-value pairs after the starting values:
myDecimals decimal(10,2)[3] {55.43, 22.12, 4.34, CurrencySymbol = "$"};
If you are using the array literal method of specifying starting values, you can set
properties with the set-value block as usual:
myBools boolean[3]{MaxSize = 5} = [true, false, true];
If you specify a number of elements in the array when you create it, that array is
initialized to contain that number of elements. Each element has the default value
for its type:
fiveInts int[5];
SysLib.writeStderr(fiveInts[1]); //Writes "0"
It’s good coding practice to specify a starting length for the array when you create
it so that EGL can initialize it. You can always add or remove elements later with
array functions such as appendElement and removeElement.
However, if you do not specify a starting length for the array, it starts as null, so
there is nothing in the array to be accessed:
nullArray int[];
nullArray[2] = 5; //NullValueException!
nullArray.appendElement(5); //NullValueException!
nullArray {1,2,3}; //NullValueException!
Instead, you must begin by initializing the array with an array literal:
nullArray2 int[];
nullArray2 = [1,2,3];
nullArray2.appendElement(4);
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];
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.
A function can receive parameters, execute EGL statements, and return a value to
the function that called it. Following is a simple example of a function:
Function addIntegers(int1 int in, int2 int in) returns (int)
sum int = int1 + int2;
return (sum);
end
stopNumber int = 7;
function main()
SysLib.writeStderr("Printing multiplication table through "
:: stopNumber);
i, j int;
SysLib.writeStderr("Finished.");
end
end
Library
A library part is a collection of functions and variables that are made
available locally to other logic parts. Functions in a library part can be
invoked in any order, while the main function in a program always runs
first. The following example shows a simple library part:
package libraries;
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
Introduction to functions
Functions are the fundamental units in EGL logic parts.
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,
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.
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)
A Library part is a generatable logic part with multiple entry points. You can
access a Library part by direct calls to the shared Library functions or by direct
references to the shared Library variables.
EGL provides many system Libraries that contain common functions. You can also
create your own Libraries of functions that you use frequently. The program uses
stereotypes to specialize code for functions. The following stereotypes are available
as part of the core EGL package:
BasicLibrary
Contains EGL-written functions and values for runtime use in other EGL
logic parts. This is the most common type of Library. For more
information, see “BasicLibrary stereotype” on page 111.
NativeLibrary
Enables code migrated from Informix 4GL to invoke a single, locally
running DLL (dynamic link library, also sometimes called a driver). Most
Many properties that determine the behavior of your generated code are available
to Libraries. The properties that are available depend on the stereotype of the
Library. See Library properties and NativeLibrary properties.
An EGL Library is generated separately from the parts that use it. At run time,
EGL loads the Library the first time you use it, and unloads it when the run unit
ends. If a Library invokes another Library, the invoked Library remains in memory
as long as the invoking Library does.
Related concepts
“Introduction to logic parts” on page 105
Logic parts define a sequence of instructions. Most logic parts contain one or
more functions, which are the basic unit of logic.
“BasicLibrary stereotype”
The BasicLibrary stereotype identifies a Library part that contains EGL-written
functions and values for runtime use in other EGL logic parts.
“NativeLibrary stereotype” on page 112
Customers migrating from Informix 4GL need the NativeLibrary stereotype to
hold their C language subroutines.
Related reference
Library properties
NativeLibrary properties
The NativeLibrary stereotype provides additional properties to the standard set
of Library properties.
BasicLibrary stereotype:
// 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:
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.
RUIPropertiesLibrary stereotype:
When you are writing a Rich UI application, set up an Rich UI properties library
(stereotype RUIPropertiesLibrary) if you want to retrieve displayable text from
external files rather than hard-coding the text.
For details on this stereotype, see the following files in the EGL Language
Reference:
v Use of properties files for displayable text
v RUIPropertiesLibrary stereotype
Related concepts
Use of properties files for displayable text
RUIPropertiesLibrary stereotype
“Introduction to Library parts” on page 110
Library parts support the sharing of functions and variables.
A requester is a program or other code that accesses the functions that are defined
in a service. The requester can be a program, handler, library, or another service,
and can be local or remote.
When you want to consume a service, you create an Interface part. The interface
provides EGL with a list of the functions that the service provides. To handle the
connectivity, use the EGL deployment descriptor file. The deployment descriptor
file describes how other applications can use a Service part from your application,
or how your application uses an external service. For more information about
Interface parts, see “Introduction to Interface parts” on page 114. For details about
the deployment descriptor file, refer to the EGL Generation Guide.
You can call a function from a service much as you would call a function from a
library, but you must first declare a variable based on the service:
myEcho EchoString;
result STRING;
result = myEcho.returnString("Hello!");
You might want to create a service in this way to act as a wrapper for the called
program. In this context, a wrapper refers to a logic part that has no meaningful
logic in itself but exists only to provide other applications access to another logic
part.
1. In the Project Explorer view, right-click a file containing an EGL called program
part and then click EGL Services → Create Program Call Function. The New
EGL Service Part window opens.
2. Enter the location and file name information for the Service part as in “Creating
EGL source files” on page 90.
If you type the name of an existing Service part and then select the Update
existing files check box, EGL adds a function to the existing Service part that
calls the called program. If you type a name for a new Service part, EGL
creates the new part and adds a function that calls the called program.
3. Click Finish.
Related concepts
“Overview of service-oriented architecture (SOA)” on page 475
Accessing IBM i programs as Web services
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.
Related reference
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.
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.
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.
Delegate part
A Delegate part provides a model for a function.
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.
This mapping is similar to the mapping that an Interface part provides for Service
functions, but mapping EGL to external language elements is generalized to
include fields and constructors. The only external element that ExternalType part
supports is the Java object.
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.
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
This method is provided mainly for compatibility and to preview the WSDL file
that will be created when you deploy your service. If you want to expose a Web
service to other applications through a WSDL file, add Web service binding
information to an EGL deployment descriptor file and then generate the project to
create a WSDL file. See “Exposing a service to other applications” on page 493.
1. In the Project Explorer view, right-click the file that contains the Service part
and then click EGL Services → Generate WSDL File. The Create WSDL file
window opens.
2. Fill out the Project Source, Folder, and WSDL file name fields with the
location and name of the new WSDL file.
3. Under Advanced, provide the deployment information to be added to the
WSDL file.
4. Click Finish.
The new WSDL file is created in the location that you specified. This file is not
updated automatically, so if the service information changes, you must recreate or
edit the WSDL file.
Related tasks
“Exposing a service to other applications” on page 493
Your EGL application can act as a service by exposing its functions to other
applications.
“Adding Web service deployment information to the deployment descriptor”
on page 496
After you have coded a service part that you want to expose as a Web service,
you must add information to the deployment descriptor that tells EGL to
generate the necessary Web service wrapper.
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.
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
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
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
Some properties are provided for compatibility with previous versions or migrated
code and are unnecessary for new EGL applications. To know which properties are
provided for new code and which are used for compatibility, see the EGL Language
Reference topic that covers a particular part and its properties.
When you create a part based on another part, the new part inherits the properties
of the old part:
In this case, the field myField behaves as though you had specified the color
property on it.
In this case, myBlueInt still has the color property set to blue.
In this case, the field myField overrides the red value with the blue value.
In this way, it is legal but not recommended to define a property twice for one part
or variable. The last property specification sets the value, as in this example:
myBlueVar int {color = red, color = blue};
In this case, the variable’s color property is set to blue because the second
definition overrides the first.
Related concepts
“Introduction to EGL parts” on page 95
Parts are the building blocks of EGL applications.
Related reference
Properties
Set-value blocks
EGL import and use statements are commonly used in these situations:
v You import a logic part (such as a Program or Library) or a data part (such as a
Record or DataItem) so that you can refer to the part as though it were part of
the current package.
v You import an entire package so that you can refer to any of the parts that it
contains as if they were part of the current package.
v You use a library that is in your current package so that you can drop the
library prefix from any function names or variable names that you use from that
library.
You can refer directly to any of the parts that EGL defines without having to
import them, and you can refer directly to functions in system libraries or
EGL-defined enumerations without having to use them. These parts are therefore
described as implicitly imported and used.
For example, you can call the sysLib.writeStdOut() system function without
referring to the library because of this implicit use:
writeStdOut("Progam complete.");
Example
You might want to access customer information in your accounts receivable (AR)
package using the data definitions and functions from your customer relations
management (CRM) package. To call the function getCustomer() from the library
CustomerLib in the package com.companyb.crmpackage, you can use the following
code:
package com.companyb.arpackage;
function main()
getCustomer();
end
end
You can comment a single line of code at once, or you can create a block of
commented lines.
v To comment a single line or a portion of a line, use two virgules or slashes (//):
myInt int; //This is an integer variable
//The following function is for error checking
function validateData (inputRecord myRecord inOut)
end
v To comment a block of lines, begin the comment with /* and end the comment
with */:
/*
This function is commented.
function myPlannedFunction()
end
*/
To comment lines, you can type the comment characters yourself, or you can tell
the EGL editor which lines to comment. Follow these steps to comment lines of
code in the EGL editor:
1. In the EGL editor, highlight one or more lines of code.
2. Right-click the highlighted lines and then click Comment. Comment indicators
(//) are placed at the beginning of each line in the selected range.
Use the same procedures to uncomment lines, but select Uncomment from the
pop-up menu.
Related concepts
“The EGL editor” on page 155
The EGL code editor looks and works like a standard text editor or code editor
for other languages, but it has additional features to help you edit EGL code.
The code editor highlights invalid syntax, provides an explanation for problems
in the code, colors keywords, strings, and comments, and helps you write EGL
code.
Related tasks
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.
Calling Java
There are several ways to call Java code when you are generating Java from EGL.
This topic covers a few of the most common ways, including using the system
functions in the JavaLib system library such as javaLib.invoke(), and declaring an
ExternalType part.
Prerequisites
v An EGL project generated to Java, not to COBOL
v An EGL program or other logic part
If you need to use a method in a Java class only once, you can use the
javaLib.invoke system function.
The only methods you can call in this way are the methods defined as static.
″Static″ is a Java term that has no parallel in EGL; in this context, it means that the
method is ready to be called at any time and needs no initialization before use.
1. In an EGL function within a logic part, declare any variables that you might
need to pass or that you might need to accept a return value:
myNumber float;
2. Use the javaLib.invoke() system function to call the method, passing the name
of the class and the method to call as parameters:
myNumber = javaLib.invoke("java.lang.Math", "random");
3. Then, you can use the results of the call:
sysLib.writeStderr(strLib.formatNumber(myNumber));
If you plan to use methods in a Java class several times, or if the method that you
want to call is not defined as static, you should create an ExternalType part, as in
″Creating an ExternalType part to represent a class″ that follows. However, for
compatibility with migrated programs, and with a little less EGL code, you can use
other functions in javaLib to initialize and use a class multiple times, even its
non-static methods.
The following example uses a different class that returns random numbers. The
method nextInt in the class java.util.Random provides an alternate way to return
a random integer. Because the method is not defined as static, you cannot use
javaLib.invoke() to call nextInt without any preparation:
//Error! The method nextInt() is not static.
myInt int = javaLib.invoke("java.util.Random", "nextInt");
Instead, you must first initialize the class and give it an identifier in EGL using
javaLib.storeNew(). Note the use of the casting operator, AS, to convert Java types
to EGL:
javaLib.storeNew("myRandomGenerator" AS "objId:java", "java.util.Random");
If you plan to use the class often, or if the method that you want to use is not
defined as static, you can define an EGL ExternalType part, an EGL part that
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
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));
function main()
myRandomGenerator Random = new Random();
myInt int = myRandomGenerator.nextInt();
SysLib.writeStderr(StrLib.formatNumber(myInt));
end
end
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
The values of the text types (CHAR, MBCHAR, DBCHAR, UNICODE, STRING),
data and time types (DATE, TIME, TIMESTAMP, and INTERVAL), and HEX do not
end with a null byte. You can use StrLib.setNullTerminator to convert trailing
blanks to null, or StrLib.setBlankTerminator to convert trailing nulls to blanks.
For arrays, the data passed to the C function is as follows, in this order:
1. An INT value representing the current length of the array
2. An INT value representing the maximum size of the array
3. The following data for each element in the array:
a. If the element is a STRING or a record, an INT value representing the
length of the element’s data
b. The data of the element
c. If the element is nullable, a SHORT representing the element’s nullability. If
the element is nullable and has a null value, the value of the SHORT is -1.
d. If the element is nullable, a SHORT as a filler value. EGL ignores this value.
For non-structured records, the data passed to the C function is as follows, in this
order:
1. An INT value, representing the number of fields
2. The following data for each field in the record:
a. An INT value representing the length of the field’s data
b. The field’s data
c. If the field is nullable, a SHORT representing the field’s nullability. If the
field is nullable and has a null value, the value of the SHORT is -1.
d. If the element is nullable, a SHORT as a filler value. EGL ignores this value.
For structured records, EGL passes the data of the lowest-level fields. You could
define a C struct with the same structure as the record.
Related reference
“Calling C functions with the call statement” on page 131
Primitive data types
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.
char *fun_name;
int (*fptr)(int);
};
With your C shared library, function table, and stack library linked, you are now
ready to invoke the C functions from your EGL code. For information on how to
invoke a C function in EGL, see Invoking a C function from an EGL program.
Related concepts
Linkage options part
Related reference
“BIGINT functions for C” on page 138
“Mapping EGL data types to C” on page 132
“DATE functions for C” on page 139
“DATETIME and INTERVAL functions for C” on page 139
“DECIMAL functions for C” on page 140
“Invoking a C function from an EGL program”
“Return functions for C” on page 144
“Stack functions for C” on page 141
For example, the following function invocation statement calls the C function
sendmsg( )
sendmsg(chartype, 4, msg_status, return_code);
It passes two arguments (chartype and 4, respectively) to the function and expects
two arguments to be passed back (msg_status and return_code, respectively). This
is made clear by defining the function in a native library as follows:
Library I4GLFunctions type nativeLibrary
{callingConvention = I4GL, dllName = "mydll"}
Function sendmsg(chartype char(10) in, i int in,
msg_status int out, return_code int out)
end
end
The arguments passed are specified using the ″in″ parameter and the arguments to
be returned are specified using the ″out″ parameter.
callingConvention
specifies that the arguments will be passed between functions and the calling
code using the argument stack mechanism.
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.
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
The BIGINT data type is internally represented with the ifx_int8_t structure.
Information about the structure can be found in the header file int8.h, which is
included in the ESQL/C product. Include this file in all C source files that use any
of the BIGINT functions.
All operations on int8 type numbers must be performed using the following
ESQL/C library functions for the int8 data type. Any other operations,
modifications, or analyses can produce unpredictable results. The ESQL/C library
provides the following functions that allow you to manipulate int8 numbers and
convert int8 type numbers to and from other data types.
The following date-manipulation functions are in the ESQL/C library. They convert
dates between a string format and the internal DATE format.
For more information about the individual functions, see the following: IBM
Informix ESQL/C Programmer’s Manual.
Related reference
“BIGINT functions for C” on page 138
“DATETIME and INTERVAL functions for C”
“DECIMAL functions for C” on page 140
“Invoking a C function from an EGL program” on page 136
The DATETIME and INTERVAL data types are internally represented with the
dtime_t and intrvl_t structures, respectively. Information about these structures can
be found in the header file datetime.h, which is included in the ESQL/C product.
Include this file in all C source files that use any of the DATETIME and INTERVAL
functions.
You must use the following ESQL/C library functions for the datetime and
interval data types to perform all operations on those types of values.
For more information about the individual functions, see the following: IBM
Informix ESQL/C Programmer’s Manual.
Related reference
“BIGINT functions for C” on page 138
“DATE functions for C” on page 139
“DECIMAL functions for C”
“Invoking a C function from an EGL program” on page 136
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.
For more information about the individual functions, see the following: IBM
Informix ESQL/C Programmer’s Manual.
Related reference
“BIGINT functions for C” on page 138
“DATE functions for C” on page 139
“DATETIME and INTERVAL functions for C” on page 139
“Invoking a C function from an EGL program” on page 136
You can call the following library functions from a C function to pop number
values from the argument stack:
v extern void ibm_lib4gl_popMInt(int *iv)
v extern void ibm_lib4gl_popInt2(short *siv)
v extern void ibm_lib4gl_popInt4(int *liv)
v extern void ibm_lib4gl_popFloat(float *fv)
v extern void ibm_lib4gl_popDouble(double *dfv)
v extern void ibm_lib4gl_popDecimal(dec_t *decv)
v extern void ibm_lib4gl_popInt8(ifx_int8_t *bi)
The following table and similar tables below map the return function names
between I4GL pre-Version 7.31 and Version 7.31 and later:
Each of these functions, like all library functions for popping values, performs the
following actions:
1. Removes one value from the argument stack.
2. Converts its data type if necessary. If the value on the stack cannot be
converted to the specified type, an error occurs.
3. Copies the value to the designated variable.
The structure types dec_t and ifx_int8_t are used to represent DECIMAL and
BIGINT data in a C program. For more information about the dec_t and ifx_int8_t
structure types and library functions for manipulating and printing DECIMAL and
BIGINT variables, see the IBM Informix ESQL/C Programmer’s Manual.
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)
The len argument sets the maximum size of the receiving string buffer. Using
ibm_lib4gl_popQuotedStr( ), you receive exactly len bytes (including trailing
blank spaces and the null), even if the value on the stack is an empty string. To
find the true data length of a string retrieved by ibm_lib4gl_popQuotedStr( ), you
must trim trailing spaces from the popped value.
You can call the following library functions to pop DATE, INTERVAL, and
DATETIME (TIMESTAMP) values:
v extern void ibm_lib4gl_popDate(int *datv)
v extern void ibm_lib4gl_popInterval(intrvl_t *iv, int qual)
You can call the following library function to pop TIMESTAMP values:
v extern void ibm_lib4gl_popDateTime(dtime_t *dtv, int qual)
The structure types dtime_t and intrvl_t are used to represent DATETIME and
INTERVAL data in a C program. The qual argument receives the binary
representation of the DATETIME or INTERVAL qualifier. For more information
about the dtime_t and intrvl_t structure types and library functions for
manipulating and printing DATE, DATETIME, and INTERVAL variables, see the
IBM Informix ESQL/C Programmer’s Manual.
You can call the following function to pop a BYTE or TEXT argument:
v extern void ibm_lib4gl_popBlobLocator(loc_t **blob)
The structure type loc_t defines a BYTE or TEXT value, and is discussed in the
IBM Informix ESQL/C Programmer’s Manual.
Any BYTE or TEXT argument must be popped as BYTE or TEXT because EGL
provides no automatic data type conversion.
Working with EGL code 143
Related reference
“BIGINT functions for C” on page 138
“Mapping EGL data types to C” on page 132
“Calling C functions through EGL libraries” on page 133
“DATE functions for C” on page 139
“DATETIME and INTERVAL functions for C” on page 139
“DECIMAL functions for C” on page 140
“Invoking a C function from an EGL program” on page 136
“Return functions for C”
The external return functions copy their arguments to storage allocated outside the
calling function. This storage is released when the returned value is popped. This
situation makes it possible to return values from local variables of the function.
Note: The return functions were originally used with IBM Informix 4GL (I4GL);
hence the inclusion of ″4gl″ in the function names.
The following table maps the return function names between I4GL pre-Version 7.31
and Version 7.31 and later:
C functions called from EGL must always exit with the statement return(n), where
n is the number of return values pushed onto the stack. A function that returns
nothing must exit with return(0).
Related reference
“BIGINT functions for C” on page 138
“Mapping EGL data types to C” on page 132
“Invoking a C function from an EGL program” on page 136
“Calling C functions through EGL libraries” on page 133
“DATE functions for C” on page 139
“DATETIME and INTERVAL functions for C” on page 139
“DECIMAL functions for C” on page 140
“Stack functions for C” on page 141
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.
However, if you hard-code your password in a place other than the function call,
EGL does not encrypt the password:
myPasswordVariable string = "myPassword";
sqlLib.connect(myDatabase, myUserid, myPasswordVariable);
In this case, the password is not encrypted and is displayed in the generated
source.
You can manually encrypt your password by running the command-line utility and
using the returned encrypted value in your code:
myPasswordVariable string = "crypto:abcdef12345";
sqlLib.connect(myDatabase, myUserid, myPasswordVariable);
Following are some places where you might need to manually encrypt hard-coded
passwords:
v Variables in which you store passwords
v CallLink element properties, such as ctgKeyStorePassword
v Calls to system functions, such as sqlLib.connect, sysLib.setRemoteUser, or
VGLib.connectionService in which you do not pass the password as a literal in
the function call
When an EGL system function receives a password with the crypto: prefix, it
decrypts the password automatically. For this reason, you must encrypt any
passwords beginning with the characters crypto:; otherwise, EGL will attempt to
decrypt the non-encrypted password.
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:
The myErrorHandler() function could, for example, take care of initializing the
array and perform the assignment again.
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
If EGL throws an exception but no onException block catches the exception, the
function ends immediately and control returns to the function that called the
function that threw the error. In this way, EGL passes the exception upward until a
function catches the exception with an onException block or the exception reaches
the main function. If the main function fails to catch the exception, the program
ends immediately and writes the message field of the exception to the log. When
an exception occurs in a remotely called program, the calling program receives an
InvocationException rather than the original exception. Similarly, an exception in a
service function delivers a ServiceInvocationException to the calling program.
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:
if (myCustomer is noRecordFound)
add myCustomer;
end
v Catch the exception, which is the preferred technique:
try
get myCustomer;
onException (myEx FileIOException)
if (myCustomer is noRecordFound)
add myCustomer;
else
myErrorHandler(myEx);
end
end
In addition to the exceptions that the system defines, you can create your own
exception records. As with other records, you must define a Record part first, and
then declare a variable based on it.
Record CustomerException type Exception
customerNumber INT;
end
...
throw new customerException {
customerNumber = custNum,
message = "Illegal customer number" };
Custom exceptions records like this one automatically include the messageID and
message fields, just like the system exception records.
V6 exception compatibility
For compatibility with earlier versions, you can still use the error handling
methods from version 6 of EGL.
You specify V6 exception mode on a program-by-program basis when you set the
program’s v60ExceptionCompatibility property to YES. However, for best results
use the same setting for all of your programs.
V6 exceptions are typically handled through a try block. The difference is that V6
exceptions allow only a single onException statement, and do not specify an
exception type. The behavior is thus the same as if the onException statement had
an implied AnyException modifier:
try
posNum = abs(myVar);
onException
if(sysVar.errorCode = "00000008") // invalid input
myErrorHandler1();
if(sysVar.errorCode = "00000012") // cannot assign value
The customized messages are stored in a properties file that you identify in the
vgj.messages.file Java runtime property. This property is set with the
userMessageFile build descriptor option. For more information about the format of
a Java properties file, see Program properties file.
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.
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.
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.
The main tool that the EGL editor provides to speed up code development time is
code assist. Code assist searches for valid keywords, variables, or part names that
begin with the first few characters that you type and the matching code. To
activate code assistance, press CTRL+Space and choose a keyword, variable, part,
or function from the list of options. You can also type the first few characters of a
keyword, part, or variable to filter the list. See “Content assist” on page 157.
Code assist can also insert larger code templates into your code, such as a
framework for a part. See “Code templates” on page 158.
The editor also includes wizards that can generate EGL code into the file you are
editing. For example, the DataItem part source assistant can help you set the
properties for a DataItem part. See “Editing DataItem parts with the source
assistant” on page 167.
Getting help
The editor provides dynamic help for most EGL keywords. To activate dynamic
help, highlight an EGL keyword, such as package, and press F1. Additionally, the
F1 key provides dynamic help when you are in most EGL-related wizards and
windows.
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.
The formatting preferences affect how the code is formatted in the editor, including
what characters and how many characters to use for indentation, whether to use
upper or lower case for keywords, and how much white space to include in the
source code.
You can create one or more EGL editor profiles using the EGL Editor Formatter
preference. There are two formatting profiles defined within EGL:
v EGL [build in]
v VA Gen [build in]
You cannot change the formatting preferences within these two profiles or remove
these profiles. Any profile that you create is added to the list of available profiles.
You can change or remove any profile that you create.
See “Setting preferences for formatting in the EGL editor” on page 177 for defining
editor profile preferences.
Related tasks
“Working with EGL code” on page 127
Content assist
The EGL content assist is a tool that you can use to complete programming
statements without having to type the entire statement. It provides a way to
quickly insert an EGL keyword, function, variable, property, or code template.
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,
The that name you give your code templates is significant because that name is the
keyword that represents the code template, not the first word of the code in the
template itself. For example, assume you have created a code template named
″myFunction″ that consists of an EGL function, beginning with the keyword
function. When you want to insert this template, you must begin by typing letters
from the name, such as my or myFunc, not f or fun. Templates are displayed in code
assist only when you have typed at least one character to filter the list of options.
Also, if you begin the code template with an EGL keyword such as function, the
template will be available only when the cursor is in a place where that keyword is
valid. In this case, the function template would be an option only if the cursor is in
a place where a function would be valid. If the beginning of the template is not an
EGL keyword, the template can be inserted anywhere.
Related concepts
“Content assist” on page 157
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can
be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.
Related tasks
“Enabling and disabling code templates”
“Creating code templates” on page 160
“Editing code templates” on page 161
“Removing code templates” on page 163
“Importing code templates” on page 162
“Exporting code templates” on page 162
“Restoring default code templates” on page 163
If the code template you edited is one of the templates provided with the product,
you can revert to the original template as follows:
1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL → Editor and then click Templates. A list
of templates is displayed.
3. Click the desired template from the table and then click Revert to Default.
4. To save your changes, click Apply.
5. Click OK to close the window.
Related concepts
“Content assist” on page 157
“Code templates” on page 158
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can
be a piece of code or a complete programming task. In addition to the default
snippets provided in the workbench, you can create your own snippets.
Related tasks
“Enabling and disabling code templates” on page 159
“Creating code templates” on page 160
“Importing code templates” on page 162
“Exporting code templates” on page 162
“Removing code templates” on page 163
“Restoring default code templates” on page 163
Alternately, you can restore a single code template to the default shipped with the
product. See “Editing code templates” on page 161.
Code snippets
Snippets are code objects that are reusable programming objects. Snippets can be a
piece of code or a complete programming task. In addition to the default snippets
provided in the workbench, you can create your own snippets.
The Snippets view provides access to the snippets available for use. The Snippets
view contains several pieces of EGL code, as well as code for many other
technologies. The following table lists the snippets that are available in EGL.
Table 28. Snippets available in EGL
Snippet name Description
Set cursor focus (JSP) A JavaScript function that sets the cursor
focus to a specified form field on a Web
page. See “Setting the focus to a form field”
on page 418.
Auto redirect (JSP) A JavaScript function that tests for the
presence of a session variable. If the session
variable is not present, it forwards the
browser to a different page. See “Testing
browsers for a session variable” on page 425.
Get clicked row value An EGL function that retrieves the
hyperlinked value of a clicked row in a data
table. See “Retrieving the value of a clicked
row in a data table” on page 417.
database update An EGL function that updates a single row
of a relational table when passed a record
from a JSF Handler. See “Updating a row in
a relational table” on page 423.
Related concepts
“Content assist” on page 157
“Code templates” on page 158
Note: If the cursor turns into a circle with a strike through it, indicating that
the snippet can not be inserted at that point, you may be trying to insert
the snippet into the wrong place. Check the snippet’s details to find out
where it should be inserted in the code.
5. Change the predefined names of functions, variables, and data parts in the
snippet as appropriate to your code. Most snippets include comments that
explain what names need to be changed.
Related concepts
Snippets view
“Code snippets” on page 164
Snippets are code objects that are reusable programming objects. Snippets can
For more information on cheat sheets, see Working with cheat sheets.
This search returns part definitions and references; it does not search your project
for a text match to a string. For a textual search of your project, click Search → File.
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.
While viewing a list of parts in the EGL Parts List view, you can filter the list to
include only certain parts:
1. Populate the EGL Parts List view with EGL parts.
2. From the list at the top right corner of the EGL Parts List view, click Filters.
The EGL Parts List Filter window opens.
3. In the EGL Parts List Filter window, set the criteria for the filter:
v To filter by project, folder, package, or file, select or deselect the resources
under Part Resources.
v To filter by type of part, select or deselect the types of parts under Part Type.
v To filter by part name, enter a part name in the Part name filter field. A
question mark (?) represents any one character and an asterisk (*) represents
a series of any characters.
4. When you are finished setting the filter in the EGL Parts List Filter window,
click OK. Only the parts that match the filter criteria are shown in the EGL
Parts List view.
Related concepts
“Introduction to EGL parts” on page 95
Parts are the building blocks of EGL applications.
Related tasks
To open a generatable logic part in the EGL Parts Reference view, right-click the
file that contains the part in the Project Explorer view and then click Open in Parts
Reference. After the part opens in the view, you can expand its hierarchy to see
the parts that are referenced. Alternatively, you can right-click the part in the
Outline view or the EGL Parts List view and then click Open in Parts Reference.
In the EGL Parts Reference view, you can perform several tasks on a part or its
referenced parts:
v Open a part in the EGL editor by double-clicking the part.
v Search for related EGL code by right-clicking on the part, clicking References or
Declarations, and then selecting a scope for the search.
You can also search for parts or text strings among the parts in the view:
1. Right-click the EGL Parts Reference view and then click Find in tree.
The EGL Parts Reference Find window opens.
2. Type a search string into the Search string field.
v A question mark (?) represents any one character
v An asterisk (*) represents a series of any characters
For example, type my?Part to locate parts named ″my1Part″ and ″my2Part″, but
not ″my10Part″. Type my*Part to locate parts named ″my1Part″, ″my2Part″, and
″my10Part″.
3. Choose a search type. Part search searches for EGL parts and Text search
searches for text within the part.
4. Select the options for the search.
v If you selected Part search, you can select a type of part to search for by
clicking a radio button under Search For.
v Under Direction, choose to search Forward or Backward from the currently
selected part.
v To make a text search case-sensitive, select the Case sensitive check box.
v To continue searching from the other end if the search reaches the bottom or
the top of the tree, select the Wrap search check box.
v To search for only a complete part name or text string, select the Whole
word check box.
5. When you are finished setting the criteria for the search, click Find. The first
result of the search is highlighted in the EGL Parts Reference view.
6. To move to the next result, click Find.
7. When you are finished, click Close.
To locate an EGL source file in one of these views, right-click the open file in the
EGL editor and then click Show in → ProjectExplorer. You can also click Show in →
Outline or Show in → Navigator to display where the file is in one of those views.
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
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.
To change the fonts and colors used in the EGL editor, follow these steps:
1. Click Window → Preferences.
2. In the Preferences window, click General → Appearance → Colors and fonts.
3. On the Colors and Fonts page, expand EGL and click EGL Editor Text Font.
4. Click Change.
5. In the Font window, select the font to use in the EGL editor, including the
typeface, size, and color.
6. Click OK.
7. If you want to restore settings, you can click Reset to return to the defaults for
the workbench, and you can click Use System Font to use your computer’s
default font.
8. Click OK to close the Preferences window.
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related tasks
“Setting preferences for the EGL editor” on page 175
“Setting general preferences” on page 173
Folding has no effect on EGL source code or generated source; it is only a tool to
view the active parts of your source code while hiding parts that you are not
currently working with.
Follow these steps to set preferences for organizing the import statements in your
code:
1. From the main menu, click Window → Preferences.
2. In the Preferences window, expand EGL → Editor and click Organize Imports.
3. On the Organize Imports page of the Preferences window, set the order for
import statements in the list of package names:
v To add a new package or prefix to the list, click New and type the new
name. You can use the asterisk character as a wild card at the end of the
package name.
v To reorder the packages and prefixes, click a package or prefix in the list to
select it and then click Up or Down.
4. In the Number of imports needed field, enter the minimum number of
individual import statements in the same package to simplify into an import
statement with a wild card character.
For example, your file might have the following similar import statements:
import com.mypackage.myPart1;
import com.mypackage.myPart2;
import com.mypackage.myPart3;
If you set the Number of imports needed field to 3, the editor will simplify
these import statements into the following single import statement:
import com.mypackage.*;
5. Click Apply to save the changes and remain in the Preferences window. Click
OK to save the changes and exit the window.
To organize your import statements, open a source file in the editor, right-click the
file, and then click Organize Imports. Alternatively, you can organize the import
statements for every file in a project or package by right-clicking the project or
package in the Project Explorer view and then clicking Organize Imports.
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related tasks
“Enabling EGL capabilities” on page 11
Capabilities keep the workbench menus from becoming cluttered by hiding
items you do not use. You can always perform these tasks, but to make them
appear in the menus, you must enable the capability for that area of
functionality.
The most common type of database is the relational database. In very simple terms,
the information in a relational database resides in tables that can refer to each
other. A relational database management system (RDBMS) keeps track of the tables
and relationships. You use a special language, called SQL, to communicate with the
database manager. Some popular types of RDBMS include IBM DB2, Microsoft®
SQL Server, Oracle, and the open-source MySQL.
Another option is to use a lower level data structure that is provided by your
operating system. Using this type of data source enables you to manage more of
the details of data storage and retrieval yourself. IBM MVS™ systems use a file
access method called VSAM (Virtual Storage Access Method) that enables you to
write directly to several different types of file, including plain sequential access
files and indexed files (which keep track of data by means of a key).
The EGL strategy is to provide a few basic commands (like get, which fetches
information and puts it into a record) that focus on business logic rather than
implementation details. For an overview of how this works, see “Reading and
writing records” on page 184.
Related tasks
“Reading and writing records” on page 184
“Creating a data access application” on page 208
EGL can create a simple data access application based on a database to which
you are connected. The resulting application contains data parts, logic parts and
(optionally) Web pages that are based on one or more database tables.
“Viewing implicit SQL statements” on page 217
The goal of information processing is to transform data (raw facts and figures) into
information (data that means something and increases knowledge). Common
processes include:
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.
The details of the record, and its properties, will vary depending on how you plan
to use it.
Next, within the body of your program, declare a variable based on this Record
part:
myCustomer CustomerRecord;
To find an existing customer record, you will need a unique piece of information
about the record. Typically this means some kind of ID number, often used as a key
to the file. A key is a piece of data used to index a file, so you don’t have to look
at every record to find the one that you want. Assume that you have separately
written a function called getCustomer() that asks the user for a customer number
and returns that number:
myCustomer.customerNumber = getCustomer();
To read the information that matches the requested number, simply code the
following:
get myCustomer forUpdate;
EGL generates the appropriate code to read the data from the file or database and
then places the information in your record variable. The forUpdate keyword tells
EGL to place a hold on the data so you have the option to replace or delete it.
You can then offer the information to your user with the option to change it.
Assume that you have separately written a function called showCustomer() that
returns a –1 if the user wants to delete the record, 0 if the record is unchanged,
and 1 if the user made any changes to the record:
case (showCustomer(myCustomer))
when (-1)
delete myCustomer;
when (1)
replace myCustomer;
end
If you handle errors (see “Handling errors” on page 148), you can do a bit more
with the number that getCustomer() returns. Assume that you have separately
written a function called getReply() that returns TRUE or FALSE depending on
whether the user answers Y or N to the specified question:
try
get myCustomer forUpdate;
onException (ex AnyException) // couldn't get the record
if(myCustomer is noRecordFound) // because customer # not on file
if(getReply("Do you want to add this customer? (y/n)") == TRUE)
showCustomer(myCustomer); // let user fill in remaining fields
add myCustomer;
end
else
myErrorHandler(ex);
end
With these few lines of code you have the heart of a customer file service program
that you can use with an SQL database or your own VSAM indexed file. The only
difference in your program between VSAM and SQL is the stereotype you apply to
the CustomerRecord definition.
Related concepts
“Introduction to Record parts” on page 100
Record parts are collections of other data parts. The data parts within the
Record part are referred to as fields. A Record part can contain any number of
fields, and the fields can be primitives, data items, or other records.
Related tasks
“Handling errors” on page 148
With EGL, you can decide how your program behaves in case of errors.
EGL allows you to write and read several types of files, including indexed files,
sequential files, and comma-separated value (CSV) files, also known as delimited files.
These types of files differ mostly in the way they store information to the file; the
process of reading the file and writing to the file is similar for each type. This topic
deals with sequential files and CSV files.
Prerequisites
v An EGL project
To connect to a file, you must first define a resource associations part that points to
that file. The file itself can be a data set as well as a file on your system, but this
example uses a local file.
1. Open the project’s build descriptor.
2. Add a resource associations part to the build descriptor and open that part in
the build parts editor. See ″Adding a resource associations part to an EGL build
file.″
3. In the new resource associations part, add a new association to the location
where the sequential file will go:
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:
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.
Reading data from a sequential or CSV file is similar to reading from any other
data source, except that you must read the records in order.
In general, use the get next statement to read a single record and the get statement
to read multiple records when you deal with serial records. In this context, get
next begins with the first record in the sequential file and reads the records in
order.
1. Open an EGL program or other logic part.
2. Make sure that your serial record part is in scope and is associated with the
sequential file as described in ″Setting up a resource association″ above. You
might need to use an import statement to bring it into scope:
import myProject.myData.mySerialRecord;
3. In an EGL logic part, declare a variable that is based on your serial record:
variableRecord mySerialRecord;
4. Retrieve a record from the sequential file using the variable:
get next variableRecord;
5. Use the data from the sequential file:
sysLib.writeStderr(variableRecord.myChar);
6. Save, generate, and run the program. The program reads the sequential file and
displays the data from the record in the console:
Hello!
One of the advantages of CSV files is that they are human-readable. Here is a
simple example of a CSV file:
123,yes,3/9/2007,Rahima
-1,no ,9/9/1999,Jorge
92,yes,,Ludmilla
This example shows three lines of data, each with four pieces of information. Each
piece of information is separated by a character called a delimiter, in this case a
comma. Note that the third piece of data in the third line is null, as indicated by
no data between the delimiters. CSVRecord parts treat each of these pieces of
information as a field. A CSVRecord for this file would look like this example:
record CsvRec type CSVRecord
{
fileName = "CSVFile",
delimiter = ",",
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()
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
When you are creating a new EGL project whose code will access an
LDAP-compliant server, select the EGL project feature EGL with LDAP Support
by updating an Advanced Setting. Similarly, when you are adding LDAP support
to an existing project, add the EGL project feature EGL with LDAP Support from
the Properties of the project. The effect in each case is to add the server-access files
LDAPExternalTypes.egl and LDAPLib.egl to the project.
For more information about LDAP, see Sample: EGL LDAP access.
EGL provides two options in dealing with SQL data. If you are doing fairly
common and straightforward tasks, you can simply use EGL statements to perform
Topics in this section will show you how to connect EGL to your SQL database
(see “Creating an SQL database connection” on page 197), as well as shortcuts for
creating SQL records (see “Retrieving SQL table data” on page 205) and complete
SQL applications (see “Creating a data access application” on page 208).
Best practices
The following table shows where to use each of the EGL SQL techniques:
Table 30. Best practices for EGL SQL
SQL objective EGL approach
Simple SQL data manipulation (SELECT, Use EGL keywords (get, replace, add,
UPDATE, INSERT, DELETE). Primary key delete) and let EGL generate implicit SQL.
controls WHERE and ORDER BY.
Simple SQL data manipulation with reusable Place the custom WHERE clause in the
custom WHERE clause. defaultSelectCondition property.
SQL SELECT statements with custom Use explicit SQL through the #sql directive.
WHERE clause.
SQL table JOIN statement. Use the Retrieve SQL feature in the
workbench, then create use the
defaultSelectCondition property to correctly
join the tables on primary and foreign keys,
as in the following example:
defaultSelectCondition = #sqlCondition{
customer.customer_ID =
orders.customer_ID }
Derived data in SELECT command (such as Use explicit SQL through the #sql directive,
MAX() or AVG()) placing the derived fields inside the braces.
Create a custom SQLRecord, where the
column property for the individual fields
specifies the derived or computed
expression.
Complex or custom SQL UPDATE, INSERT, Use EGL replace, add, or delete statements
or DELETE statement. with explicit SQL (#sql directive).
Use explicit SQL through the execute #sql
statement.
SQL statements other than simple data Use explicit SQL through the execute #sql
manipulation (such as CREATE TABLE). statement.
Dynamic SQL (prepared SQL statement). Use explicit SQL through the execute #sql
statement.
Stored procedure. Use explicit SQL such as the following:
open result_set with #sql{
CALL stored_proc ( :host_var) }
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;
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
If the SQLRecord part is not a fixed record part, you can include primitive fields as
well as other variables. You are especially likely to include the following kinds of
variables:
v Other SQL records. The presence of each represents a one-to-one relationship
between the parent and child tables.
v Arrays of SQL records. The presence of each represents a one-to-many
relationship between the parent and child tables.
After you define an SQLRecord part, you declare a record variable that is based on
that part.
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
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.
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
CICS for z/OS, z/OS The generated code can access DB2 UDB directly
batch, iSeriesC
AIX, HP-UX, iSeriesJ, JDBC provides access to DB2 UDB, Oracle, Informix, or
Linux, Solaris, z/OS Microsoft SQL Server
UNIX® System Services,
Windows 2000/NT/XP
Related tasks
“Creating an SQL database connection” on page 197
The New Connection wizard creates an SQL database connection that you can
use either at design time or at run time.
“Reading and writing records” on page 184
“Retrieving SQL table data” on page 205
“Creating a data access application” on page 208
EGL can create a simple data access application based on a database to which
you are connected. The resulting application contains data parts, logic parts and
(optionally) Web pages that are based on one or more database tables.
“Viewing implicit SQL statements” on page 217
Even if you plan to use either of these functions, it is still recommended that you
have a default connection in place.
Prerequisites
You must have a database set up and running. The database must be one of the
products that EGL supports. See “Supported SQL database managers” on page 200
for more information.
Note: The Data perspective is not filtered for EGL, and includes information for
other products. Thus if you run the New Connection wizard from the
Data perspective, you might see databases listed (such as Generic JDBC or
Sybase) that EGL does not support. Use the table in ″Supported database
managers″ to determine the database managers that you can use with
EGL.
The information the wizard needs varies with the type of database that you use.
When you choose from the Select a database manager list, the wizard fills in as
many default values as it can. For the list of supported databases and the
information that each requires, see “Supported SQL database managers” on page
200.
When you have given the wizard enough information, the Test Connection button
becomes available. Click this button to verify your connection information. If you
get an error message, check your settings or work with your database
administrator to resolve the problem.
If the test is successful, you have everything you need to use the EGL features that
require a design-time connection, such as “Creating a data access application” on
page 208 or “Retrieving SQL table data” on page 205. You are not, however,
You can override the default values in these fields by selecting Other for your
JDBC driver and specifying the appropriate JDBC driver class.
The wizard will complete as many of the other fields as it can, but might require
you to fill in some or all of the following:
Connection Name
You will not need to complete this field if you check the Use default
naming convention option, which typically uses the name of your
database.
SID The ID of the server where your database is located.
Host The host name of your database server.
Port number
The port number that you connect to on the host.
Server The address of your database server.
Database
The name of the specific database to which you want to connect.
Class location
The fully qualified location of the *.jar or *.zip file that contains the driver
class:
v For IBM DB2 Universal Driver, type the fully qualified filenames to the
db2jcc.jar and db2jcc_license_cu.jar files
v For IBM DB2 APP DRIVER for Windows, type the fully qualified
filename to the db2java.zip file; for example, d:\sqllib\java\
db2java.zip
To create a connection, the New Connection wizard requests some or all of the
information in the right column. This information is provided so that you can
obtain the right information from a database administrator, if necessary. For more
information about these connection fields, see “Fields in the New Connection
wizard” on page 198.
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.
Error conditions
EGL uses a different process to connect with the database at run time than it does
at design time. These differences might result in errors when you try to run your
code:
v EGL might not be able to find the Java class containing the driver for your
database manager, even though you specified a Class location in the New
Connection wizard. To correct this error, make sure the driver is on the classpath
for your project:
1. Right-click on your project name in the Project Explorer view and click
Properties from the pop-up menu.
2. Select Java Build Path from the left pane of the Properties window.
3. Click the Libraries tab on the Java Build Path page.
4. If the correct class location is not displayed, click Add External JARs and
add the class and location. You can copy this information from your
Connection; see “Editing or deleting an SQL database connection” on page
205
.
Related tasks
“Creating an SQL database connection” on page 197
The New Connection wizard creates an SQL database connection that you can
use either at design time or at run time.
“Editing or deleting an SQL database connection” on page 205
204 EGL Programmer’s Guide
Editing or deleting an SQL database connection
Prerequisites
v An existing database connection
Alternately, you can edit an existing connection from the EGL preferences:
1. Click Window → Preferences.
2. Expand EGL and click SQL Database Connections.
3. Select the connection from the Connection list.
4. Click Edit.
5. Change information in the connection as appropriate.
6. When you are finished editing the connection, click Finish and then click OK
to close the Preferences window.
Note: You cannot retrieve an SQL view that is defined with the DB2 condition
WITH CHECK OPTIONS.
After you create record fields, you may want to gain a productivity benefit by
creating the equivalent DataItem parts for the fields in the record:
1. Open the record in the EGL editor and then open the Outline view. The Outline
view shows a hierarchical view of the parts and other EGL code on the page.
2. In the Outline view, right-click the field and then click Create DataItem Part.
EGL creates a dataItem part based on the field in the record and uses that
dataItem as the field type.
If character data is read from an SQL table column into a shorter host variable,
content is truncated on the right. To test for truncation, use the reserved word
trunc in an EGL if statement.
Default mapping
EGL uses a default mapping when it creates records with the Retrieve SQL feature.
The following table shows the default mapping.
Table 34. EGL variable characteristics
SQL data type EGL variable characteristics
Primitive type Digits/characters Number of bytes
BIGINT BIGINT n/a 8
BIT SMALLINT n/a 2
BLOB BLOB n/a n/a
BOOLEAN BOOLEAN n/a 1
CHAR CHAR 1–32767 1–32767
CLOB CLOB n/a n/a
DATE DATE n/a 8
DECIMAL DECIMAL 1-18 1–10
DOUBLE FLOAT n/a 8
FLOAT FLOAT n/a 8
GRAPHIC DBCHAR 1–16383 2–32766
INTEGER INT n/a 4
LONG VARBINARY HEX 65534 32767
LONG VARCHAR CHAR >4000 >4000
LONG VARGRAPHIC DBCHAR >2000 >4000
NUMERIC DECIMAL 1-18 1–10
REAL SMALLFLOAT n/a 4
SMALLINT SMALLINT n/a 2
TIME TIME n/a 6
TIMESTAMP TIMESTAMP n/a 14
VARBINARY HEX 2–65534 1–32767
VARCHAR CHAR ≤4000 ≤4000
VARGRAPHIC DBCHAR ≤2000 ≤4000
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.
For each table that you select, the EGL Data Access Application wizard creates the
following parts. You can choose to put these parts into a new project or into one or
more existing projects.
v Data parts based on the table:
– An SQLRecord part that represents the table
– DataItem parts that represents the columns in the table
v Data access functions that perform operations on the database, such as adding,
retrieving, and deleting records. You can choose to put these data access
functions in libraries or in services.
Also, you have the option of creating a Web interface for the data access
application. If you choose to create a Web interface, the wizard creates these
additional files and parts:
Before you begin creating the application, make two decisions about where the
new files and parts will go:
v You can put all the new files and parts into one project, or you can put the files
and parts into different projects, based on the kind of file and part. Data parts,
logic parts, and JSF handler parts (with the associated Web pages) can all go into
separate projects.
v You can put files and parts into a new project or into an existing project. If you
choose to put parts into different projects, some can go into an existing project
and others can go into a new project.
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
Prerequisites
v An EGL project and program or other logic part
v An SQL database with a stored procedure
The execute keyword is appropriate for calling stored procedures that do not
return a result set. You can also use execute to call stored procedures that return
one or more result sets, but in that case any result sets are ignored.
To call a stored procedure with execute, use the #sql directive and specify the
name of the stored procedure in the explicit SQL:
execute #sql{
CALL MYSTOREDPROCEDURE
};
If the stored procedure accepts parameters, pass EGL variables as host variables
(see “Host variables” on page 211):
myParameter int = 5;
execute #sql{
CALL MYSTOREDPROCEDURE(:myParameter)
};
The following example uses a prepared statement in combination with the execute
statement:
prepare p1 from "CALL MYSTOREDPROCEDURE(?)";
execute p1 using myParameter;
You can use the open keyword to call only stored procedures that return exactly
one result set. To call a stored procedure that does not return a result set or that
returns more than one result set, use execute.
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;
When you work with an Oracle database, you can call either a stored procedure or
a stored function.
There are specific rules that apply to using the open statement to call a stored
procedure when you use an Oracle database:
v The procedure must have at least one parameter.
v The first parameter must be have an out or inOut modifier, and must be a REF
CURSOR type (an example of how to define this type is shown later). A variable
based on this type, called a cursor variable, can pass result sets between the
parts of a program.
v The SQL code that the open statement runs should represent the first parameter
of the procedure with a question mark.
v If the procedure call is in a prepared statement, do not include anything in the
using clause for the first parameter. If there are no other parameters, omit the
using clause.
In the first example, using the #sql directive, the procedure has no parameters
except the cursor variable:
open rs1 with #sql { call p1( ? ) };
In the next example, also using #sql, the procedure has two parameters in addition
to the cursor variable:
x int = 10;
y int = 1000;
open rs2 with #sql { call p2( ?, x, y ) };
In the next example, using a prepared statement, the procedure has no parameters
except the cursor variable:
prepare pstmt3 from "call p1( ? )";
open rs3 with pstmt3;
The following example shows one way to define a REF CURSOR type to Oracle.
(For other ways, refer to your Oracle documentation.)
execute #sql{ CREATE OR REPLACE PACKAGE MYPKG
AS
TYPE RC12 IS REF CURSOR;
END; };
The preceding code creates a new type named MYPKG.RC12 that you can use for
the type of a parameter that holds the results of a query. The following EGL code
defines a stored procedure that you can call using an EGL open statement:
execute #sql{ CREATE PROCEDURE ZPQPRM2( c IN OUT MYPKG.RC12, x IN CHAR )
AS
BEGIN
OPEN c FOR SELECT firstnme, empno FROM empx WHERE empno > x ORDER BY empno;
END; };
In addition, you can create stored functions in Oracle. A stored function is the
same as a stored procedure, except that it returns a value (Oracle’s stored
procedures cannot return a value). You can call an Oracle stored function from
EGL, using a slightly different SQL syntax than in the stored procedure call.
In this first example, the called function is passed a string and returns an integer:
x int;
y string = "hello";
execute #sql{ call :x := func1( :y ) };
writeStdout( "The function returned " :: x );
This next example calls the same function using a prepared statement:
prepare q from "call ? := func1( ? )";
execute q using x, y;
writeStdout( "The function returned " :: x );
EGL can call Oracle stored functions that return the results of a query. The
following rules apply:
v Call the function with an EGL open statement.
v The function must return a REF CURSOR type.
v The SQL code that the open statement runs must include a question mark to
represent the value that the function returns.
v If the function call is in a prepared statement, do not include anything in the
using clause for the first question mark. If the function has no parameters, omit
the using clause.
In the first example, using the #sql directive, the function has no parameters except
the cursor variable:
open rs5 with #sql { call ? := f5() };
In the next example, also using #sql, the function has two parameters in addition
to the cursor variable:
x int = 10;
y int = 1000;
open rs6 with #sql { call ? := f6( :x, :y ) };
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
Using prepared statements instead of explicit SQL code can improve performance
for data access operations that you use repeatedly. When you create a prepared
statement, the database performs much of the processing necessary for the
statement ahead of time. Then, the database has to perform less processing when
you execute the prepared statement. Whether you use a prepared statement or
explicit SQL depends on how many times you use the data access operation.
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.
To prepare the statement, first create a string variable to hold the statement. Like
any string, you can assign a value to the variable directly or assemble the value
from multiple strings or variables:
myString string = "SELECT ";
myString += "CUSTOMER_ID, LAST_NAME ";
myString += "FROM MYSCHEMA.MYTABLE";
Then, use prepare to create the prepared statement from the variable, assigning the
statement to a new identifier:
prepare myStatement from myString;
Also, you can add a for clause to specify the SQLRecord to use with the prepared
statement:
myCustomer myCustomers;
prepare myStatement2 from myString for myCustomer;
Finally, execute the statement and put the results into a variable:
myCustomerArray myCustomers[];
get myCustomerArray with myStatement2;
Prepared statements are especially useful when you want to insert variables into
the statement. Variables in prepared statements are even more powerful than host
variables in normal explicit SQL code, because you can do more than just insert an
EGL variable value; you can change which variable the dynamic statement uses.
When creating a prepared statement, you use a question mark (?) to represent
variables. The question mark acts as a placeholder into which you can insert a
value later with the using clause:
myCustomerID int = 5;
myCustomerArray myCustomers[];
myHostVarString string = "SELECT CUSTOMER_ID, LAST_NAME";
myHostVarString += " FROM MYSCHEMA.MYTABLE";
myHostVarString += " WHERE CUSTOMER_ID = ?";
prepare myStatement from myHostVarString;
get myCustomerArray with myHostVarString using myCustomerID;
In this case, you can change the using myCustomerID clause to use different
variables in different situations.
EGL also provides a tool that creates a prepare statement and the related execute,
get, or open statement.
1. Within a function in your logic part, right-click a blank line and then click Add
SQL Prepare Statement. The Add SQL Prepare Statement window opens.
2. In the Prepared statement identifier field, type a name to identify the EGL
prepare statement. For rules, see ″Naming conventions″ in the EGL Language
Reference.
3. In the SQL record variable name field, select a record variable from the list or
type a name for a new variable and then select an SQL record part using the
Browse button. You must eventually define an SQL record variable with that
name in the EGL source code.
4. In the Execution statement type field, select execute,get, or open.
5. If you selected open in the Execution statement type field, type an identifier
for the result set in the Result set identifier field.
6. Click OK. EGL creates the prepare statement and related data access statement.
Related concepts
“Working with SQL statements” on page 211
With EGL you can deal with explicit SQL code in your EGL program.
Related tasks
“Calling a stored procedure” on page 212
You can call an SQL stored procedure with the open or execute statements and
the #sql directive.
Related reference
SQL data access
open
open considerations for SQL
execute considerations for SQL
SQLRecord stereotype
prepare considerations for SQL
#sql directive
Host variables
Host variables allow SQL statements to use EGL variables.
Naming conventions
EGL can also display a default SELECT statement based on an SQL Record
definition.
The default SELECT statement: Right-click within the first line of an SQL Record
definition and select SQL Record. A second menu offers you the following choices:
Retrieve SQL
If you are in the process of defining the record, this option asks EGL to
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]}
end
The following options are available from the SQL Statement menu:
Add This option converts implicit SQL code to embedded SQL code and adds it
to your program. The Add option converts the simple I/O statement get
myCustomer to the following:
get myCustomer with #sql{
select
C_NUMBER, C_NAME, C_ADDR1, C_ADDR2, C_ADDR3, C_BALANCE
from ADMINISTRATOR.CUSTOMER L1
where
C_NUMBER = :myCustomer.customerNumber
};
Add with Into
This option functions the same as Add, but includes an EGL into clause for
the field names in the EGL record variable. This is useful if you want to
update only some of the fields; you can remove the field names you do not
want to update from the into and select clauses:
get myCustomer
into myCustomer.customerNumber, myCustomer.customerName,
myCustomer.customerAddr1, myCustomer.customerAddr2,
myCustomer.customerAddr3, myCustomer.customerBalance with
#sql{
select
C_NUMBER, C_NAME, C_ADDR1, C_ADDR2, C_ADDR3, C_BALANCE
To create a new connection using the New Connection wizard, see “Creating an
SQL database connection” on page 197, or use the following steps to set up or edit
the connections:
1. Click Window → Preferences.
2. When a list of preferences is displayed, expand EGL, then click SQL Database
Connections.
3. The currently selected connection in the Connection list is the default database
for EGL in the workbench. You can switch between database connections, edit
or delete the connections, and test the connections from this window.
4. To create a new connection, click New. For an explanation of the preference
fields, see “Fields in the New Connection wizard” on page 198.
5. If you are using DB2 you might need to set the Secondary Authentication ID
field. See ″Secondary Authentication ID″ in this topic.
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.
The following terms and concepts are essential in developing a DL/I database
program:
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
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
Database layout
The following database is named CUSTOMER:
CUSTOMER
NAME/
ADDRESS
(STSCCST)
CUSTOMER
ORDER
(STPCORD)
ITEM
(STLCITM)
IMS PSB
In the following PSB definition on the host, the DBDNAME is set to CUSTOMER,
the name of the database. A PCB is defined with the name STDCDBL; the
customerPCB in the next section sets the pcbName property to this name.
TITLE 'PSB FOR PROCESSING SAMPLE DATA BASES'
ELAALT PCB TYPE=TP,MODIFY=YES
ELAEXP PCB TYPE=TP,MODIFY=YES,EXPRESS=YES
STDCDBL PCB TYPE=DB,DBDNAME=CUSTOMER,PROCOPT=AP,KEYLEN=50,POS=S
SENSEG NAME=STSCCST,PARENT=0
SENSEG NAME=STSCLOC,PARENT=STSCCST
SENSEG NAME=STPCORD,PARENT=STSCLOC
SENSEG NAME=STLCITM,PARENT=STPCORD
SENSEG NAME=STSCSTA,PARENT=STSCCST
SENSEG NAME=STSCHIS,PARENT=STSCCST
PSBGEN LANG=ASSEM,CMPAT=YES,PSBNAME=STBICLG
END
EGL PSBRecord
The following code represents the IMS PSB in the EGL program:
//define overall db layout in PSB
Record CustomerPSBRecordPart type PSBRecord { defaultPSBName="STBICLG" }
// three PCBs required for CBLTDLI on IMS
iopcb IO_PCBRecord { @PCB { pcbType = PCBKind.TP } };
elaalt ALT_PCBRecord { @PCB { pcbType = PCBKind.TP } };
elaexp ALT_PCBRecord { @PCB { pcbType = PCBKind.TP } };
// database PCB
customerPCB DB_PCBRecord { @PCB {
pcbType = DB,
pcbName = "STDCDBL",
hierarchy = [
@relationship { segmentRecord = "CustomerRecordPart" },
@relationship {
segmentRecord = "LocationRecordPart", parentRecord = "CustomerRecordPart" },
@relationship {
segmentRecord = "OrderRecordPart", parentRecord = "LocationRecordPart" },
@relationship {
segmentRecord = "ItemRecordPart", parentRecord = "OrderRecordPart" },
@relationship {
segmentRecord = "CreditRecordPart", parentRecord = "CustomerRecordPart" },
@relationship {
segmentRecord = "HistoryRecordPart", parentRecord = "CustomerRecordPart" }]}};
end
function main()
...
end
end
Related concepts:
“Working with DL/I data” on page 221
Related reference:
DL/I database support
EGL supports DL/I (Data Language/I), a hierarchical data base manager for
COBOL environments.
DL/I examples
These DL/I examples use the same example DL/I database as described in
Example DL/I database. Following are some examples of typical techniques for DL/I
database I/O:
v “Searching within a parent segment”
v “Searching with another non-key field”
v “Searching based on information in another record” on page 228
v “Searching for a non-root segment” on page 229
v “Searching with a secondary index” on page 230
v “Using path calls to access multiple segments” on page 232
v “Reading all segments with a single I/O statement” on page 232
v “Using dynamic arrays” on page 233
Consider the situation in which you want to retrieve the items for a particular
order. You can use the following to retrieve the order:
get myOrder with #dli {
GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
STSOCORD (STQCODN = :myOrder.orderDateno) };
Then you can use the following to retrieve the line segments within the order:
get next inParent myItem;
while (myItem not noRecordFound)
// process the current item
get next inParent myItem;
end
EGL creates the following pseudo-DL/I code for the get next inParent statement:
GNP STLCITM
Program myProgram
(customerParm CustomerData)
{ @DLI{ psb = "myCustomerPSB" }}
//declare variables
myCustomerPSB CustomerPSBRecordPart;
myCustomer CustomerRecordPart;
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) } ;
Consider the situation where the customer segment STSCCST is the parent of the
location segment STSCLOC and you want to retrieve only the data for the location
segment. You have defined the following record variables in your program:
myCustomer CustomerRecordPart;
myLocation LocationRecordPart;
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.
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:
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.
Consider the situation in which you have defined record variables and a dynamic
array as follows:
myCustomer CustomerRecordPart;
myLocation LocationRecordPart;
myOrder OrderRecordPart;
myOrderArray OrderRecordPart [] {maxsize = 20}; // array of orders
You can use a get statement to fill the array the first time and a get next statement
to retrieve a second group of 20 orders as follows:
myCustomer.customerNo = "123456";
myLocation.locationNo = "ABCDEF";
myOrderDateNo = "20050730A003";
get myOrderArray; // fill the array the first time
... do some processing
get next myOrderArray; // get the next batch of 20 orders
EGL creates the following pseudo-DL/I code for the get statement:
get myOrderArray with #dli{
GU STSCCST (STQCCNO = :CustomerRecordPart.customerNo)
STSCLOC (STQCLNO = :LocationRecordPart.locationNo)
STPCORD (STQCODN = :OrderRecordPart.orderDateNo)
GN STPCORD };
EGL creates the following pseudo-DLI code for the get next statement:
get next myOrderArray with #dli{
GN STPCORD };
Filling the dynamic array for the first batch of 20 orders with a get statement
requires an initial GU call followed by a loop of GN calls until the array is full or
DL/I runs out of segment occurrences. In the pseudo-DL/I code that EGL creates,
the GU call retrieves the first order segment. EGL treats the GN call as a loop and
provides the logic to loop until the array is full or DL/I runs out of segment
occurrences. Similarly, EGL treats the get next statement as a loop and provides the
loop control logic for you.
The get next statement provides the correct pseudo-DL/I code to retrieve the
second batch of orders. However, the pseudo-DL/I code for the get statement is
to the following:
Record STSCCST type DLISegment
{ segmentName="STSCCST", keyItem="customerNo" }
10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field
...
end
Make similar changes for the location segment (STSCLOC) and the order
segment (STPCORD). Then change your PSB record to use the new names as
follows:
Record CustomerPSBRecordPart type PSBRecord { defaultPSBName="STBICLG" }
// database PCB
customerPCB DB_PCBRecord { @PCB { pcbType = DB, pcbName = "STDCDBL",
hierarchy = [ @relationship { segmentRecord = "STSCCST" },
@relationship {segmentRecord="STSCLOC",
parentRecord="STSCCST"},
@relationship {segmentRecord="STPCORD",
parentRecord="STSCLOC"}
]}};
end
Change the declaration of your record variables and myOrderArray so that they
reference the new DL/I segment record parts as follows:
STSCCST CustomerRecordPart;
STSCLOC LocationRecordPart;
STPCORD OrderRecordPart;
myOrderArray STPCORD [] {maxsize = 20}; // array of orders
Now when you issue the following get statement:
get myOrderArray; // fill the array the first time
EGL creates the following pseudo-DL/I code for the get statement and the host
variable qualifiers use the correct record variable names:
get myOrderArray with #dli{
GU STSCCST (STQCCNO = :STSCCST.customerNo)
STSCLOC (STQCLNO = :STSCLOC.locationNo)
STPCORD (STQCODN = :STPCORD.orderDateNo)
GN STPCORD };
Because EGL creates the default SSAs from the PCB hierarchy information, this
is an easy way of ensuring that the variable names EGL uses match your
program’s record variable declarations. The disadvantage is that this technique
does not follow the general practice of using different names for parts and
variables.
v Use the #dli directive and explicit DL/I database I/O as follows:
An MQI message is a string of data sent from one program to another. An MQI
message consists of program information and routing information used by the
message queue manager (control information). The structure and content of the
program information is determined by the communicating programs, not by the
queue manager.
Programs that use message queueing techniques have the following features:
v There is no physical connection between programs.
v Communication network access functions are built into the queue managers, not
into the programs.
v Communicating programs can run in parallel.
v Communicating programs do not need to be running concurrently.
v Intermittent communication link failures do not prevent messages from being
delivered.
v Work is carried out by small, self-contained programs.
v Communication can be driven by events.
v Messages can be assigned priorities.
v Messages can be recoverable resources, committed or rolled back along with
database or file updates.
v Workloads can be balanced by starting multiple servers for processing a single
queue.
v Availability can be increased by assigning multiple alternative processors to
service a queue.
New code should use EGL keywords to communicate with message queues.
EGL uses resource associations to determine the queue to which the record is
assigned. For more information, see “Defining resource associations for message
queues” on page 237.
To define a resource associations part for message queues, perform the following
steps:
1. Open an EGL build file by right-clicking the file name in the Project Explorer
and selecting Open With → EGL Build Parts Editor.
2. Create a resource association part by right-clicking the build file in the Outline
view and selecting Add Part.... Select Resource Association from the wizard
dialog and click Next.
3. Specify a name for the Resource Association part and an optional free-form
description. Click Finish.
4. EGL displays the Resource Association part. Click Add Association to add a
new element. Specify a file name (fileName property) to identify the element.
The entry will apply to any message queue record whose fileName property
matches the name you enter here.
5. Enter a file type (fileType property) of MQ for the element.
6. Specify the platform on which the message queue is located (system property).
7. If you want to specify different properties for different systems, click Add
System and specify additional systems.
8. For each file name and system on the left side of the editor, you can specify
properties on the right side. The system and file type carry over from the left
side. Specify the system resource name (systemName property) in the
following form:
[queueManagerName:]queueName
The first time you use an EGL statement with an MQ record during a program,
EGL checks to see if there is an active connection to a queue manager. If not, it
creates one.
After you have read from or written to a message queue you may need to commit
or roll back your changes.
EGL automatically connects to the queue manager on the first add or get next
statement in a program, using the queue manager name specified in the system
resource name associated with the message queue record. If the queue manager
name is not specified, the queue manager is the default queue manager defined for
your system. EGL automatically disconnects from the queue manager when the
program ends, closing any open files and committing the current unit of work if it
is still open.
EGL provides sample functions named MQCONN and MQDISC that call the
MQCONN and MQDISC routines from the MQ API. Use these functions in the
following circumstances:
v If the connection queue manager and the queue manager to which the queue
belongs are different, use an MQCONN function call to connect before issuing
the add or get next statement in the program. Otherwise the add or the get next
statement will use the current open connection instead of attempting to connect
to the queue manager specified in the system resource name.
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.
You must use a local definition of the remote queue on the currently connected
queue manager if both of the following circumstances are true:
v You are writing messages to a queue on another Queue Manager using the add
statement.
v You previously wrote a message to a queue using the add statement.
You must use the close statement after an add statement to close the connection to
the queue in any of the following circumstances:
v Before using the get next statement.
v To release the queue for access by another program.
v To release the queue if you have a long running program and have completed
work with the queue.
You must use a local definition of the remote queue on the currently connected
queue manager if both of the following circumstances are true:
v You are reading messages from a queue on another Queue Manager using the
get next statement.
v You previously read a message from a queue using the get next statement.
The methods used for commits and rollbacks depend on your environment. The
following environments handle commits and rollbacks independently of MQ:
v AS/400®
v CICS for MVS/ESA™
v CICS for VSE/ESA™
v IMS
The MQ API (also known as the MQ Interface, or MQI) accesses the message
queue manager directly. Because of the complexity of the interface, the ease of
making mistakes, and the lack of flexibility, the MQI should only be used to
maintain existing code. New code should use the EGL add and get next statements
to access message queue information.
To use direct MQ API calls, you must enable an EGL Project Feature:
1. Right-click the project name in the Project Explorer view.
2. Select Properties.
3. Click EGL Project Features in the left side of the Properties dialog.
4. Check the box next to EGL with low-level MQ API support.
5. Click OK.
MQ reusable parts
EGL provides a set of reusable parts, which are parameters, records, and functions
that you can use or modify to make direct calls to the MQ API. The source files for
these parts are located in the SDP70Shared\plugins\
com.ibm.etools.egl.resources_version\MqReusableParts directory.
MQI parameters are either data items or records. The MQSTATE and
MQATTRIBUTES sample records contain declarations for most data item
parameters.
The BUFFER parameter (message buffer parameter used with MQGET, MQPUT,
and MQPUT1 calls) and the CHARATTRS (character attributes buffer parameter
used with MQINQ and MQSET calls) are both defined with a length of 1024
characters. Increase the length of these items if you reuse MQSTATE in a program
that requires larger buffers.
Sample records are provided to define the format of record parameters and special
purpose messages and message headers. Record names are the same as the
COBOL structure names. The data items in the records have the same names as the
corresponding fields in the COBOL structures, except that the COBOL names use a
hyphen (-) as a token separator instead of an underscore.
The following table shows the names of the sample records for direct MQ calls.
Table 36. Sample records for MQ calls
Record Description Initializer function
MQBO Begin options MQBO_INIT
MQCNO Connect options MQCNO_INIT
MQDH Distribution header MQDH_INIT
MQDLH Dead-letter header MQDLH_INIT
MQGMO Get-message options parameter MQGMO_INIT
MQINTATTRS Integer attributes parameter MQINTATTRS_INIT
MQMD Message descriptor parameter MQMD_INIT
The following table shows the sample EGL functions that call MQ API functions.
Table 37. EGL functions that call MQ API functions
Function Description
MQCONN Connect to message queue manager
MQCONNX Extended connect
MQDISC Disconnect from message queue manager
MQOPEN Open a message queue
MQCLOSE Close a message queue
MQGET Read a message from a queue
MQPUT Write a message to a queue
MQPUT1 Write a single message to a queue including queue open and close
MQINQ Inquire about queue attributes
MQSET Set queue attributes
MQBEGIN Begin a logical unit of work
MQCMIT Commit a logical unit of work
MQBACK Back out a logical unit of work
Related concepts
“Working with MQ message queues” on page 235
Message queueing provides an alternative to calling a remote program. With
message queueing, programs communicate by writing to and reading messages
from queues.
Related tasks
“Reading from and writing to message queues” on page 238
Write to message queues with the EGL add statement; read with get next.
Generated Java programs require a special format for the linkage options entry.
The entry should look like the following example:
:calllink applname=elaq* library=mqWrapperDllNname linktype=csocall
parmform=commptr remotecomtype=direct remoteapptype=nonvg
contable=javaConversionTableName
mqWrapperDllNname
The wrapper dll name for your run-time environment from the table.
javaConversionTableName
The java conversion table for your language and the system on which the
program is running.
Refer to the EGL Generation Guide for help in determining which conversion table
to choose.
Related concepts
The iSeries operating system has its own API to handle program-to-program
communication. The communication can take place through one of two objects:
v A data area is a fixed-size object that any job running on the system can read
from or write to. Think of it as a virtual whiteboard. You can set it up to contain
one of the following kinds of data:
– A character string of up to 2000 bytes
– A decimal number
– A Boolean value (TRUE or FALSE)
v A data queue is a variable-length object that can hold any number of messages
from any number of jobs. Data queues are similar to MQ message queues.
A data area has lower overhead than a data queue, so your choice of which object
to use generally depends on the complexity of your task. You might use a data
area, for example, to hold a flag that lets one program tell another to perform
garbage collection. A data queue scenario is typically more complex, as in the
following example:
v One application listens for a specific type of request. For each request, it creates
a record and adds that new record to the queue.
v Other applications listen for new records created by the first application. One
uses the record to update a database. Another uses the same record to generate
an invoice.
For details of these Record parts and function calls, see the EGL Language Reference.
Related tasks
These differences in the ordering scheme, text orientation, and other bidirectional
format characteristics require the program to convert bidirectional text strings from
one format to another:
v To control the format of bidirectional text strings in FormGroup fields, use a
bidirectional runtime file.
v To control the format of bidirectional text strings between a server and client,
use a bidirectional conversion table.
The bidiRuntime build descriptor option specifies a bidirectional runtime file. This
file, in XML format, contains a set of options that control the bidirectional behavior
for the fields in the form groups associated with an application. Several of these
options correspond to existing bidi properties:
v bidiInput
v orientation
v numericSwapping
v symmetricSwapping
Before the bidirectional runtime file was added to EGL (prior to version 7.5),
individual properties controlled this behavior. Those properties are still part of
EGL. If your code associates these individual properties with a FormGroup,
changing the runtime file will cause EGL to change the values of the individual
properties accordingly. If you change the individual properties, EGL will use the
new values to update the runtime file.
For information on how to set up the bidirectional runtime file, see “Creating a
bidirectional runtime file” on page 247.
In all cases, the bidi conversion table reference is specified as the 1- to 4-character
file name with the .bct extension. For example, if you have created a bidi
conversion table named hct1.bct, you can set the value of formConversionTable
in a program by adding the following statement at the beginning of the program:
sysVar.formConversionTable = "hct1.bct" ;
– 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.
Note: The default value here is the opposite of the default value of the
symmetricSwapping property.
Numeric Swapping
Equivalent to the numericSwapping property (see numericSwapping).
Select one of the following values:
Yes (default)
If you want to enable numeric swapping.
No If numeric characters are already swapped.
Note: The default value here is the opposite of the default value of the
numericSwapping property.
9. Click Finish. The table is displayed for editing. Save and close the window
when you have finished.
Related concepts
“Working with bidirectional data” on page 245
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.
8 bytes
Figure 1. Format of the form area passed using the call statement
On CICS, the address points to the user interface block (UIB). The UIB is 6 bytes
long. The first 4 bytes contain the address of the PCB address list for the PSB. The
last 2 bytes contain status information (for example, an indication of whether the
PSB contains status information).
On non-CICS systems, the address points to a simulated UIB. The simulated UIB is
6 bytes long. The first 4 bytes contain the address of the PCB address list for the
PSB. The last 2 bytes must contain binary zeros. The PCB address list must be the
list pointed to by register 1 when the IMS or the DL/I region controller invoked
the first program in the DL/I run unit.
PCB Number 1
Status information
PCB Number 2
.
.
.
High order byte PCB Number n
must have
bit 0 = 1
Figure 2. Format of dliLib.psbData
Format of a PCBRecord
There are special considerations for the dliLib.psbData structure and PCB record
parameters. If you pass the dliLib.psbData structure as a parameter, it is
implemented as a 12-byte field consisting of an 8-byte PSB name followed by a
4-byte address. The address points to the CICS user interface block (UIB).
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
For a localCall, you can also specify the linkType property that determines the
actual call statement as follows:
DYNAMIC
Standard dynamic COBOL call.
STATIC
Standard static COBOL call. The called program must be link edited with the
calling program.
CICSLINK
CICS LINK command (default for CICS programs). CICSLINK is only
supported in the following situations:
v The callLink element for the called program specifies a remoteCall.
v The callLink element for the called program specifies parmForm =
CHANNEL.
v The call statement specifies isExternal = YES or the callLink element for the
called program specifies pgmType = EXTERNALLYDEFINED.
In all other cases, including where CICSLINK is the default, EGL does not
generate a CICS LINK command for linkType = CICSLINK. Instead EGL
generates a standard dynamic COBOL call, the same call as if you specified
linkType = DYNAMIC for the callLink element for the called program.
You must create a CICS RDO PROGRAM entry for any called program that is
called with the following linkage options:
You can also specify how the parameters on the call statement are to be passed to
the called program:
COMMPTR
Pointers to the parameters are passed in the COMMAREA (default for CICS
programs if the property type is localCall).
COMMDATA
Parameter data is passed in the COMMAREA (default for CICS programs if the
property type is remoteCall).
OSLINK
Parameters are passed using a standard COBOL parameter list. The called
program cannot contain any CICS statements or be an EGL program.
CICSOSLINK
A standard COBOL parameter list is used. The first two parameters are the
EXEC interface block (EIB) and COMMAREA followed by the call statement
parameters.
CHANNEL
Parameters are passed in containers in a channel. The containers are named
EGL-PARM-1 through EGL-PARM-n, where the maximum value of n is 30. No
COMMAREA is passed in the CHANNEL parameter format.
Table 41. Valid parameter format and linkage combinations for CICS
COMMPTR COMMDATA OSLINK CICSOSLINK CHANNEL
DYNAMICValid Valid Valid Valid No
STATIC Valid Valid Valid Valid No
CICSLINK Valid Valid No No Valid
REMOTE Valid if calling from an Valid No No Valid
EGL-generated Java
program; Not valid if
calling from a CICS
program.
All calls described here are local calls between programs running on the same
CICS system. Called programs can also run on a different system than the calling
program as follows:
v If both programs run in CICS, set the type property to remoteCall and the
linkType property to COMMDATA. The call statement is generated as a CICS
LINK command with data passed in the COMMAREA control block
(COMMDATA).
v If the calling program is a generated Java program and the called program runs
on CICS, set the type property to remoteCall and the linkType property to
either COMMPTR or COMMDATA depending on how the called program
expects to receive its parameters.
If either the calling or called program is a PL/I program, you must set the
linkType property to CICSLINK. In addition, if the called program is a PL/I
The following sections give the specifics for using parameters with the call
statement.
The figure below illustrates the COMMPTR parameter format. Register 1 points to
a list of pointers. The first is the address of the EXEC interface block (EIB),
followed by the address of the COMMAREA. Pointers to the parameters are
passed in the COMMAREA.
Register 1
Address of EIB
Address of COMMAREA
High Order
. Parameter
Byte, . pointers
When you set the endCommarea build descriptor option to YES for the calling
program, the calling program adds the x’FFFFFFFF’ fullword at the end of the
parameter list. You should set endCommarea to YES only when the called program
requires this terminal fullword, as in a program that was previously called from a
CSP/AE (Cross System Product/Application Execution) program. The length of the
The figure below illustrates the COMMDATA parameter format. Register 1 points
to a list of pointers. The first is the address of the EIB, followed by the address of
the COMMAREA. Actual parameter data is passed in the COMMAREA.
Address of COMMAREA
Parameter Data
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).
.
. 1 to 30 parameter
. pointers
High Order Byte,
Bit 0 = 1
4 Byte Parm Pointer
The figure below illustrates the CICSOSLINK parameter format. Register 1 points
to a list of pointers. The first is the address of the EIB, followed by the address of
the COMMAREA, followed by the addresses of buffers of parameter data (one for
each parameter).
Address of COMMAREA
The user program name must be defined to CICS and the program must exist in
the operating system load library, or a NOT FOUND condition results. The
program must also be link-edited according to CICS command level programming
rules. Refer to the CICS application programmer’s reference for more details.
Refer to the application programming guide for your CICS environment for more
information on using COBOL calls in a CICS environment.
The format of variables in the parameter list must match the definition specified
for the parameters received by the called program. If they are not the same the
results are not predictable.
The following example shows the format of CICS LINK for a program call to a
program generated with the COMMPTR parameter format:
EXEC CICS LINK
PROGRAM('MYAPPL') COMMAREA(record of pointers)
LENGTH(length of COMMAREA)
If the linkType is DYNAMIC or STATIC, at exit the called EGL program sets the
COBOL special register RETURN-CODE to the value of the EGL variable
sysVar.returnCode. This return code, which is stored in register 15, can be tested
by the calling non-EGL programs.
Related concepts
“Transfer of control across programs” on page 251
Related tasks
“Transferring control in CICS environments”
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.
The originating program must be defined as a main program, and the target
program name is the only required parameter. That parameter must point to a
valid EGL program name.
EXEC CICS XCTL ('applnam') COMMAREA(record)
LENGTH (length of record)
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.
The following example shows the format of the START command that EGL
generates if a record is specified in the transfer to transaction statement:
EXEC CICS START TRANSID('transid') FROM(record)
LENGTH(length of record)
TERMID(current-terminal)
EGL always includes the TERMID option of the CICS START command if the
transfer to transaction is issued from a main text UI program. The transaction is
not invoked unless the terminal is in TRANSCEIVE status in the CICS TCT.
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.
If the genReturnImmediate build descriptor option is set to YES, then the transfer
to transaction statement is implemented as an EXEC CICS RETURN IMMEDIATE.
The first 10 bytes of the COMMAREA received by the target program is binary
zeros. If a record is specified in the transfer to transaction statement, that record is
found in the COMMAREA starting at the 11th byte.
The example below shows the format of the START command that can be used
when passing a record to the EGL program:
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.
The following example shows the format of the CICS RETURN IMMEDIATE when
you pass a record to the EGL program:
EXEC CICS RETURN TRANSID('transid')
COMMAREA(10 bytes of low-values + record)
LENGTH(10 + length of record)
IMMEDIATE
If you use CICS RETURN IMMEDIATE to transfer to an EGL program, you must
set the genReturnImmediate build descriptor option to YES when generating the
EGL program to be started.
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.
Depending on the value of the termID parameter, EGL issues the CICS START
command with or without an associated device:
v If termID is not specified, EGL associates the current terminal with the target
transaction; specifically, EGL assigns the current terminal identifier to the
TERMID option in the CICS START command.
v If termID is specified and its value is not binary zeros, EGL associates the
specified device (terminal or printer) with the target transaction; specifically,
EGL assigns the value of termID to the TERMID option in the CICS START
command but does not include the RTERMID option. Results are not predictable
if the value in termID is the CICS terminal ID that is associated with the current
transaction. To end the current transaction and start a new transaction at the
current terminal, use the transfer to transaction or show statement rather than
the vgLib.startTransaction() system function.
v If the value of the termID parameter is binary zeros, EGL associates no terminal
with the target transaction; specifically, EGL assigns the value of the prID
parameter to the RTERMID option in the CICS START command but does not
include the TERMID option. In addition, if you set the build descriptor option
printDestination to TERMINALID when you generate the started EGL program,
the prID parameter is the printer ID that is used to initialize the
converseVar.printerAssociation system variable in the target transaction. To set
the termID CHAR field to binary zeros, use an assignment statement containing
a hex literal for 4 bytes of binary zeros, as in the following example:
myCHAR = x"00000000";
v The target transaction must have a CICS TRANSACTION entry.
v If the first program in the started transaction is a non-EGL program, it must
issue a CICS RETRIEVE to get the passed work area and terminal information.
For more information, see “Retrieving data for a started task in a non-EGL
program” on page 267.
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 program can receive the data that was passed by doing the following:
EXEC CICS RETRIEVE INTO (workRecord) LENGTH(length of workRecord)
RTERMID(userRtermid)
The options for the CICS RETRIEVE command have the following meanings when
the non-EGL program is started as a result of vgLib.startTransaction():
v workRecord must be defined to match the data portion of the requestRecord that
you used in the vgLib.startTransaction() system function (from byte 11 through
the end of the requestRecord).
v Be sure to put the length of workRecord into LENGTH.
v If the RTERMID option contains 4 bytes of binary zeros, it should be ignored. If
the RTERMID option is not 4 bytes of binary zeros, it contains the printer (prID
parameter) specified for the vgLib.startTransaction() function.
Related concepts
“Transfer of control across programs” on page 251
Related tasks
“Calling programs in CICS environments” on page 254
.
. 1 to 30 parameter
. pointers
If you need to link your program with other modules (such as a PL/I program, for
example), see Link edit part examples.
Use the linkage options part to specify how you want EGL to generate the call
statement:
v The type must be remoteCall.
v The remoteComType must be CICSEXCI.
v To pass parameters to the called program, set the parmForm property of the
callLink element to COMMDATA.
When processing the call statement, EGL generates the necessary COBOL code to
call via EXCI. For more information on these linkage options, see “Calling
programs in CICS environments” on page 254.
Calling a CICS program from the z/OS batch environment has the following
limitations:
v Client unit of work is not supported.
Example
In the following example, a program named calledExci is called from z/OS batch.
The call uses the following linkage options:
v remoteComType = CICSEXCI (required)
v alias = CALLED
v location = NQA17C03 (required)
v luwControl = SERVER
v parmForm = COMMDATA
v pgmName = calledExci
v remotePgmType = EGL | EXTERNALLYDEFINED (has no effect)
v serverID = ABCD (default is CSMI)
v type = REMOTE
v conversiontable (has no effect)
The next table outlines the different ways of implementing the transfers.
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.
In each case, the EGL transfer-to program starts at its main function.
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.
dliLib.psbData
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.
PCB
020 Simulated UIB 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.
The input record for the EGL program is initialized according to data type if the
EGL program is started with this interface.
Related concepts
“Transfer of control across programs” on page 251
Related reference
“Format of the dliLib.psbData structure” on page 253
Related tasks
“Calling programs in IMS and z/OS batch environments” on page 267
“Transferring control in the IMS/VS environment” on page 275
EGL main Text UI programs that are generated for the IMS/VS target environment
run as IMS message processing programs (MPPs).
The definition and generation options of the target non-EGL program or EGL
program control the type of switch that is possible and the way the data is passed.
Transferring from conversational to nonconversational or from nonconversational
to conversational is not supported for EGL programs.
If the target transaction is an EGL program, the use of the property inputForm
determines which type of message switch is valid:
v If inputForm is not specified, an immediate message switch is required.
v If inputForm is specified, either a deferred program-to-program message switch
(EGL show statement) or an immediate program-to-program message switch
(EGL transfer to transaction statement) can be used. If the immediate switch is
used, the input form (identified in the inputForm property) is automatically
displayed by the target program. However, this is less efficient than a deferred
switch because the target program must be processed twice: once to display the
input form and once to read the data entered by the program user.
If a non-EGL program does a deferred program-to-program message switch to an
EGL program, the non-EGL program should turn on the modified data tag (MDT)
attribute for all fields on the form and should set all other field properties to the
values that were defined during form definition. If the program user requests help
or if edit errors occur, the program displays default data in any fields that did not
have the MDT attribute set and were not modified by the program user. The EGL
program uses the defined properties for all other field properties.
If the target transaction is a non-EGL program that needs form input from the
message queue at the start of processing, the EGL program should use a deferred
Immediate switch between two EGL programs: With this technique, two
segmented conversational EGL programs can change both the transaction name
and the PSB name without presenting a form to the program user. Different
FormGroups can be used by the two programs. The example below shows a
skeleton definition of the two programs.
program ProgramA type textUIProgram
{segmented=yes, inputRecord="basicRecord1",
@DLI { psb="psb" } }
// Declarations
basicRecord1 TRANSFER_RECORD;
psb PSB1A;
// FormGroup
use FORMGX;
function main()
...
sysVar.transferName = 'trx1b';
transfer to transaction sysVar.transferName passing basicRecord1;
...
end // end main
end // end ProgramA
// Declarations
basicRecord1 TRANSFER_RECORD;
psb PSB1B;
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.
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.
Deferred switch between two EGL programs: With this technique, two
segmented conversational EGL programs can change both the transaction name
and the PSB name when a form is presented to the program user. You must use
the same formGroup for both programs. You do not have to transfer a record, but
a form is required. The example below shows a skeleton definition of the two
programs.
program ProgramA type textUIProgram
{segmented=yes, inputRecord="basicRecord2",
@DLI { psb="psb" } }
// Declarations
basicRecord2 TRANSFER_RECORD;
psb PSB2A;
// FormGroup
use FORMG2;
function main()
...
sysVar.transferName = 'trx2b';
show form2 returning to sysVar.transferName passing basicRecord2;
...
end // end main
end // end ProgramA
// Declarations
basicRecord2 TRANSFER_RECORD;
psb PSB2B;
// FormGroup
use FORMG2;
function main()
// generated EGL logic does the following:
// initializes basicRecord2
// performs edits for map2
// converses map2 until map2 passes all edits
// gives control to the first statement in the main function
...
end // end main
end // end ProgramB
Deferred switch from non-EGL program to EGL program: The non-EGL program
must be an IMS conversational program. The EGL program must be defined
similarly to program B in ″Deferred switch between two EGL programs″ above.
The spaSize build descriptor option must specify the SPA size that is being used
by the non-EGL program.
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.
Immediate switch between two EGL programs: When developing EGL programs,
this technique is the same as transferring with segmented conversational EGL
programs, except that the spaSize build descriptor option is set to 0
(nonconversational). With this technique two nonconversational EGL programs can
change both the transaction name and the PSB name without presenting a form to
the program user. Different form groups can be used by the two programs.
// Declarations
basicRecord1 TRANSFER_RECORD;
psb PSB1A;
// FormGroup
use FORMGX;
function main()
...
sysVar.transferName = 'trx1b';
transfer to transaction sysVar.transferName passing basicRecord1;
...
end // end main
end // end ProgramA
// Declarations
basicRecord1 TRANSFER_RECORD;
psb PSB1B;
// FormGroup
use FORMGY;
function main()
// generated EGL logic does the following:
// initializes basicRecord1
// if inputForm is specified:
// converses form2
// performs edits for form2
// converses form2 until form2 passes all edits
// gives control to the first statement in the main function
...
end // end main
end // end ProgramB
The EGL-generated program control logic automatically handles the IMS message
that is used to transfer control and the record that is passed from program A to B.
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.
The outlines of the two programs are identical to those in the conversational
deferred switch between two EGL programs; the difference is in the value of the
spaSize build descriptor option at generation time:
program ProgramA type textUIProgram
{segmented=yes, inputRecord="basicRecord2",
@DLI { psb="psb" } }
// Declarations
basicRecord2 TRANSFER_RECORD;
psb PSB2A;
// FormGroup
use FORMG2;
function main()
...
sysVar.transferName = 'trx2b';
show form2 returning to sysVar.transferName passing basicRecord2;
...
end // end main
end // end ProgramA
// Declarations
basicRecord2 TRANSFER_RECORD;
psb PSB2B;
// FormGroup
use FORMG2;
function main()
// generated EGL logic does the following:
// initializes basicRecord2
// performs edits for map2
// converses map2 until map2 passes all edits
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.″
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.
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.
The following example shows the COBOL definition for a scratch pad area passed
in either a deferred or an immediate program-to-program message switch for
conversational processing. Keep in mind that PL/I requires a 4-byte length field
rather than the 2-byte length field used for COBOL. Refer to the IMS/VS
documentation for your system for additional information. The specific field names
are used for illustrative purposes only; the actual field names might vary in the
generated code.
* SPA IO area.
01 SPA.
05 SPA-LENGTH PIC S9(4) COMP.
05 SPA-ID PIC S9(9) COMP.
05 IMS-TRAN-NAME PIC X(8).
05 CSP-OPTIONAL-SSM-BYTE PIC X(1). See Note 1.
05 CSP-APPL-WS-DATA.
10 data-item-1 PIC ........................
10 data-item-2 PIC ........................
.
.
.
05 CSP-OPTIONAL-SSM-BYTE PIC X(1). See Note 2.
The data identified as ″Program data″ in the table above is treated as the input
record for the target program. This technique enables a non-EGL program to store
data in the SPA and switch to an EGL program (or a series of EGL programs) that
use or modify the SPA data. The EGL program can eventually switch back to a
non-EGL program with information from the EGL program contained in the SPA.
Follow the IMS restrictions regarding changes in the SPA size.
SPA size and transfer record size: The following table defines how the SPA, the
record specified on the transfer to transaction or show statement, and the input
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.
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.
When you use the show statement in an IMS nonconversational program, the
optional record is passed via the work database for a deferred program-to-program
message switch. The following table shows the record layout:
01 CSP-APPL-WS-RECORD.
05 CSP-APPL-WS-DATA.
10 data-item-1 PIC ........................
10 data-item-2 PIC ........................
Related concepts
“Transfer of control across programs” on page 251
Related tasks
“Transferring control in the IMS/VS environment” on page 275
“Transferring to and from IMSADF II programs” on page 293
Related reference
“Reference information for IMS/VS transfers” on page 286
The following sections provide reference information for call and transfer
statements in the IMS/VS environment or when DL/I databases are being used.
The two service routines that non-EGL programs can use to interface to the work
database are:
v ELATSGET to retrieve data from the work database.
v ELATSPUT to store data into the work database.
In the previous example, modname is an 8-byte character field, and parm1 through
parm6 are as follows:
v Record buffer
v Length of buffer (fullword binary)
v Target transaction code (8 bytes padded with blanks)
v I/O PCB
v ELAWORK PCB (or fullword of binary zeros if a DB2 work database is used)
v Return code (fullword binary).
ELATSGET provides the following return codes:
Table 50. ELATSGET return codes
Code Meaning
0 Read successful
4 Read successful, truncation occurred
8 Read failed, record not found
12 Read failed, other error
Truncation occurs when the calling program attempts to restore data into a buffer
that is smaller than the data that was previously saved. If the buffer is larger than
the data that was previously saved, the trailing portion of the buffer is initialized
to blanks.
ELATSGET does not issue any error messages. The calling program must take the
appropriate action when an error occurs. If a DL/I work database is used, the PCB
contains the status code that indicates the error. If a DB2 work database is used,
the full-word binary (5th parameter) contains the SQL code that indicates the error.
In the previous example, modname is an 8-byte character field, and parm1 through
parm6 are as follows:
v Record buffer
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.
The code example below shows an EGL DLISegment record definition for the
IMSADF II, Version 2, Release 2, work database. The fields in this definition are
limited to those you must modify if an EGL program is transferring directly to the
IMSADF II conversational transaction driver.
//*** RECORD=ADFWKDB ****
// The sample segment layout of the ADFWORK database default
// segment size is 6000 bytes. Use this DLISegment definition
// to retrieve data from and store data into the ADF work database.
// Refer to the IMSADF Application Development Guide
// Appendix E for details on which fields to update.
// ***********************
Record ADFWKDB type DLISegment {
keyItem = "LTERMNME"
}
3 LTERMNME char(8) ;
3 SPALEGTH smallint ;
3 * char(4) ;
3 SPATRANS char(8) ;
3 * char(397) ;
3 SPABITS hex(2) ;
3 * char(6) ;
3 SPAFIRST smallint ;
3 SPARTNCD int ;
3 SPASECTX smallint ;
3 * char(4) ;
3 SPAPGOPT smallint ;
3 SPASWITH char(2) ;
4 RDFSWITH smallint ;
3 SPATRX char(3) ;
3 SPACGTRX char(3) ;
3 * char(66) ;
3 SPASHOTR char(8) ;
3 * char(31) ;
3 SPAKEYID char(255) ;
3 SPAFLDSG char(5192) ;
end // end ADFWKDB
Rational COBOL Runtime for zSeries does not share its work database with
IMSADF II; the two databases have different formats. Changes to the IMSADF II
work database do not affect the Rational COBOL Runtime work database.
Similarly, changes made by an EGL program to the Rational COBOL Runtime work
database do not affect the IMSADF II work database.
Starting from the IMSADF II side, define the EGL program to IMSADF II in the
same way that you define a transaction that is written entirely in COBOL. Refer to
the IMSADF II documentation for your system for additional information. The
EGL generated program name (and therefore, the load module name) must obey
the following IMSADF II naming convention:
ssssTcc
ssss
The IMSADF II program system ID.
T A constant.
The EGL program must be generated with the spaADF build descriptor option set
to YES and spaSize set to 28 to match the IMSADF II SPA size. When IMS
schedules the new transaction, the EGL program control logic reads the IMSADF II
SPA from the I/O PCB. Because of these build descriptor options, the EGL
program control logic does not modify the SPA in any way. Therefore, the EGL
program can eventually do an immediate program-to-program message switch
back to the IMSADF II conversational transaction driver. Switching directly to the
IMSADF II sign-on transaction is not supported.
You can also specify the spaStatusBytePosition=p build descriptor option, where p
specifies an available byte in the IMSADF II SPA that can be used for EGL’s
segmentation status byte. All EGL programs involved in a series of message
switches that started from the IMSADF II transaction driver must have the same
spaSize, spaADF, and spaStatusBytePosition build descriptor options. Refer to
your IMSADF II documentation for information on the positions in the SPA that
are available.
As in a COBOL program, the EGL program can access the IMSADF II work
database to use information or to modify information in the IMSADF II
communication area. If you access the IMSADF II work database, the EGL program
processes the IMSADF II work database the way it would any other program
database. Use the record definition above to access the IMSADF II work database.
If you use a DL/I IMSADF II work database, be sure to include a database PCB in
the EGL program’s PSB definition.
The following table shows the conventions used for transferring between EGL
programs when the spaADF build descriptor option is set to YES. These
conventions differ from the techniques used when IMSADF II is not involved in
that special techniques are used to pass a record so the SPA can remain intact. ADF
mode does not support transfers between segmented nonconversational programs.
Table 52. Transfers between EGL conversational programs
Immediate switch (optional
Action input form) Deferred switch (with input form)
Coding and Define both programs as Define both programs as segmented
generating segmented = YES. Generate both = YES. Generate both programs as
programs as conversational with conversational with the spaSize
the spaSize build descriptor set to build descriptor set to 28 and the
28 and the spaADF build spaADF build descriptor option set
descriptor option set to YES. to YES.
Performing the The originating program cannot The originating program must write
transfer send a form. If it is an EGL the form to a message queue
program, it does this using a associated with the terminal after
transfer to transaction statement first writing the SPA. If it is an EGL
with a record. program, it does this using a show
statement with a form and an
optional record.
Using an input The target program can optionally The target program must have an
form have an input form. input form.
Passing a record The record is transferred in a The record, if any, is transferred
message segment following the through the work database.
SPA.
Specifying If spaStatusBytePosition was If spaStatusBytePosition was
segmentation specified, the target program specified, the target program uses
status byte always ignores the value of the the value of the segmentation status
segmentation status byte that is byte at the offset specified when
located in the SPA at the offset there is an input form integrity
specified. problem caused by the program user
pressing PA1 or PA2.
The segmentation status byte specified by spaStatusBytePosition is used only for program
to program transfers for conversational programs. The byte is present for transfers between
conversational programs and other programs. However, a transferring non-EGL program
should always set the byte to blank. A target non-EGL program can ignore the value of the
segmentation status byte.
Immediate switch between two EGL programs: With this technique two
segmented conversational EGL programs can change both the transaction name
and the PSB name without presenting a form to the program user. The two
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.
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.
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.
If you are calling a non-EGL program from an EGL program, the call uses the
standard iSeries CALL interface. Parameters are passed using a standard system
argument list.
When you use the transfer to program or transfer to transaction statement, control
is passed directly to the target program using the iSeries XCTL interface. If a
record is specified, it is passed as a parameter using a standard system argument
list. The transferring program is removed from the program invocation stack and
does not resume control when the target program ends.
Related concepts
“Transfer of control across programs” on page 251
If you are calling a non-EGL program from an EGL program, the call uses the
standard iSeries CALL interface. Parameters are passed using a standard system
argument list.
When you use the transfer to program or transfer to transaction statement, control
is passed directly to the target program using the iSeries XCTL interface. If a
record is specified, it is passed as a parameter using a standard system argument
list. The transferring program is removed from the program invocation stack and
does not resume control when the target program ends.
Related concepts
“Transfer of control across programs” on page 251
You create a Library part of type nativeLibrary to act as an interface between your
EGL program and the DLL. The Library part lists function names and parameters,
and can use the alias property of the functions where function names do not
match EGL conventions.
The program accessed on IMS is not the called program itself, but is a catcher
program provided by Rational COBOL Runtime for zSeries. As shown later, the
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.
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
To use the Generation for VSE feature, you must do the following things:
v Install the feature and then enable the feature by purchasing and applying the
license for IBM Rational Business Developer Extension for VSE. The feature
provides the COBOL generation capability for the VSE environment.
v Install and customize IBM Rational COBOL Runtime for z/VSE, which provides
the runtime support for the VSE environment (similar to the runtime support for
z/OS that is provided by IBM Rational COBOL Runtime for zSeries).
For more information about developing and generating EGL programs in the VSE
environment, including compatibility considerations for VSE that differ from z/OS,
refer to the Rational Business Developer V7.5 Generation for z/VSE feature Reference
Manual (SC19-2539-00). You can find this manual in PDF form on the EGL Cafe
site:
http://www.ibm.com/software/rational/cafe/community/egl/documentation
For more information about installing and customizing the VSE runtime support,
refer to the Program Directory for Rational COBOL Runtime for z/VSE (GI10-8803-00).
Related reference
“Developing EGL programs for the IMS environment” on page 307
For more information on how to interact with IMS control blocks, see “EGL
support for runtime PSBs and PCBs” on page 310.
The next two sections provide information particular to each of the two program
types.
Text UI programs
If you code a main program that accepts or displays a text form, EGL handles the
details of I/O PCB access. You must set the segmented program property to YES.
You can interact with the terminal by using the converse statement, which presents
a text form and responds to the user’s input by processing the statement that
follows the converse statement. For an overview of the runtime behavior, refer to
the EGL Language Reference.
On IMS, a called Text UI program is not supported. A main Text UI program can
transfer to or from a non-EGL IMS or IMSADF II program on the same IMS
system. For more information, see one of the following topics:
v “Transferring control in the IMS/VS environment” on page 275
v “Transferring to and from IMSADF II programs” on page 293
.
Basic programs
If you code a main program that neither accepts nor displays a text form, input is
available from the IMS message queue. To retrieve that input, you code a loop that
reads one message after another into a serial record that is associated with the I/O
PCB. For input from a message queue, the file type associated with the serial
record may be SMSGQ or MMSGQ. For details, see “Using serial and print files in
IMS” on page 319.
In most environments, when a main basic program is started, the program’s input
record is initialized from the record that was passed by the transferring program.
This is not true of a main basic program that is generated for the IMS BMP
environment. Instead the target program must read the transferred record from the
message queue.
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.
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.
To create a transaction-oriented IMS BMP program, you must retrieve input from
the IMS message queue by coding a loop that reads one message after another into
a serial record that is associated with the I/O PCB. The use of single-segment and
multi-segment message queues is as described earlier for IMS MPP programs. To
create a batch-oriented IMS BMP program, do not read input from the IMS
message queue. For details, see “Using serial and print files in IMS” on page 319.
An IMS BMP program can also send output to another message queue or printer
as described for IMS MPP programs. An IMS BMP program can use any of the
EGL statements that a program generated for z/OS batch can use. In particular,
you can do the following in an IMS BMP or z/OS batch program:
v Receive input or send output to a GSAM file. For that purpose, you code an add
statement to write a serial record that is associated (at generation time) with a
GSAM PCB. You also specify the file type as GSAM and specify the name of the
GSAM data set. Alternatively, at run time you can use
recordName.resourceAssociation to change the name of the data set.
v Send print output to a GSAM data set; and for that purpose you code a print
statement. You associate the printer (at generation time) with a GSAM PCB,
Your code can transfer to or call another IMS BMP program. A called program
cannot read from a message queue.
To generate a program for an MPP or IFP region, set system to IMS/VS. The
following options also apply:
v To mandate the size of a SPA (as needed for a conversational program), set the
build descriptor option spaSize. To ensure that a program is nonconversational,
set that value to zero (as is the default).
v To indicate that a conversational program transfers to or from an IMSADF II
program, set the build descriptor option spaADF to YES.
v To generate a FastPath program (which runs in an IFP region), set the build
descriptor option imsFastPath to YES.
To generate a program for the IMS BMP region, set system to IMSBMP.
Additional build descriptor options apply only to the IMS/VS or IMS BMP
environments:
v imsLogID
v mfsExtendedAttr
v mfsIgnore
v mfsUseTestLibrary
v formServicePgmType
v spaStatusBytePosition
The mfsDevice must also be set before you generate your formGroup.
Related concepts
“Transfer of control across programs” on page 251
Related reference
“EGL support for runtime PSBs and PCBs”
Related tasks
“Using serial and print files in IMS” on page 319
“Transferring control in the IMS/VS environment” on page 275
“Transferring to and from IMSADF II programs” on page 293
First, define the DLISegment record parts that you will reference in database PCB
records (if any). Your next, primary tasks are as follows:
1. Define a PSB record part. That part includes the set of PCB records that will be
used when accessing IMS message queues, DL/I databases, or GSAM files.
2. In the program, make the PSB and PCB information available:
v Declare a record that is based on the PSB record part
v Set the program property @dli, property field psb to the name of the PSB
record; for more information on the syntax, see Set-value blocks.
Each PCB record is based on one of the following, predefined PCB record parts:
IO_ PCBRecord
Used to interact with an I/O PCB, which allows for input from a program or
terminal and (if the input came from a terminal) allows for output to the same
terminal. The I/O PCB also provides access to other IMS capabilities; for
example, checkpoint and restart of a batch program.
ALT_PCBRecord
Used to reference a teleprocessing PCB other than the I/O PCB. This type of
record allows your code to write output to a message queue that is associated
either with another transaction or with a device other than the terminal
associated with the I/O PCB. The runtime PCB may be either of the following
kinds:
v An alternate PCB, in which case the message is sent to its destination only if
a commit occurs; or
v An express alternate PCB, in which case the message is sent to its
destination regardless of whether a commit or rollback occurs.
DB_PCBRecord
Used to reference a database PCB, which represents a DL/I database accessible
from your program. The runtime database PCB specifies the data that can be
accessed and the type of access that is valid.
GSAM_PCBRecord
Used to reference a GSAM PCB, which is used when a z/OS batch or IMS
BMP program accesses a serial file that acts as a root-only DL/I database.
The next list provides details on the runtime PSB in each of the target systems.
CICS
The value of the PSB record property defaultPSBName is (by default) the
name of the runtime PSB. EGL places that name in the psbName field of the
system variable dliLib.psbData, but you can assign a different value to that
library field. When your program attempts an I/O operation against a DL/I
database, the value in psbName determines what runtime PSB is used.
The system variable dliLib.psbData has a second field, psbRef. The initial
value of the field is zero, which indicates that no PSB is scheduled. When the
first DL/I I/O occurs, EGL runtime issues a PSB schedule call, which acts as
follows:
v Uses the value in dliLib.psbData.psbName to schedule a runtime PSB.
Note: You must avoid writing logic that assigns any value to
dliLib.psbData.psbRef.
During a call, you can use the variable dliLib.psbData to ″pass the PSB″
(really, to pass a name and the related address).
During a transfer, details of runtime behavior depend on how the transfer
occurs:
v If the transfer is by a show statement with a returning clause or by a
transfer to transaction statement, the scheduled PSB ends because a commit
point occurs during the transfer, and a PSB is not passed to the target
program.
v If the transfer is by a transfer to program statement, the default behavior
depends on whether a PSB is scheduled:
– If a PSB is not scheduled, no commit point occurs.
– If a PSB is scheduled, that PSB ends because a commit point occurs
during the transfer, and a PSB is not passed to the target program. But in
this case an alternative outcome is possible, with the benefit that you can
minimize the difference in behavior when the transferring program is
generated for CICS as compared to when that program is generated for
IMS/VS. The alternative outcome occurs when four conditions are met:
- The target system is z/OS CICS;
- The target program is generated by EGL;
- The build descriptor option synchOnPgmTransfer is set to NO; and
- The default PSB referenced in the PSB record of the transferring
program is the same as the default PSB referenced in the PSB record of
the target program.
In this case, a commit point does not occur, and EGL passes the
scheduled PSB to the target program.
Note: 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.
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.
With the exception of I/O and alternate PCB records that EGL ignores so you can
generate the same program across different environments, the structure of the PSB
record in a main program must reflect at least the initial PCBs in the runtime PSB:
v The PSB record cannot have more PCB records than the number of PCBs in the
runtime PSB but can have fewer
v The position of each PCB record must match the position of the related runtime
PCB and must be of the same type as that PCB
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
From To printer
Terminal 1 or other transaction
From
Terminal 2
Queue
Message
Back to
Relational original terminal
or DL/I
Database
Message
In this example, the IMS controller starts the transaction program when the
message queue associated with the program contains a message. Another program
might have put the message on the queue, or the controller might have read input
from the terminal. The program takes the message off the queue, does any
required database I/O, and adds messages to output queues to continue
processing. The output queue can represent the input terminal, another terminal or
printer, or a queue associated with another transaction. The program then loops
back to the beginning and processes the next message on its input queue.
Typical PL/I or COBOL programs must continue the cycle until the message queue
is empty because multiple terminals run the same transaction concurrently.
However, EGL textUI programs automatically loop to read the next message in the
queue. You do not need to define message queue control functions directly. You
can define programs for IMS just as you define programs for CICS, that use a
synchronous logic structure instead of a message-driven structure. The following
figure shows an example of a synchronous program:
Database
Terminal
or File
With the synchronous model, you only need to consider the processing that must
occur for a single user at a single terminal. This simplifies both the design and the
definition of the program.
IMS requires you to commit all database changes and to release all database locks
and positions when waiting for user input. In EGL, this means creating a
segmented program. When you define the program, remember that EGL performs
a commit with each converse I/O statement.
You must understand how segmentation works to develop programs for IMS; see
Segmentation in Text UI programs.
Related concepts
“Developing EGL programs for the IMS environment” on page 307
You can define the 8-byte constant field with the protect and dark attributes. The
attribute byte on the form becomes the attribute byte in the EGL-generated MFS
control block. The 8-byte constant contains the name of the IMS transaction that is
started when the form is processed. Specifying the constant on the form enables
the user to specify the IMS /FORMAT command to display a formatted screen to
start a transaction. Do not use the /FORMAT command if variable fields on the
form have initial default values. If the /FORMAT command is used, the default
values do not appear.
If you do not define an 8-byte, protected, dark constant on the form, EGL searches
for any string of 9 blanks on the form and sets this area aside as a protected, dark
variable field (1 byte attribute, 8 bytes of data) in the generated MFS map. The
generated program uses this field to store the name for the next IMS transaction to
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).
MFS control blocks cannot exceed 32748 bytes. If you are using a large FormGroup
part, the following formulas offer a guideline for estimating an upper limit for the
size of the control blocks that will be generated. Using these formulas during your
design helps you determine whether your FormGroup parts should be split into
smaller ones. If a generated control block is too large, MFS generation issues a 3022
abnormal termination.
You identify a serial file or print file as a GSAM file by using the resource
association part during generation to specify a file type of GSAM and a PCB name.
When you associate a serial file with a GSAM file, you must include the following
information:
You can associate a serial file or print file with a message queue by using a
resource association part during generation and specifying the file type and a PCB
name. When you associate a serial file with a message queue, you must define the
following resource information:
Resource name
You must indicate the 1- to 8-character destination ID for printer or serial file
data. The name must match the ID of an IMS logical terminal or a transaction
code that is defined in the IMS system definition.
The file name is the default resource name for the message queue. You can
override this default in the resource association part.
If the PCB that you select is a modifiable alternate or express alternate PCB,
you can override the default message queue name at run time by setting a
value for record.resourceAssociation for a file or
converseVar.printerAssociation for a printer in the program.
record.resourceAssociation is treated as a local variable. Setting
record.resourceAssociation for a record in one program does not affect
record.resourceAssociation in another program. An add statement writes to the
message queue identified by the setting of record.resourceAssociation for that
program.
Message queue type
You can specify single-segment message queues or multiple-segment message
queues.
Single-segment message queues (SMSGQs)
For a single-segment message queue, each record that you add or that you
read (with a get next) from the serial file is a complete message. The
generated COBOL program issues an IMS PURG call between records that
are added to a single-segment message queue. The generated COBOL
program issues an IMS get unique for each get next statement.
Multiple-segment message queues (MMSGQs)
EGL I/O error code IMS Messsage Queue status code Severity
endOfFile QC Soft
noRecordFound QD Soft
ioError any non-blank status code Hard or soft
hardIOError non-blank other than QC, QD, CE, CF, CG, Hard
CI, CJ, CK, CL
EGL I/O error code GSAM status code Severity
endOfFile GB Soft
ioError any non-blank status code Hard or soft
hardIOError non-blank other than GB Hard
// declare variables
myTransaction myTransactionPart; // serial record for message queue
mypsb addToQueue; // psb
function main()
...
converse FORM1;
// do whatever processing is necessary
move FORM1 to myTransaction byName;
add myTransaction;
...
end
end
When you generate, you must specify a resource association part that associates
the serial file with a message queue and that provides the name of the transaction
to which it is to be sent, along with the name of the PCB to use. Consider the
following example, which also includes an association element that makes possible
the input of the message-queue data by a batch program, as described later:
<ResourceAssociations name="IMS_RESOURCE_ASSOCIATION">
<association fileName="MYMSGQUE">
<imsvs>
<smsgq systemName="NEXTTRX" pcbName="elaalt"/>
</imsvs>
</association>
<association fileName="MYINQUE">
<imsvs>
<smsgq systemName="NEXTTRX" pcbName="iopcb"/>
</imsvs>
</association>
</ResourceAssociations>
The program can use the same serial record that addtrans used, but with a new file
name because a different PCB name is required. Key changes show in bold in the
example below:
//define PSB
Record getFromQueue type PSBRecord { defaultPSBName="MYTRXCD2" }
// three PCBs required for CBLTDLI on IMS
iopcb IO_PCBRecord { @PCB { pcbType = TP } }
elaalt ALT_PCBRecord { @PCB { pcbType = TP } };
elaexp ALT_PCBRecord { @PCB { pcbType = TP } };
// other database PCBs
end
// declare variables
myTransaction myTransactionPart // serial record for message queue
{fileName="MYINQUE"};
mypsb getFromQueue; // psb
function main()
while (myTransaction not endOfFile)
get next myTransaction;
// do whatever processing is necessary
end
end
end
When you generate the program for either the IMS/VS or the IMS BMP
environments, you must also specify a resource association part that associates the
serial file with a message queue, as well as the name of the PCB to use. In this
case, the I/O PCB is used for input, as shown in the ResourceAssociations part in
the previous section. The systemName property is optional. The program reads the
message queue associated with the transaction that started the program, based on
the IMS system definition. EGL sets sysVar.transactionID based on the IMS
transaction id in the input message.
A developer writes Rich UI applications using EGL syntax. For advanced purposes,
however, a developer can write custom JavaScript or use JavaScript libraries
instead of relying on the default behavior provided by EGL. For example, you can
use Rich UI to access the following software:
v The Dojo Toolkit (http://dojotoolkit.org/)
v Microsoft Silverlight (http://silverlight.net/)
A Rich UI application can act as the front end for services that access databases
and do other complex processing. You can access the following kinds of services,
which are described in Overview of service access:
v SOAP Web services
v REST Web services that are provided by third parties such as Yahoo and Google
v EGL REST services, which are REST Web services for which the access code is
particularly simple
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.
You can use the EGL Rich UI editor to modify a Rich UI handler and to preview
the handler’s runtime behavior. The editor includes the following views:
v The Design view is a graphical design area that shows the displayable content of
the Rich UI handler. You can drag-and-drop widgets from a palette into the
display and then customize those widgets in the Properties view.
v The Source view provides the EGL editor, where you update logic and add or
update widgets. The Design view and Source view are integrated: changes to the
Design view are reflected in the Source view; and, if possible, changes to the
Source view are reflected in the Design view.
v The Preview view is a browser, internal to the Workbench, where you can run
your logic. You can easily switch to an external browser if you prefer.
Here is the EGL Rich UI perspective as it appears when a Rich UI handler is open
in the Rich UI editor:
When you first open the Workbench, switch to the EGL Rich UI perspective:
v Click Window -> Open Perspective -> Other
v At the Open Perspective dialog, double-click EGL Rich UI
If most of your EGL work will involve Rich UI, you will want to make the Rich UI
editor the default for EGL files:
1. Click Window > Preferences. The Preferences dialog box is displayed.
2. Expand General and Editors and click File Associations. The File Associations
dialog is displayed.
3. In the File types section, click .egl
4. In the Associated editors section, click EGL Rich UI Editor and, at the right,
click Default
5. Click OK
We recommend that you use the Rich UI samples to explore the technology:
1. Click Help -> Samples. The Help dialog box is displayed.
2. Expand Samples, Technology samples.
3. Click Rich UI technical sample.
4. If your workbench does not already have the project com.ibm.egl.rui_1.0.0, click
the entry to it.
5. Click the entry to import the samples.
6. In the workbench Project Explorer, expand the project com.ibm.egl.rui.samples,
file EGL Source, package contents.
7. If you previously set the Rich UI editor to be the default for EGL files,
double-click contents.egl. Otherwise, right-click contents.egl and select Open
with → EGL Rich UI Editor.
8. Select the Preview tab at the bottom of the editor.
9. Follow the on-screen directions and try out the alternatives presented there.
When you want to work outside of the Rich UI samples project, do as follows:
1. Click File -> New -> Project. The New Project wizard is displayed.
2. Expand EGL, click EGL Project and then Next. The New EGL Project page is
displayed.
3. Type a project name and select Rich UI Project. In most cases, complete the
task by clicking Finish, However, if you want to consider additional options,
continue here:
EGL Cafe provides is a center of information about the products that include EGL:
http://www.ibm.com/software/rational/eglcafe
For a concise introduction to EGL, see IBM Rational Business Developer with EGL:
http://www.mc-store.com/5087.html
The content of that book will be included in a new work that focuses on Rich UI.
Enterprise Web 2.0 with EGL is expected from MC Press in May 2009.
See the following topics in the EGL Programmer’s Guide (aside from topics
specifically on Rich UI):
v Using EGL with the Eclipse IDE
v Introduction to EGL projects through Properties:
– In relation to Data parts, ignore references to Form Group and
ArrayDictionary
– In relation to Logic parts, ignore references to Handlers (other than Rich UI
handlers) and Programs
– Ignore Build parts other than the build descriptor and the deployment
descriptor
v Content assist
v Searching for EGL files and parts
v Setting Preferences in the EGL editor; specifically, the following topics:
– Setting Preferences for folding in the EGL editor
– Setting Preferences for organizing import statements in the EGL editor
– Setting Preferences for source styles
– Enabling and disabling code templates
Exclude the following subjects when reviewing the EGL Language Reference:
v File and database access; related statements such as forEach and get, and related
Exception records. When you work with Rich UI, all such access is handled by
invoked services.
v The Program-related statements transfer and call.
v User interfaces.
v Record stereotypes other than BasicRecord and ExceptionRecord.
v Details that are specific to Java or COBOL processing; in particular, details
related to J2EE, CICS, IMS, and z/OS batch.
v Compatibility with VisualAge Generator or Informix 4GL.
v System libraries ConsoleLib, ConverseLib, DliLib, J2eeLib, JavaLib, LobLib,
PortalLib SqlLib, VgLib, and VgVar.
See the following topics in the EGL Generation Guide (aside from topics specifically
on Rich UI):
v Introduction to EGL generation
v Build descriptor part
When a user enters a Web address into a browser, the browser transmits a request
to a Web server, which is usually on a second machine. The address identifies a
specific server and indicates what content is to be returned to the browser. For
example, if you enter the address http://www.ibm.com, an IBM server replies with a
message that the browser uses to display the IBM home page. The question that is
of interest now is, how does the browser use the message?
The browser brings portions of the message into an internal set of data areas. The
browser then uses the values in those data areas to display on-screen controls,
which are commonly called widgets. Example widgets are buttons and text fields.
The internal data areas used by the browser are represented as an inverted tree:
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
When you develop a Web page with Rich UI, you declare widgets much as you
declare integers. However, the widgets are displayable only if your code also adds
those widgets to the DOM tree. Your code can also update the tree—adding,
changing, and removing widgets—in response to runtime events such as a user’s
clicking a button. The central point is as follows: Your main task in Web-page
development is to create and update a DOM tree.
When you work in the Design tab of the Rich UI editor, some of the tasks needed
for initial DOM-tree creation are handled for you automatically during a
drag-and-drop operation. When you work in the Source tab of the Rich UI editor
or in the EGL editor, you can write code directly and even reference DOM
elements explicitly.
In general terms, you create and update a DOM tree in three steps:
1. Declare widgets of specific types—Button for buttons, TextField for text fields,
and so forth—and customize the widget properties. For example, you might set
the text of a button to ″Input to Output,″ as in our example.
2. Add widgets to the initial DOM tree.
3. Alter the DOM tree by adding, changing, and removing widgets at those points
in your code when you want the changes to be displayable.
We say that a widget or its changes are ″displayable″ rather than ″displayed″
because a widget in a DOM tree can be hidden from view.
Related concepts
“Overview of EGL Rich UI” on page 327
“Introduction to the EGL Rich UI editor” on page 337
You can use the EGL Rich UI editor to modify a Rich UI handler and to
preview the handler’s runtime behavior.
Overview of service access
Overview of EGL Rich UI generation and deployment
“Securing a Rich UI application” on page 352
Related reference
Rich UI handler part
Rich UI widgets
Reference to widgets
Extending the Rich UI widget set
When you drag a widget from the palette to the Design surface, the areas that can
receive the widget are called potential drop locations, and the color of those areas is
yellow by default. When you hover over a potential drop location, the area is
called a selected drop location, and the color of that area is green by default. You can
customize the colors in the Workbench preferences.
When you first drag a widget to the Design surface, the entire surface is a selected
drop location, and the effect of the drop is to declare the widget and to identify it
as the first element in the Rich UI handler’s initialUI property. That property
When you drag another widget to the Design surface, you have the following
choices:
v You can place the widget adjacent to the initially placed widget. The effect on
your source code is to declare the second widget and to identify it as another
element in the initialUI array. Your placement of the new widget is either
before or after the first widget and indicates where the widget is placed in the
array.
v If the initially placed widget was a container—for example, a box—you can
place the second widget inside the first. The effect on your source code is to add
an element to the children property of the container. The effect is ultimately to
add a child element to the DOM tree; specifically, to add a child element to the
element that represents the container.
Your subsequent work continues to build the DOM tree. You can repeatedly fulfill
drag-and-drop operations, with the placement of a widget determining what array
is affected and where the widget is placed in the array. The drag-and-drop
operation is an alternative to writing a widget declaration and array assignment in
the code itself, whether in the Source tab of the Rich UI editor or in the EGL
editor.
New widget declarations are added to the source code before the declarations that
were already there; that is, the order of the statements is opposite to the order of
the drag-and-drop operations.
The Design surface is composed of two layers. The bottom layer is the Web
browser, which displays widgets, including initial text values. The top layer is an
editing overlay, including angle brackets at each corner of each widget.
The background of the top layer can have any of the following characteristics:
transparent, a pattern of white and transparent dots, or (on Windows platforms) a
white layer with a varying level of transparency. You can set those transparency
options by setting a Workbench preference, as described in Setting preferences for
Rich UI appearance. When you are working in the editor, you can change the
transparency options that are in use for the editing session.
You can complement the features in the Rich UI editor by opening a single file in
both the EGL Rich UI editor and the EGL editor. For example, the following screen
shot displays the file GridDemo.egl in two ways. At the top is the Design tab of
the Rich UI editor, along with a palette that lists the available Widget types. At the
bottom is the EGL editor. Your work in either editor affects the same file and is
reflected in the content displayed in the other editor.
To learn the implication of the actions described here, see Introduction to the EGL
Rich UI editor.
Adding a widget
When multiple widgets overlap a given area, click the area repeatedly to cycle
through the available widgets, making each one the current one in turn. You can
move or delete the current widget as described in the next sections.
Moving a widget
Deleting a widget
Delete a widget:
v Click the widget and press the Delete key; or
v Right-click the widget and, at the popup menu, select Delete.
The deletion removes the reference to the widget in the handler-specific initialUI
property or in the container-widget-specific children property, but does not
remove the widget declaration from the Rich UI handler.
Related concepts
“Overview of EGL Rich UI” on page 327
“Understanding how browsers handle a Rich UI application” on page 334
Related tasks
“Introduction to the EGL Rich UI editor” on page 337
You can use the EGL Rich UI editor to modify a Rich UI handler and to
preview the handler’s runtime behavior.
“Using the tools on the Design surface”
“Selecting a palette” on page 342
“Setting widget properties and events” on page 343
You use the Properties and Events views when working at the Design surface
of the Rich UI editor.
“Running a Web application in the EGL Rich UI editor” on page 344
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
Rich UI handler part
Rich UI widgets
Reference to widgets
Extending the Rich UI widget set
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.
The effect of selecting the Palette view is to close the Rich UI editor palette. If you
want to return to the Rich UI editor palette, close the Palette view.
Related concepts
“Overview of EGL Rich UI” on page 327
“Understanding how browsers handle a Rich UI application” on page 334
Related tasks
“Introduction to the EGL Rich UI editor” on page 337
You can use the EGL Rich UI editor to modify a Rich UI handler and to
preview the handler’s runtime behavior.
“Opening the EGL Rich UI editor” on page 339
“Using the tools on the Design surface” on page 341
“Setting widget properties and events”
You use the Properties and Events views when working at the Design surface
of the Rich UI editor.
“Running a Web application in the EGL Rich UI editor” on page 344
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
Rich UI handler part
Rich UI widgets
Reference to widgets
Setting 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).
At the Events tab, you can create a new function in the Rich UI handler:
1. Click the New event handler icon. The New event handler dialog is displayed.
2. Specify the function name and click OK.
Also at the Events tab, you can specify which Rich UI handler function to run in
response to an event such as a user’s click on a button. In this case, you also add
an entry for an event property such onClick. Here are the keystroke details:
v To specify an existing Rich UI handler function, select the event of interest and
use the dropdown to select the function name.
v Alternatively, to create a new function, do as follows:
1. Select the event of interest and click the New event handler icon. The New
event handler dialog is displayed.
2. Specify the function name and, if you want to link the function to the event,
ensure that the checkbox is selected.
3. Click OK.
Related concepts
“Overview of EGL Rich UI” on page 327
“Understanding how browsers handle a Rich UI application” on page 334
Related tasks
“Introduction to the EGL Rich UI editor” on page 337
You can use the EGL Rich UI editor to modify a Rich UI handler and to
preview the handler’s runtime behavior.
“Opening the EGL Rich UI editor” on page 339
“Using the tools on the Design surface” on page 341
“Selecting a palette” on page 342
“Running a Web application in the EGL Rich UI editor”
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
Rich UI handler part
Rich UI widgets
Reference to widgets
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
In the Browser size tab, you set the browser size that is appropriate for a specific
kind of device such as a cell phone. Specifically, you set options that are in effect
whenever you open the Rich UI editor. However, when you are working in the
editor, you can change the browser-size options for the file being edited.
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.
You can set these preferences only if you previously enabled bidirectional text as
follows:
1. From the main menu, click Window → Preferences. The Preferences dialog box
is displayed.
2. Expand EGL and select Bidirectional text. The Bidirectional text page is
displayed.
3. Select the Enable bidirectional support checkbox. After this check box is
selected, the other options are available.
4. To display and edit the bidirectional text fields in visual mode (the way the text
will be displayed), select Enable visual data ordering.
5. For languages that read from right to left, select Enable right-to-left
orientation.
You should also evaluate JSF applications that are rewritten into Rich UI
applications for security issues. Even if the JSF application was not originally
secure, the introduction of the EGL Rich UI Proxy in V7.5.1 presents security risks
that must be mitigated. You might need to change the design of the application.
This section contains considerations that are specific to securing the resources that
are related to Rich UI applications. It also provides a quick overview and examples
of how to configure and use Java™ Enterprise Edition (JEE) authentication and
Secure Sockets Layer (SSL). Security is not available when you preview a Rich UI
application from the EGL Rich UI editor. Because security is a large and complex
topic, also consult the online documentation of your application server and other
security documentation.
Related concepts
“Overview of Rich UI security”
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
“Resources to secure” on page 355
“JSF versus Rich UI applications” on page 357
“Using Web container-managed (JEE) authentication” on page 357
“Using application-managed (custom) authentication” on page 362
“Authentication summary” on page 367
“Authorization” on page 368
“Overview of SSL” on page 377
“Overview of EGL Rich UI” on page 327
Related tasks
“Preventing client-side security threats” on page 376
Related reference
“Sample login and error pages for JEE form-based authentication” on page 374
“JEE security example” on page 369
Consider using JEE security to protect your Rich UI application in the following
cases:
v The entire Rich UI application needs to be secured.
Two common types of JEE authentication are basic and form-based. In JEE basic
authentication (also known as HTTP basic authentication), when a client, such as a
browser, requests a Web page from a server without providing a user id and
password, the server sends back a 401 response code. The client then prompts the
user for a user id and password by displaying a default login dialog to the user.
The client resends the request to the server, including the user id and password in
the HTTP header. If the user is authenticated, the server returns the requested
page. If the user id and password are invalid, the server returns a 401 response
code and the client prompts the user again. In JEE form-based authentication, you
can use a customized login screen with the look and feel of the application instead
of the browser-provided login dialog. The user id and password are passed to the
server in the form data instead of in the HTTP header of the request.
JEE security uses roles to manage access to resources. Certain roles are allowed
access to certain resources. Users and groups are mapped to appropriate roles. For
example, the user bob might be mapped to the role administrator.
While JEE security is available through WebSphere Application Server and Apache
Tomcat, it is not available from the Workbench. You need to deploy a Rich UI
application to WebSphere or Tomcat to apply and test security.
If Web container-managed security is not suitable for your needs, you can build
custom security into your Rich UI application. Although custom security requires
that you add security-related code to your Rich UI application, you cannot avoid it
if JEE security alone is not sufficient to express the security model of an
application. If you prefer, you can combine both forms of security.
Custom authorization can provide a more granular level of authorization than JEE
roles. You might want to use custom security to authenticate users before they can
access restricted parts of your application.
Related concepts
“Overview of Rich UI security” on page 352
“Confidentiality and Integrity”
“Authentication summary” on page 367
Related tasks
“Using Web container-managed (JEE) authentication” on page 357
“Using application-managed (custom) authentication” on page 362
It is important that you authenticate over SSL, whether you use JEE form-based,
JEE basic, or custom authentication. For more information about SSL, see
″Overview of SSL.″
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
Resources to secure
When you determine which resources to secure, review all of the components that
have a URL mapping and that your Rich UI application accesses:
EGL generates a Rich UI application into an HTML file. HTML files are generated
into the WebContent folder (or into a subfolder in the WebContent folder) of your
deployed project. If an HTML file is secure, you must authenticate before you
access the Rich UI application that is defined in the HTML file. To secure the entire
HTML file, you can use JEE authentication. To restrict sensitive areas of the Rich
UI application, you can use custom security.
The EGL Rich UI Proxy handles communication between the HTML file that EGL
generates for a Rich UI application and Web services Because of the Same Origin
policy for JavaScript™, the HTML file cannot invoke a Web service that has a
different origin (defined as protocol, domain, and port) than that of the HTML file.
To get to Web services on different origins, the HTML file uses a Java servlet
known as the EGL Rich UI Proxy. All Web services that are invoked in a Rich UI
application are accessed through the proxy.
Because the URL of the EGL Rich UI Proxy is visible in the JavaScript that EGL
generates for your Rich UI application, you must prevent the proxy from being
used by anyone other than your Rich UI client to invoke Web services. If you leave
the proxy unsecured, it can be used to instigate JavaScript hijacking attacks. If your
Rich UI application does not use the EGL Rich UI Proxy (that is, if the application
invokes no Web services), remove access to the proxy from your deployed project.
For more information, see Removing access to the EGL Rich UI Proxy servlet.
Otherwise, you can use JEE basic authentication to prevent the proxy from being
invoked by an unauthenticated client. While this action cannot guarantee
protection against Web threats, it can reduce the possibility of one occurring.
If both the HTML file and EGL Rich UI Proxy are secure, authentication is required
only before you can access the HTML file. If the EGL Rich UI Proxy is secure and
the HTML file is not, authentication is required before you can access the proxy
(that is, before the application calls a Web service that is invoked through the
proxy).
To secure EGL Web services that are generated into a Web project, you can use JEE
security through HTTP basic authentication. In HTTP basic authentication, you
access secure Web services by passing a valid user id and password in the HTTP
header. EGL provides a system function in ServiceLib,
setHTTPBasicAuthentication, which sets these values in the header. Precede each
call to a secure Web service with a call to setHTTPBasicAuthentication.
To avoid security exposures, never hardcode the user id and password into the
Rich UI application. Instead, the Rich UI application should display a user-defined
login screen to prompt the user for the values to pass to
setHTTPBasicAuthentication. Once you obtain the password, you can store it in
your Rich UI handler or a library for future Web service calls. Whenever you need
a different set of credentials to pass to a Web service, you must prompt the user
again.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
For JSF applications, each JSF handler is associated with a Faces JSP. The JSF
handler and EGL parts it references are generated into Java. Each JSP is generated
into its own file and has its own URL, which might need to be secured from
unauthenticated users using JEE security. When securing URLs, you can choose to
include some or all of the JSPs in your JSF application. Depending on your choices,
you can keep some JSPs in your JSF application public and restrict other JSPs to
authenticated users.
For Rich UI applications, EGL generates the contents of all the Rich UI handlers in
an application into JavaScript in a single HTML file. If your Rich UI application
calls EGL Web services, you must generate those services into Java because Web
services run on an application server, not in a Web browser. The HTML file that
EGL generates for a Rich UI application is associated with a single URL that can be
secured with JEE security. If you choose to secure a URL with JEE security, users
will be prompted to authenticate before they can access any part of your Rich UI
application. If you want to make some of the areas of your Rich UI application
public, you cannot use JEE authentication. Instead, use custom security to prompt
users to log in before they can access the restricted parts of your application.
Another major difference between JSF and Rich UI applications is that the EGL
Rich UI Proxy, which Rich UI applications use to call Web services, is not needed
by JSF applications because JSF handlers are generated into Java instead of
JavaScript.
Related concepts
“Using Web container-managed (JEE) authentication”
“Using application-managed (custom) authentication” on page 362
To secure the entire Rich UI application, the EGL Rich UI Proxy, and Web services,
you can use JEE security.
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.″
To secure all the resources that are in the WebContent folder of a deployed project,
specify /* as the URL pattern. Specifying /* as your URL pattern secures your
HTML page, EGL Rich UI Proxy, and SOAP and REST services.
Related concepts
“Overview of Rich UI security” on page 352
“Securing a Rich UI application” on page 352
“Using Web container-managed (JEE) authentication” on page 357
Related tasks
“Securing the HTML file by using form-based authentication” on page 359
“Securing the EGL Rich UI Proxy by using basic authentication” on page 359
“Removing access to the EGL Rich UI Proxy servlet” on page 360
For sample login and error pages that you can use with form-based authentication,
see ″Sample login and error pages for JEE form-based authentication.″
To secure the HTML file that EGL generates for a Rich UI application named
RSSReader, specify a URL pattern of /RSSReader.html. If RSSReader.html is in a
subdirectory of WebContent named Secured, specify a URL pattern of
/Secured/RSSReader.html.
When you use form-based authentication to secure the HTML file, include the EGL
Rich UI Proxy in the security constraint. To secure the EGL Rich UI Proxy, specify
a URL pattern of /___proxy (three underscores). By specifying this pattern, you
prevent unauthenticated users from accessing the proxy. After logging in, users
will gain access to the EGL Rich UI Proxy as well as the HTML file.
Related concepts
“Overview of Rich UI security” on page 352
“Securing a Rich UI application” on page 352
“Using Web container-managed (JEE) authentication” on page 357
Related tasks
“Defining URL patterns for Rich UI resources” on page 358
“Securing the EGL Rich UI Proxy by using basic authentication”
“Removing access to the EGL Rich UI Proxy servlet” on page 360
“Securing EGL Web services by using basic authentication” on page 361
To secure the EGL Rich UI Proxy, in a security constraint in your web.xml, specify
a URL pattern of /___proxy (three underscores).
By using JEE basic authentication, the Web server uses a browser-provided dialog
to collect a user id and password. This dialog looks like the following dialog for
Mozilla® Firefox® V2.0:
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
If you want to invoke Web services from your Rich UI application later, edit the
web.xml and add a servlet URL mapping into EGLRichUIProxy by using the URL
pattern /___proxy.
Related concepts
“Overview of Rich UI security” on page 352
“Securing a Rich UI application” on page 352
“Using Web container-managed (JEE) authentication” on page 357
Related tasks
“Defining URL patterns for Rich UI resources” on page 358
“Securing the HTML file by using form-based authentication” on page 359
“Securing the EGL Rich UI Proxy by using basic authentication” on page 359
“Securing EGL Web services by using basic authentication”
To secure all EGL SOAP services in a Web project, in a security constraint in the
web.xml, specify a URL pattern of /services/*. You can replace the asterisk with a
specific name to secure a specific SOAP service. To secure a specific function in a
SOAP service, specify the service and function name, as in /services/
accountService/checkBalance.
To secure all EGL REST services in a Web project, in a security constraint in the
web.xml, specify a URL pattern of /restservices/*. You can replace the asterisk
with a specific name to secure a specific REST service. To secure a specific function
in a REST service, specify the service and function name, as in
/restservices/accountService/checkBalance.
Related concepts
“Overview of Rich UI security” on page 352
“Securing a Rich UI application” on page 352
“Using Web container-managed (JEE) authentication” on page 357
Related tasks
When you use custom security, your Rich UI application must include a
user-defined login screen. To hide the password as it is being typed, use the
PasswordTextField widget in your Rich UI handler. Your Rich UI application can
require authentication to occur either at the beginning of the application or before
accessing a restricted area. You can integrate this form of security into the rest of
the application.
The first step in defining custom security is to determine which parts of the
application should be secured (that is, which parts can be accessed only after
logging in with a valid user id and password). Even if you are not using JEE
security protect to the HTML file, use JEE security to secure the EGL Rich UI
Proxy. This is an important factor to remember when you design your Rich UI
application. A design that uses EGL single sign-on will reduce the number of times
a user will have to authenticate.
When authenticating with custom security, use SSL to ensure that the user id and
password are secure during transmission between the browser and server. For an
introduction to SSL, see Overview of SSL.
Related concepts
“EGL single sign-on”
“Accessing user repositories” on page 364
“Adding a new user to a repository” on page 366
“Authentication summary” on page 367
By using EGL single sign-on, you can combine the following aspects of security
into a single step: authentication to your application (protected by custom security)
and authentication to the EGL Rich UI Proxy (protected by JEE security). You can
also include authentication to Web services.
Although the user registries that you use for authentication to the application, EGL
Rich UI Proxy, and Web services do not need to be the same, the user ID and
password used during EGL single sign-on must exist in all the relevant user
registries to prevent an authentication error.
For EGL single sign-on, the Rich UI application must define a login screen that
contains a user ID field, password field, and command button, as in the following
example:
useridLabel TextLabel { text = "User ID:", width = 80 };
useridField TextField { width = 100 };
useridBox Box { children = [ useridLabel,
useridField ], margin = 3 };
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.
If you use EGL single sign-on to authenticate to your application and to the EGL
Rich UI Proxy, authentication to the proxy occurs before authentication to your
application. Because the EGL Rich UI Proxy is secured using JEE basic
authentication, the Web container, not the application, handles login failures.
Because the Web container steps in, you can no longer authenticate in a single step.
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:
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
You can also use EGL code that is generated into Java and running on a server to
access an LDAP directory. To use EGL code to access an LDAP directory, define
either an EGL REST or SOAP service. The service can use EGL external types that
map to JNDI LDAP Java classes to access an LDAP directory. Here is an example
of EGL code that establishes a connection to an LDAP directory server:
// External types needed to access an LDAP directory server.
externalType ControlArray type JavaObject
{ JavaName = "Control[]", PackageName = "javax.naming.ldap" }
end
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
Note that the tighter your user registry is controlled, the tighter the security will be
of your Rich UI application and EGL Rich UI Proxy. Although securing your EGL
Rich UI Proxy with JEE security prevents unauthenticated users from accessing the
proxy, it does not prevent malicious authenticated users from using the proxy to
inflict damage. Therefore, when you require new users to go through a system
administrator, the EGL Rich UI Proxy will be more secure than if you allow the
application to add new entries to the user registry.
If you must add new users to a repository with your Rich UI application, you can
write EGL code to add the users. This code must run on an application server. You
can write the code as either a Web service or a JSF application.
If you use a Web service to write the code to add a new user, the EGL Rich UI
Proxy has to invoke the code. If the proxy is secure, a new user cannot access it.
Therefore, you can use a Web service to add a new user only if the proxy is not
protected by JEE security.
If you use JEE security to secure the proxy, you can use a JSF application to add a
new user to the repository. To link to a JSF application in a new window to update
the repository, the Rich UI handler can use a hyperlink widget that is similar to the
following example:
registerLink Hyperlink = new Hyperlink { target = "_blank",
href = "http://localhost:9080/LDAPSample/ldapLogin.faces",
text = "Click here to register" };
To close the window after authentication completes, the JSF page can invoke a
JavaScript ″window.close″.
Related concepts
Authentication summary
During the design phase of your Rich UI application, determine the type of
security that you need and integrate that security with the rest of your application.
If your entire Rich UI application needs to be secured and you do not need to
access security credentials from within the application, consider using JEE
authentication. Otherwise, you might need to implement custom security.
To secure the EGL Rich UI Proxy, use JEE security. If you use JEE form-based
authentication for your HTML file, include the URL pattern of the proxy in your
security constraint. Otherwise, use JEE basic authentication to secure the proxy. If
your application requires custom security or calls secure Web services, consider
using EGL single sign-on to eliminate the need for a user to log in more than once.
You can secure Web services using by JEE basic authentication and set a user id
and password in the HTTP header before invoking them by using the
ServiceLib.setHTTPBasicAuthentication system function.
Use SSL, described in Overview of SSL, to secure data transmitted to and from your
Rich UI application. Securing data is vital to keeping your passwords from being
compromised.
The following table summarizes the combinations of resources that you can secure
with JEE or custom authentication. For each of the eight scenarios (columns), an
″X″ represents a secure resource. These scenarios assume that the HTML file is
calling Web services. Otherwise, remove access to the EGL Rich UI Proxy by
deleting its URL mapping from the deployment descriptor. The safer scenarios are
identified with an ″*″.
Table 53. Authentication scenario
1 2 3* 4 5* 6* 7 8*
HTML x x x x
file
EGL x x x x
Rich UI
Proxy
Web x x x x
service
Scenario descriptions
1. In this scenario, the proxy is publicly accessible. If possible, do not implement
this scenario. Secure the proxy with JEE basic authentication (scenario 3).
2. Although the HTML file is secured with either JEE or custom security, the
proxy is still publicly accessible. If possible, do not implement this scenario.
Secure the proxy with JEE authentication (scenario 5).
3. In this scenario, the proxy is secured with JEE basic authentication. This
scenario is safer than the first two.
4. In this scenario, the proxy is publicly accessible. If possible, do not implement
this scenario. Secure the proxy with JEE authentication (scenario 6).
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.
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.
The Security Editor is used in this example because it provides an easy way to
specify and view security criteria.
You can use the Security Editor to define the following things in web.xml:
v Security roles
v Security constraints
v Authentication method
From the Project Explorer in the EGL Rich UI perspective, open the Security Editor
by double-clicking on the Security Editor icon of your deployed project.
In JEE role-based security, users must be assigned roles to access resources. Roles
are mapped to actual user registry entries.
v In the Create a Security Role dialog, click OK.
v In the Add Roles window, type user as the role name and click Add.
v Click Finish.
To specify the resources that are protected and the roles that have access to the
resources, define a security constraint.
1. In the Resources pane, expand the folder with your project name, Servlets,
EGLRichUIProxy, and Servlet Mappings. Under Servlet Mappings, you should
see /___proxy.
2. To secure the proxy and allow anyone in the user role to access the proxy, drag
the user role from the Security Roles pane to /___proxy in the Resources pane.
3. To see the security constraints, in the Resources pane, right click on /___proxy
(user) and click Assign Roles. In the Select Roles window, select user and click
Advanced>>>. You should see the userConstraint security constraint that is
mapped to user, which specifies how you can access the /___proxy secure
resource. The userConstraint security constraint contains the default HTTP
method access (GET, PUT, HEAD, TRACE, POST, DELETE, OPTIONS). Click
OK. To change the defaults for your security constraints, in the Security Editor,
click Security Preferences.
A user data constraint specifies how data is protected while it is in transit between
a client and server. If you do not want to use the default user data constraint
(NONE), you must specify the user data constraint directly into the web.xml
because that information is not available from the Security Editor.
The Security Editor is used in the following example because it provides an easy
way to specify and view security criteria.
To bind the roles that are defined in your web.xml to actual users and groups in
your user registry, use the Security Editor. This binding information is stored in the
deployment descriptor of your Enterprise Application project (application.xml).
To open the Security Editor from the Project Explorer in the EGL Rich UI
perspective, double-click on the Security Editor icon of your deployed project.
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
When the Web container receives a request for the j_security_check servlet, it
passes the request to the security mechanism of WebSphere Application Server to
perform the authentication. If authentication fails, the error page is displayed.
Below is code for a sample login page. Copy and save this code in login.jsp under
the WebContent folder.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Sample Login Page for JEE Security</title>
<style type="text/css">H1 {color: navy}</style>
</head>
<body>
<table width="500" border="0">
<tbody>
<tr>
<td colspan="3" width="80%" align="center"><b><font face="Verdana"size="+2"
color="#15406a">Sample Login</font></b><hr>
</td>
</tr>
<tr>
<td colspan="3" width="560" height="65">
<form method="POST" action="j_security_check">
<div>
<table width="100%" border="1" bgcolor="#e9e9e9">
<tbody>
<tr>
<td align="right" width="169"
bgcolor="#e9e9e9"><b>
<font face="Verdana">User id:</font></b></td>
<td width="315"><input type="text" name="j_username"></td>
</tr>
<tr>
<td align="right" width="169" bgcolor="#e9e9e9">
<font face="Verdana"><b>Password:</b></font></td>
<td width="315"><input type="password" name="j_password"></td>
</tr>
<tr bgcolor="white">
<td align="right" width="169" bgcolor="white"></td>
<td width="315"><input type="submit" value="Login"></td>
</tr>
</tbody>
</table>
</div>
</form></td>
</tr>
<tr>
<td colspan="3" width="560" align="center" height="58" valign="top">
<script> document.write(Date()+".")
</script>
</td>
</tr>
</tbody>
</table></body>
</html>
When you use EGL, you are protected from some of these client-side threats. For
example, EGL prevents malicious data being sent to the client using either
JavaScript Object Notation (JSON) or XML. It also guards its usage of ″eval″ in
runtime code. However, it is very difficult for EGL to defend against certain types
of attacks like cross-site scripting and SQL injection without limiting the types of
applications customers can write.
You can prevent unauthenticated clients from calling the proxy and reduce the
possibility of proxy misuse by securing the EGL Rich UI Proxy with JEE security.
However, securing the proxy with JEE security does not prevent authenticated
users from using the proxy for unintended purposes. The more tightly your user
registry is controlled, the safer your proxy will be. Therefore, for security reasons, a
system administrator should control the access of your user registry.
You can keep a log of the end users who have accessed your Rich UI application if
you are using your own login screen, rather than one supplied through JEE
form-based authentication or the browser-provided login dialog from JEE basic
authentication. (In your Rich UI application, you cannot retrieve user ids from the
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
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
Web service
Configuration
A Web service is secured by using JEE basic authentication and includes a
CONFIDENTIAL or INTEGRAL user data constraint.
Problem
HTTP is used to request the Web service instead of HTTPS.
Error A ServiceInvocationException is thrown with messageID ″CRRUI3655E″
and the message, ″An error occurred while processing response object:
‘ReferenceError: urlString is not defined’″. detail1 of the
ServiceInvocationException is set to ″302″; detail2 is set to ″Found″.
Solution
Request the Web service with HTTPS instead of HTTP.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
“Overview of SSL” on page 377
“SSL transport between WebSphere Application Server and LDAP” on page 386
“How SSL works” on page 380
Related tasks
“Using SSL with Rich UI applications” on page 377
“Preventing SSL handshaking exceptions” on page 385
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
“SSL terminology” on page 380
“SSL example” on page 381
A trust store is a file that contains public keys, which are stored as signer
certificates from target servers whom you have deemed trustworthy. If the target
uses a self-signed certificate, extract the public certificate from the server key store
and add the extracted certificate into the trust store as a signer certificate.
Otherwise, add the CA root certificate to your trust store.
A certificate is sent from the server to the client during SSL authentication to
confirm the identity of the server. Certificates contain data such as the owner’s
name and email address, duration of validity, web site address, and certificate ID
of the person who certifies or signs this information. Trusted parties called
Certificate Authorities (CAs) issue digital certificates. For internal Web sites that do
not need a CA certificate, you can use WebSphere Application Server to create
self-signed certificates.
In SSL server authentication, the client prompts the server to prove its identity. The
opposite occurs in client authentication, which is also supported through SSL, but
not covered here. Client authentication is used when the server needs to send
confidential financial information to a customer but wants to verify the identity of
the recipient first.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
“Overview of SSL” on page 377
“SSL transport between WebSphere Application Server and LDAP” on page 386
“How SSL works”
Related tasks
“Using SSL with Rich UI applications” on page 377
“Preventing SSL handshaking exceptions” on page 385
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
“SSL-related errors” on page 378
“SSL example” on page 381
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.
To create a sample SSL-enabled port, take the following steps. For more details, see
your WebSphere Application Server documentation.
A self-signed certificate is useful when you are testing or when your Web site is
behind a firewall. Otherwise, obtain a certificate from a Certificate Authority. To
create a personal certificate:
1. From your list of key stores and trust stores, click NodeDefaultKeyStore.
2. Under Additional Properties, click Personal certificates.
3. For WebSphere V6.1, click Create a self-signed certificate.
4. For WebSphere V7.0, click Create → Self-signed certificate.
5. Type the following values for the certificate:
Alias
SampleCert
Common name
Sample Server
Organization
IBM
6. Click OK.
Click OK, and click Save. In the list of SSL configurations, you should see
SampleConfig.
Create a Web container transport chain to use the SSL configuration that you
created:
1. For WebSphere V6.1, from the left-hand pane, expand Servers and click
Application servers.
2. For WebSphere V7.0, from the left-hand pane, expand Servers and Server
Types. Click WebSphere application servers.
3. Click server1 or your server name.
4. Under Container Settings, expand Web Container Settings and click Web
container transport chains.
5. Click New.
6. In the Transport chain name field, type SampleInboundSecure.
7. To select the Transport chain template, from the drop-down list, click
WebContainer-Secure(templates/chains | webcontainer-chains.xml#Chain_2).
8. Click Next.
9. In the Select a port page, type the following values:
Port
SamplePort
Host
*
Port number
9444
If port 9444 is already in use, pick another port number and use that
number for the rest of the exercise.
10. Click Next.
11. Click Finish → Save.
Stop and restart the server. Port 9444 is now an SSL-enabled port.
To use your port, start a WebSphere V6.1 or V7.0 server. On your WebSphere
server, install the EAR that contains your deployed Rich UI application. To request
an HTML file such as RSSReader.html in the RSSReaderSample context, take one of
the following steps:
v Open a browser such as Internet Explorer, Safari®, or Mozilla Firefox. Enter a
URL in your browser using the newly-enabled SSL port: https://localhost:9444/
RSSReaderSample/RSSReader.html
v In your Project Explorer, right-click on an HTML file of an application that has
been published to WebSphere. Click Run As, then click Run on Server.
If you are using a self-signed certificate, you might see a ″Security Alert″, ″Website
Certified by an Unknown Authority″, or another warning, depending upon the
browser. This warning indicates that the certificate was signed by an unknown
certifying authority. Click the ″View Certificate″ or ″Examine Certificate″ button to
verify if the certificate is correct. If so, continue.
If the Common Name on the certificate does not match the domain name in the
requested URL (localhost, in this case), you might also see a ″Security Error:
Domain Name Mismatch″ error. To verify the certificate, click the View Certificate
button, and continue as appropriate. To prevent ″man-in-the-middle″ attacks,
where a rogue program intercepts all communication between a client and server,
the client must verify the server domain name that is specified in the certificate.
Related concepts
“Overview of Rich UI security” on page 352
“Authentication and Authorization” on page 353
“Confidentiality and Integrity” on page 355
“Overview of SSL” on page 377
“SSL transport between WebSphere Application Server and LDAP” on page 386
“How SSL works” on page 380
Related tasks
“Using SSL with Rich UI applications” on page 377
“Preventing SSL handshaking exceptions” on page 385
“Starting to work with EGL Rich UI” on page 329
This topic tells how to start developing applications with EGL Rich UI.
Related reference
“SSL-related errors” on page 378
When a Web service is invoked from a Rich UI application, the EGL Rich UI Proxy
establishes a HTTP or HTTPS connection between the proxy and Web service. This
connection is independent of the connection between the browser and proxy. If the
Web service has an HTTPS protocol, the connection between the proxy and Web
service uses SSL. Because no browser is available to display a security alert and
prompt for a response, the certificate that belongs to the server of the Web service
must be in the trust store of the server of the EGL Rich UI Proxy before the
connection is initiated. Otherwise a handshaking error occurs.
To obtain a copy of the server’s certificate when calling a third-party Web service,
enter the URL of the Web service in a browser over HTTPS. The way in which you
receive the certificate of the server varies depending on the browser. A common
way is through a ″View Certificate″ button, Details tab, and ″Copy to File″ button.
Save the certificate to a file. Use the Administrative Console to open the trust store
of your EGL Rich UI Proxy and import the saved certificate as a signer certificate.
Alternatively, you can connect to the remote SSL host and port and receive the
signer certificate during the handshake by using the ″Retrieve from port″ option. If
you try to use the SSL-enabled port 9444 you created in ″SSL Example″ to request
a Web service called from an HTML file requested on the WebSphere default SSL
port 9443, you a handshaking error occurs. To fix this problem, import the
certificate that is associated with port 9444 into the trust store that is associated
with port 9443:
1. Start the WebSphere V6.1 or V7.0 server that contains your EGL Rich UI
Proxy. The proxy is deployed to the same location as the generated HTML file
of your Rich UI application.
2. Right click the server. Click Administration → Run administrative console.
3. Log in to the Administrative Console.
4. Expand Security and click SSL certificates and key management.
5. Under Related Items, click Key stores and certificates.
6. Click the appropriate trust store.
7. Click Signer certificates.
8. Click Retrieve from port.
9. Specify the following values:
Host
localhost
Port
9444
SSL configuration for outbound connection
NodeDefaultSSLSettings
Keystore name
SampleCert
10. Click Retrieve signer information → OK.
EGL also supports two other ways to write code for Web browsers:
v Rich UI applications
v Web transactions, which are available for compatibility with previous versions of
EGL
Related concepts
“Elements of a JSF Web application”
The main elements of an EGL Web application are the Web pages themselves
and JSF Handlers, which are logic parts that control the Web pages.
“Binding JSF controls to EGL variables and functions” on page 394
When you have a JSP file and an associated JSF Handler part, you can begin
developing the Web page’s behavior. This means binding, or connecting,
elements on the Web page to variables and functions in the JSF Handler.
“Overview of EGL Rich UI” on page 327
Related reference
“Working with Web transaction applications in EGL” on page 561
Related reference
Web pages with JavaServer Faces
A JSF Handler part, also called a JSF Handler, is a logic part that is customized to
control a Web page at run time. In prior versions of EGL, JSF Handlers were
PageHandler parts and referred to generally as page handlers.
Like other types of logic part, JSF Handler parts can contain any number of
user-defined functions. You might use functions in a JSF Handler to validate or
change the data that a user types into a Web page, to assign values to fields in a
Web page, to respond to a user’s actions on the page, or to forward the user or
data to a different page. However, it is best to keep JSF Handlers as simple as
possible and to use libraries or services for complicated business logic, because
functions in a JSFHandler part behave as though they are private and are not
available to other EGL logic parts or other JSF Handlers.
JSF Handler parts also contain specialized functions that run automatically at
certain points in the life of a Web page. For more information, see “Executing
commands when a page loads” on page 411.
You can also make variables and functions that are defined in the JSF Handler
available to the Web page. In this case, you bind the variable to an input or output
Generally, there is a one-to-one relationship between JSF Handlers and Web pages.
See JSF Handler part for more information about JSF Handler parts.
The Java Server Pages (JSP) files in an EGL Web project are the files that most
resemble the Web pages that a user will actually see in the browser. In Web terms,
these files create the view portion of a Web application. JSP files contain all the text,
tables, and other elements that are commonly seen on Web pages, plus dynamic
areas that can change at run time based on the logic in the JSF Handler. For these
dynamic areas, EGL Web applications use JavaServer Faces (JSF), a technology that
includes reusable user interface components, such as command buttons, links,
input fields, and output fields. In EGL Web applications, you add JSF components
to your JSP files and refer to those JSF components in your JSF Handler code.
For more information on JSP files, see JavaServer Pages (JSP) technology. For more
information on JSF technology, see JavaServer Faces (JSF) overview.
The JavaServer Faces (JSF) configuration file contains information for your pages
and for the JSF components on those pages. In general you will not need to edit
the JSF configuration file yourself, but you should be aware of the information
stored in the file and how it affects your EGL pages. For example, the JSF
configuration file contains navigation rules, or navigation aliases for your pages.
EGL uses these aliases with the forward statement to allow your JSF Handlers to
forward the user from one page to another. See “Navigating among Web pages
with navigation rules” on page 408.
The Web deployment descriptor, not to be confused with the EGL deployment
descriptor, provides deployment information
The Web deployment descriptor is visible in your EGL Web project in two places:
v As the web.xml file, located in the project’s WebContent/WEB_INF folder by
default.
v As the Deployment Descriptor file at the root of your project, visible only in the
Project Explorer view.
These references point to the same file.
For more information on the Web deployment descriptor, see Configuring Web
applications using the Web deployment descriptor editor.
By default, all Web projects in the workbench, including EGL Web projects, contain
a Web Site Navigation file. This file is labeled Web Site Navigation in the Project
Explorer view and named .website-config in the Navigator view. The Web Site
Navigation file allows you to plan your Web application with a map of the pages
and the relationships between them. For more information, see Designing Web
sites.For more information, see ″Designing Web sites″ in the online help.
Web diagrams
By default, all Web projects in the workbench, including EGL Web projects, contain
a Web diagram. EGL does not support Web diagrams. Use the Web Site Navigation
file instead. For information on working with Web diagrams, see Web diagrams
and the Web diagram editor.
Like other Web projects, an EGL Web application can contain files that are used to
control the runtime appearance and behavior of Web pages, including images,
Cascading Style Sheet (CSS) files, and JavaScript files. For more information about
using style sheet files, see Defining styles. For more information about using
JavaScript, see Adding code to Web pages.
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.
When you create a Web page to be used with EGL, be sure to select the correct
type of Web page:
1. Click File → New → Other. The New window opens.
2. Expand Web and click Web page (not JSP).
3. Click Next.
4. In the File Name field, type the name for the new Web page. The
accompanying JSF Handler will have the same name with an .egl extension.
5. In the Folder field, select the location for the new Web page. The location must
be in the WebContent folder of an EGL Web project. The accompanying JSF
Handler will be put into the project’s jsfhandlers package unless you specified
a different package in the workbench preferences.
6. Optionally, select a template that is compatible with JSP files in the Template
box. If you don’t select a template, the new Web page will be an empty JSP file
with no template.
v For a blank Web page, click Basic Templates → JSP.
v For a Web page with placeholders for graphics and navigation elements that
are linked to a page template, expand Sample Templates and select a
template.
v To use a template that is already in your project, click My Templates and
choose the template from the Preview box.
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.
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.
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
The specific steps involved depend on the complexity of the Web page and of the
related EGL parts:
v You can bind a button on the page to a function in the JSF Handler so that when
the user clicks the button, the associated function in the JSF Handler runs. See
“Binding a JSF button to a function” on page 395.
v You can bind input and output controls on the Web page to variables in the JSF
Handler so that when the value changes on the page, the value of the associated
variable changes to match and when the value of the variable changes in the JSF
Handler, that value displayed on the page changes. See “Binding a control on a
Web page to a variable” on page 397.
v You can bind variables in the JSF Handler to a JSF single-select control, such as a
combo box or list box. See “Binding a JSF single-select control to a variable” on
page 401.
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
When you bind a JSF button to a function in the JSF Handler, the function runs
when the user clicks the button.
The easiest way to accept a command from a Web page is to write the function
first and then bind it to the button:
1. Create a Web page in an EGL Web project.
2. In the page’s JSF Handler, create a function. At this point, you only need the
basics of the function to do the binding; you can code the logic for the function
later.
3. Save the JSF Handler.
4. Open the associated JSP file.
Alternatively, you can code the function from the Quick Edit view while working
on the Web page:
1. Open the JSP file.
2. From the Enhanced Faces Components drawer of the Palette view, drag a
Button - Command onto the page.
3. Right-click the button and then click Edit Events. The Quick Edit view opens.
Typically, this view is for JavaScript code, but you can use it to write functions
in the JSF Handler as well.
4. In the Quick Edit view, click Command at the left side of the view.
5. Click on the right area of the Quick Edit view to set focus there. The view
shows a new EGL function that is actually in the JSF Handler.
6. Type your EGL statements in the new function. You must at least add a
comment in the function in the Quick Edit view. If you do not change the code
in the function, the editor assumes that the function is not needed and removes
it.
Limitations
Command elements on the page can be bound only to functions in the JSF
Handler, not functions in other logic parts such as libraries. Also, you can bind
only functions with no parameters. If the function needs input to run, create a
variable in the JSF Handler and bind it to an input control on the page. Then, you
can use that variable as a parameter in a function invocation.
Also, see “Binding a control on a Web page to a variable” on page 397 for a
limitation having to do with the location of buttons and controls within a <form>
tag.
Related concepts
“Building EGL JSF Web applications” on page 389
In an EGL JSF Web application, EGL logic parts control Web pages, enabling
you to put data on Web pages, get data from user input on Web pages, and
forward users from page to page.
Related tasks
“Binding JSF controls to EGL variables and functions” on page 394
When you have a JSP file and an associated JSF Handler part, you can begin
developing the Web page’s behavior. This means binding, or connecting,
elements on the Web page to variables and functions in the JSF Handler.
“Binding a control on a Web page to a variable” on page 397
You can bind a variable in the JSF Handler to an input or output control on the
Web page. When a variable is bound to a control on the page and the user
changes the value in the control, the value of the variable changes to match,
and if the logic in the JSF Handler changes the value of the variable, the value
on the page changes to match.
You can bind a variable in the JSF Handler to an input or output control on the
Web page. When a variable is bound to a control on the page and the user changes
the value in the control, the value of the variable changes to match, and if the logic
in the JSF Handler changes the value of the variable, the value on the page
changes to match.
There are several ways to bind Web page controls to EGL variables:
v Create the controls automatically from existing EGL variables.
v Create the controls yourself and explicitly bind variables to those controls.
v Create both the controls and the variables at the same time.
With this method, you create variables in the JSF Handler and then allow EGL to
create appropriate representations on the page.
1. Open the JSF Handler that is associated with the Web page. If you are looking
at the JSP file in the editor, you can open its JSF Handler by right-clicking the
page and then clicking Edit page code.
2. In the JSF Handler, define one or more EGL primitives, data items, or record
variables, and save the file. To be used on the Web page, the variables must be
directly within the JSF Handler part and not within any function in the part.
3. Open the JSP file.
4. In the Page Data view, expand JSF Handler. The variables that are defined in
the JSF Handler are listed here.
5. Drag the variable from the Page Data view directly onto the Web page.
Depending on the type of variable that you drag, the Insert Control or Insert
List Control window opens.
6. Click a radio button under Create controls for:
v If you want read-only output controls, select Displaying an existing record.
v If you want editable input controls, select Updating an existing record or
Creating a new record. In this context, the two options are equivalent.
This wizard treats all EGL variables as if they were records.
7. If you selected a record variable or more than one variable, select the check
boxes next to the controls or variables that you want to display. You can also
choose a type of control to represent the controls or variables from the Control
type column.
8. Click Finish.
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.
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:
Limitations
Binding controls to variables has limitations because of the way Web pages behave.
One major limitation is that the JSF Handler receives only the changed variables
from the form that is submitted on the Web page.
For example, assume the following JSF Handler with two variables and one
function:
handler formTestPage type JSFHandler
{view = "formTestPage.jsp"}
stringOne string;
stringTwo string;
function doSomething()
SysLib.writeStderr("stringOne = " + stringOne);
SysLib.writeStderr("stringTwo = " + stringTwo);
end
end
If you bind the function to a button and the variables to two input controls, you
can type values into the controls, press the button, and see the values that you
typed written to the console.
This example assumes that you have placed the button and controls in the same
HTML form. The code of the body of the Web page might look like this:
<body>
<hx:scriptCollector id="scriptCollector1"
preRender="#{formTestPage._preRender}"
postRender="#{formTestPage._postRender}">
</h:form>
</hx:scriptCollector>
</body>
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:form>
</hx:scriptCollector>
</body>
In this case, the first input control is outside the form, but the second input control
and the button are within the form. When you click the button now, the JSF
Handler receives only the second control, and the variable bound to the first
control is not changed.
Related concepts
“Building EGL JSF Web applications” on page 389
In an EGL JSF Web application, EGL logic parts control Web pages, enabling
you to put data on Web pages, get data from user input on Web pages, and
forward users from page to page.
Related tasks
“Binding JSF controls to EGL variables and functions” on page 394
When you have a JSP file and an associated JSF Handler part, you can begin
developing the Web page’s behavior. This means binding, or connecting,
elements on the Web page to variables and functions in the JSF Handler.
“Binding a JSF button to a function” on page 395
When you bind a JSF button to a function in the JSF Handler, the function runs
when the user clicks the button.
“Binding a JSF single-select control to a variable” on page 401
Binding a JSF single-select control, such as a combo box or group of radio
buttons, to an EGL variable is more complicated than binding an input or
output control because you must use two EGL variables: one for the options in
the control and one for the selected value.
“Returning the indexes of selected rows in a data table” on page 404
Binding a JSF single-select control, such as a combo box or group of radio buttons,
to an EGL variable is more complicated than binding an input or output control
because you must use two EGL variables: one for the options in the control and
one for the selected value.
In general, you need to create an array that represents the options in the control, as
well as a single variable to hold the value of the selected option. The simplest way
to do this is by defining an array of strings and populating the array with the
options for the control. See ″Using an array of STRING as the selection options.″
Alternatively, you can use an array of records as the options for the control by
specifying fields in the record as the option that is displayed in the control and as
the value for the selection. See ″Using an array of records as the selection options.″
You can check which variables the JSF control is bound to by clicking the control
to select it and then opening the Properties view. In the Properties view, the Value
field represents the variable that will receive the value of the selected option, and
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.
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.
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:
The type of this variable must match the type of the field marked as
valueItem in the Record part.
5. Indicate that the single variable will receive the option that is selected from
the list of options by adding the SelectedValueItem property to the list of
options:
selectionOptions optionsRec[3]
{selectedValueItem = selectedChoice};
6. Save and generate the JSF Handler.
7. On the page that is associated with the JSF Handler, drag the variable that
represents the list of selection options (in this case, selectionOptions from the
Page Data view onto the page. The Insert List Control window opens.
8. In the Insert List Control window, click Displaying an existing record.
9. Under Control Type, select the type of single-select JSF control to put on the
page.
You can choose from Combobox (also called a list or drop-down box), List
Box - single select, or Radio Button Group. In each case, the options will be
added dynamically depending on the number of elements in the list of
selection options at run time.
10. Click Finish. The control is added to your page and it is automatically bound
to the variables in the JSF Handler.
You can check which variables the JSF control is bound to by clicking the control
to select it and then opening the Properties view. In the Properties view, the Value
field represents the variable that will receive the value of the selected option, and
the table of variables at the right side of the view lists the variable or variables that
are used to provide the options for the control.
This is a complete example of a JSF Handler that uses a single-select control in this
way:
handler singleSelect type JSFHandler
{view = "singleSelect.jsp",
onPreRenderFunction = onPreRender}
selectionOptions optionsRec[3]
{selectedValueItem = selectedChoice};
selectedChoice string;
outputMessage string;
function onPreRender()
selectionOptions[1].displayOption = "Option one";
selectionOptions[1].optionValue = "first option";
selectionOptions[2].displayOption = "Option two";
selectionOptions[2].optionValue = "second option";
selectionOptions[3].displayOption = "Option three";
selectionOptions[3].optionValue = "third option";
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 that is based on
this variable. You also need to bind the outputMessage variable to an output
control and the getChoice function to a button on the page. When you click the
button, the output control displays the text of the option that you selected in the
JSF single-select control.
Related concepts
“Building EGL JSF Web applications” on page 389
In an EGL JSF Web application, EGL logic parts control Web pages, enabling
you to put data on Web pages, get data from user input on Web pages, and
forward users from page to page.
Related tasks
“Binding JSF controls to EGL variables and functions” on page 394
When you have a JSP file and an associated JSF Handler part, you can begin
developing the Web page’s behavior. This means binding, or connecting,
elements on the Web page to variables and functions in the JSF Handler.
“Binding a JSF button to a function” on page 395
When you bind a JSF button to a function in the JSF Handler, the function runs
when the user clicks the button.
“Binding a control on a Web page to a variable” on page 397
You can bind a variable in the JSF Handler to an input or output control on the
Web page. When a variable is bound to a control on the page and the user
changes the value in the control, the value of the variable changes to match,
and if the logic in the JSF Handler changes the value of the variable, the value
on the page changes to match.
“Returning the indexes of selected rows in a data table”
“Binding JSF controls to services” on page 407
Binding functions and variables from a service to controls on a Web page is no
different from binding any other type of functions and variables, but EGL
provides shortcuts for working with service controls in this way.
Related reference
selectFromListItem
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.
In this way, to be able to select multiple rows in a JSF data table, you need two
arrays:
v An array of records that will be the data in the table
v An array of integers to hold the indexes of the selected records
Follow these steps to set up a data table with a multiple selection column. This
example displays a list of customers and their total purchases and enables you to
select one or more rows to add together:
1. In the JSF Handler for an EGL-controlled Web page, create an array of records
to represent the table of data you want shown on the page:
purchaseList customerPurchase[3];
For example, this JSF Handler uses a selection column in this way:
handler multiSelectPage type JSFHandler
{onPreRenderFunction = onPreRender,
view = "multiSelectPage.jsp"}
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
This example assumes that you have dragged the purchaseList array onto the
page to make a JSF data table and that you have bound the sumRows function and
purchaseSum variable to a command button and output control on the Web page,
respectively.
Related concepts
“Building EGL JSF Web applications” on page 389
In an EGL JSF Web application, EGL logic parts control Web pages, enabling
you to put data on Web pages, get data from user input on Web pages, and
forward users from page to page.
Related tasks
“Binding JSF controls to EGL variables and functions” on page 394
When you have a JSP file and an associated JSF Handler part, you can begin
developing the Web page’s behavior. This means binding, or connecting,
elements on the Web page to variables and functions in the JSF Handler.
The controls for input and output and buttons to invoke the function are added to
the page and bound to the corresponding variables and functions in the JSF
Handler.
Related concepts
“Building EGL JSF Web applications” on page 389
In an EGL JSF Web application, EGL logic parts control Web pages, enabling
you to put data on Web pages, get data from user input on Web pages, and
forward users from page to page.
Related tasks
“Binding JSF controls to EGL variables and functions” on page 394
When you have a JSP file and an associated JSF Handler part, you can begin
developing the Web page’s behavior. This means binding, or connecting,
elements on the Web page to variables and functions in the JSF Handler.
“Binding a JSF button to a function” on page 395
When you bind a JSF button to a function in the JSF Handler, the function runs
when the user clicks the button.
“Binding a control on a Web page to a variable” on page 397
You can bind a variable in the JSF Handler to an input or output control on the
Web page. When a variable is bound to a control on the page and the user
changes the value in the control, the value of the variable changes to match,
and if the logic in the JSF Handler changes the value of the variable, the value
on the page changes to match.
“Binding a JSF single-select control to a variable” on page 401
Binding a JSF single-select control, such as a combo box or group of radio
buttons, to an EGL variable is more complicated than binding an input or
output control because you must use two EGL variables: one for the options in
the control and one for the selected value.
“Returning the indexes of selected rows in a data table” on page 404
Related reference
selectFromListItem
EGL provides two ways to navigate to another page: forward to URL and forward
to label, the default. When using forward to URL, you specify an absolute or
relative URL to the target page; when using forward to label, you specify a
navigation rule that in turn points to the target page. When navigating among pages
in an EGL applications, use forward to label; when navigating to a Web page in a
different application, use forward to URL.
Forwarding to a label
When navigating from page to page within an EGL application, use forward to
label. To forward the user from one page to another, you must know the name of
the JSF navigation rule that points to the target page. By default, the name of the
navigation rule that points to a page is the same as the name of the JSF Handler
that manages that page.
For example, a page named myPage.jsp might have a JSF Handler named myPage
in a file named myPage.egl. By default, the navigation rule for this page is myPage.
When you know the navigation rule of the target page, you can use the EGL
forward statement to send the user’s Web browser to that target page. In this case,
to forward to the page myPage.jsp, use the following code:
forward to label "myPage";
To find the navigation rule that points to a page, look in the faces-config.xml file,
which is in the WebContent/WEB-INF folder of your EGL Web project. This file lists
the rules and the pages to which those rules lead. The previous example used a
navigation rule that looks like this:
<navigation-case>
<from-outcome>myPage</from-outcome>
<to-view-id>/myPage.jsp</to-view-id>
</navigation-case>
The navigation rule contains two strings: a label for the rule and a relative link to
the target page. In this case, the label is myPage and the link refers to a page named
myPage.jsp in the same directory as the page that used the navigation rule. Note
the beginning slash before the file name of the page, which is a requirement for the
navigation rule. This navigation rule will result in a JSF forward as described
above.
To navigate to a page in a different EGL Web project, use a relative URL reference.
For example, to link from the page myProject01/myPage01.jsp to a file named
myPage02.jsp in a project named myProject02, use the following navigation rule:
<navigation-case>
<from-outcome>myPage02</from-outcome>
<to-view-id>/../myProject02/myPage02.jsp</to-view-id>
<redirect/>
</navigation-case>
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";
See “Navigating among Web pages with navigation rules” on page 408 for
information on forwarding to a different Web page.
end
If you define more than one of these JSF Handler properties, the specified
functions must have matching parameters because all functions receive the
passed data. However, you can leave the parameters out of the functions if you
do not plan to use the passed data in that function.
2. In the page that forwards the data, use a forward statement and include the
data in the same order as the functions that will accept it:
410 EGL Programmer’s Guide
myInteger int = 5;
myChar char(100) = "Hello";
forward myInteger, myChar to "myPage";
The variables must be separated by commas, and their types must be
compatible with the types defined in the functions of the target page.
Related reference
“Navigating among Web pages with navigation rules” on page 408
A JSF Handler can control the navigation on a Web site, forwarding the user
from one page to another and passing data between pages. EGL works closely
with JavaServer Faces (JSF) navigation functionality to control page navigation
in this way.
“Executing commands when a page loads”
A JSF Handler can include functions that run automatically when the page
loads.
JSF Handler part
forward
When these functions run depends on the value of the scope property of the page.
When the user visits an EGL-controlled Web page for the first time, EGL loads the
JSF Handler, which is represented at run time by a page bean. If the scope of the
page is set to session (the default), the bean remains active during the user’s
session, even if the user browses away from the page. If the user returns to the
page, the bean is still available. If the scope of the page is set to request, the bean
does not remain active when the user browses away from the page. In this case,
any data stored in the bean is lost, and the bean must be loaded again if the user
returns to the page.
v The function that is specified in the onConstructionFunction property runs
when the page bean is loaded. Therefore, for pages set to session scope, this
function runs only the first time that the user visits the page. For pages set to
request scope, this function runs each time the user visits the page, because the
bean is recreated each time, except when the page is redisplayed due to a JSF
validation error.
However, if the cancelOnPageTransition property of the JSF Handler is set to
yes, the page bean is removed from the session when the user moves to another
page, even if the scope property is set to session. In this case, the
onConstructionFunction runs again when the user returns to the page because
the page bean must be reloaded.
This function is useful for one-time initialization tasks. You should not use
onConstructionFunction to retrieve session variables or other data that may
change and need to be loaded again when the page is refreshed. Use
onPreRenderFunction instead. See onConstructionFunction for more information
on this property.
v The function that is specified in the onPreRenderFunction property is not
affected by the scope of the page. This function runs each time the server begins
rendering the page, whether the bean was in the user’s session or not. In this
way, the onPreRenderFunction runs the first time the page bean is loaded,
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;
numberOfLoads int;
messageString string;
function onConstruction()
numberOfLoads = 0;
end
function forwardBack()
forward numberOfLoads to "loadTest";
end
end
4. Save the JSF Handler and close it.
5. On the loadTest.jsp page, add an Output field from the Enhanced Faces
Components drawer of the Palette view.
6. Next to the output field, add a Button - Command from the Enhanced Faces
Components drawer of the Palette view.
7. From the Page Data view, drag messageString directly onto the output field.
Now the variable in the JSF Handler is bound to the output field on the page.
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.
EGL can obtain the options for the type-ahead input field in one of three ways:
v EGL can compare what the user has typed with the values in the validValues
property for the variable bound to the control. In this case, the type-ahead
feature presents all of the values in the list of valid values that start with the
same characters as the user has typed.
v EGL can compare what the user has typed with the values in a DataTable part
specified in a variable’s validatorDataTable property. This method works just
like the validValues method.
v You can define a custom function to assemble an array of options to present to
the user. Typically, type-ahead presents options that have the same starting
characters as the characters that the user has already typed in, but in this case,
the function can return an arbitrary array of options.
The steps for using type-ahead depend on which of these methods you use to
obtain the list of options.
The simplest way to provide options for the type-ahead function is to associate the
variable bound to the field with a list of options, either in a Data Table or in a list
of valid values.
1. In a JSF Handler part, create a character or numeric variable to represent the
value typed in the input field on the page:
state STRING;
2. On the variable, set the typeahead property to YES:
state STRING {typeahead = YES};
3. Associate the variable with a list of options, using either the validValues or
validatorDataTable properties:
v If you use validValues, specify the options as the values of the property:
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;
3 abbrev char(2);
{contents = [
["AK"],["AL"],["AR"],["AZ"],
["NC"],["NY"],["NH"],["NJ"],
["NM"],["NE"],["NV"],["ND"]
]}
end
For more control over the options presented in type-ahead, you can create a
function that dynamically determines the options at run time.
1. In a JSF Handler or a Library part, create the function that determines the
type-ahead options. This function must accept exactly one parameter: a
STRING, representing the text that the user has typed into the input control.
Also, the function must return an array of STRING, representing the
type-ahead options presented in the input control.
// Return any state names for which
//the key is a substring of the full state name.
function getStateChoices( key string in ) returns( string[] )
results string[0];
key_upper string = strlib.upperCase( key );
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;
3 fullname char(20);
{contents = [
["ALASKA"],
["ALABAMA"],
["ARKANSAS"],
["ARIZONA"],
["NORTH CAROLINA"],
["NORTH DAKOTA"],
["NEBRASKA"],
["NEW HAMPSHIRE"],
["NEW JERSEY"],
["NEW MEXICO"],
["NEVADA"],
["NEW YORK"]
]}
end
2. In a JSF Handler part, create a character or numeric variable to represent the
value typed in the input field on the page:
state STRING;
3. On the variable, set the typeaheadFunction property to the name of the
function:
state STRING {typeaheadFunction = getStateChoices};
4. On the Web page, drag the variable from the Page Data view onto the Web
page. The Insert Record window opens.
5. In the Insert Record window, click Updating an existing record.
You can customize the appearance and behavior of the type-ahead functionality on
the page. To set these options, follow these steps:
1. On the Web page, click the type-ahead icon to select it. The type-ahead icon is
located immediately to the right of the input control on which type-ahead is
enabled.
2. With the type-ahead icon selected, open the Properties view.
3. In the Properties view, set the options for the type-ahead feature. You can set
the size of the type-ahead field, how long the control should wait before
providing options, and how the input control should behave while waiting for
EGL to return the options. For more information on the options associated with
type-ahead, see Typeahead Complete Component.
Related reference
validValues
validatorDataTable
typeahead
typeaheadFunction
This snippet must be placed in an EGL JSF Handler part. This snippet has the
following prerequisites:
1. The JSP page has a data table.
2. The names of the JSP identifiers have not been changed from the default.
3. The page is defined as request in scope in faces-config.xml, not session.
To insert and configure this snippet, follow these directions:
1. In a JSF Handler, define a character or string variable to receive the clicked
value.
2. Place the cursor on a blank line in the JSF Handler where it is legal to add a
function. (This snippet includes an entire EGL function.)
</script>
2. From the EGL drawer of the Snippets view, drag the Set cursor focus snippet
to a blank line within the <script> tag you just added. For more information,
see Inserting code snippets into EGL and JSP files. This snippet goes into the code
of the JSP file, not the code of the JSF Handler part.
3. In the snippet code, replace both instances of [n] with the number of the form
field which will receive focus. The form fields are numbered beginning with
zero. For example, use [3] to set focus to the fourth field on the page.
A JSF Handler can set the value of error message components in these ways:
v The sysLib.setError system function sets the message of a display error
component, given the name of a variable that is bound to an input component
on the page. In other words, you pass the name of an EGL variable in the JSF
Handler to the function, and JSF finds the display error component that is
associated with an input component on the page, which in turn to that specified
EGL variable.
v The sysLib.setErrorForComponentID function sets the message of a display
error component, given the ID of an input component on the page. JSF shows
the error message in the display error component associated with the specified
input component.
Follow these steps to display an error message on a Web page with EGL:
<h:message id="message1"
styleClass="message"
for="inputComponent">
</h:message>
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 EGL Programmer’s Guide
setError()
setErrorForComponentID()
msgResource
Web applications often store these details in the user’s session object, an area of
memory on the server that stores temporary information about one user’s
transactions and interaction with the Web application. The data in the session
object is not as stable as data stored in a database because the session object is lost
if the session ends. Still, putting data in the session object is useful in the short
term if done efficiently.
When a user visits an EGL-controlled Web page, the server loads the page’s JSF
Handler, represented at run time as a page bean, stores that bean in the session
object as a session variable, and uses that bean to provide the logic for the page. If
the scope property of the JSF Handler is set to session and its
cancelOnPageTransition property is set to no, the bean remains in the session
object until the session ends or the bean times out. In this way, variables in the
Handler can retain their values during the session, even if the user moves to
another page.
However, page beans can take up large amounts of memory. A much more efficient
way to use the session object (and, in turn, server resources) is to store the user’s
information in your own smaller session variables and then remove the beans from
the session object by setting the scope of the JSF Handlers to request or
cancelOnPageTransition to yes. In this way, you retain only the data the
application needs, not all the variables in its Handlers.
To set a session variable, pass a string identifier and an EGL variable to the session
object:
myVar string = "Hello";
J2EELib.setSessionAttr("mySessionVar", myVar);
To retrieve the value later, use the J2EELib.getSessionAttr system function with
the same identifier and a new variable:
myVarFromSession string;
J2EELib.getSessionAttr("mySessionVar", myVarFromSession);
A more complete example of two JSF Handlers that set and retrieve a session
variable follows. The first Handler sets the session variable:
package jsfhandlers;
userRecord sessionRecord;
function storeAndForward()
J2EELib.setSessionAttr("mySessionRecord",
userRecord);
forward to "sessionPageTwo";
end
This example assumes a Web page named sessionPageOne.jsp with two input
fields bound to the fields in the record, along with a command button bound to
the storeAndForward function. When the user clicks the button bound to the
storeAndForward function, the record is added to the user’s session variable, and
the user is forwarded to another page, represented by the following JSF Handler:
package jsfhandlers;
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.
You can remove a single session variable from the session object by passing the
string identifier of the variable to the J2EELib.clearSessionAttr function:
J2EELib.clearSessionAttr("mySessionRecord");
Also, you can remove all EGL-controlled session variables from the user’s session
object with the J2EELib.clearEGLSessionAttrs function.
For more information on session-related functions, see ″EGL library j2eeLib″ in the
EGL Language Reference.
Related reference
EGL library j2eeLib
The snippet must be placed within the <head> tag of a JSP page after the
<pageEncoding> tag.
You can use translatable strings as the text on Web pages. The sections below cover
some different uses of these strings on web pages. Also, you can use translatable
strings as the error messages for Web pages; see “Displaying error messages on
Web pages” on page 419.
To use a translatable string as the value of a JSF field, such as an output field, you
cannot assign the key of the translatable string to an EGL variable bound to the
field. To use a translatable string as the value of a JSF field, you cannot bind that
field to an EGL variable at all. Instead, you must bind the field to the translatable
string directly, as in these steps:
You can also use translatable strings as the values of certain EGL properties, most
notably DisplayName:
1. In the jsfhandlers package of your project’s Java Resources folder, create a
resource bundle to hold the strings that you want to use in the application. See
“Creating a resource bundle” on page 430. For example, if you are using
American English, you might create a resource bundle named
myBundle_en_US.properties.
2. In the resource bundle, add keys and string values for the text that you want to
use on the Web pages, as in this example:
myString01=Hello there!
myString02=Welcome to my Web page.
3. Set your workbench preferences to use a default mnemonic to represent the
resource bundle:
a. Click Window → Preferences.
b. In the Preferences window, expand EGL and click Page Designer.
c. In the Loadbundle variable field, type a mnemonic for the translatable
strings. By default, this mnemonic is labels, but if you change it, it must
match the mnemonic that is used in the File identifier field in the
Choose/Create Properties File window as explained earlier.
d. Click OK.
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.
</locale-config>
...
</application
</faces-config>
4. Within the <locale-config> tag, add a <default-locale> tag that contains the
locale of the default resource bundle. For example, if you want your application
to appear in German if the user does not specify a locale or specifies a locale
that you application does not support, add the following code within the
<locale-config> tag:
<default-locale>de</default-locale>
It is good practice to specify a default locale, but it is not required.
5. Following the <default-locale> tag, add a <supported-locale> tag for each
locale that your application supports. For example, if your application supports
American English, add the following code within the <locale-config> tag:
<supported-locale>en_US</supported-locale>
Following is an example from an application that supports several locales:
<faces-config>
<application>
<locale-config>
<default-locale>de</default-locale>
<supported-locale>en_US</supported-locale>
<supported-locale>es</supported-locale>
<supported-locale>de</supported-locale>
<supported-locale>fr_FR</supported-locale>
<supported-locale>it_IT</supported-locale>
<supported-locale>pt_br</supported-locale>
</locale-config>
...
</application>
</faces-config>
If you define a default locale, you must also define that locale as a supported
locale.
Note: Each locale that is defined in this file must have a matching resource
bundle defined for that locale.
6. Save and close the file.
7. Test your application with your Web browser set to different languages to see
the different strings.
Related concepts
“Locales for resource bundles” on page 431
Related tasks
“Customizing runtime messages” on page 152
“Creating a resource bundle” on page 430
Related reference
displayName
help
Each resource bundle must define a string for each key that is used in the
application. If a Web page lists a key and the resource bundle for the current user’s
language does not define a string for that key, a fatal error will be generated.
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
Locales consist of one to three identifiers. Each additional identifier after the first
identifier enables you to indicate a more specific language by specifying the
dialect, variety, or geographic location of the language. The identifiers are
separated with an underscore character.
The simplest locales indicate a human language with a single identifier. This
identifier is the language code of the language that is used in the resource bundle.
For example, the language code en indicates English, and es indicates Spanish. An
English resource bundle might be named resourceBundle_en.properties. The
language code is part of the Java specification.
A more complex locale includes a language code followed by a country code. The
country code indicates a country where the dialect of the language is spoken. For
example, the country code US indicates the United States, and GB indicates Great
Britain. In this way, an American English resource bundle might be named
resourceBundle_en_US.properties, while a British English resource bundle might
be named resourceBundle_en_GB.properties. The country code is part of the Java
specification.
The most complex locale includes a language code, followed by a country code,
followed by a variant code. The variant code defines a more specific dialect or
variety of the language in the resource bundle. For example, you could use the
variant codes A and B to distinguish between two different varieties of Norwegian
spoken in Norway. These two resource bundles might be named
resourceBundle_no_NO_A.properties and resourceBundle_no_NO_B.properties.
Alternately, you could define a standard type of Norwegian as the locale no_NO and
define a variant as no_NO_B. The variant code is not part of the Java specification.
If the user requests a locale that exactly matches a locale in the application, the
resource bundle that represents that locale is the source of the strings that are used
in the application. If the user requests a locale that is more specific than any of the
locales in the application, the application uses a resource bundle with a more
general locale. For example, if the user requests the locale no_NO_B, but the only
available Norwegian locale is no_NO, the locale no_NO is used.
Setting up a JSP file and a JSF Handler to use AJAX requests involves these general
steps:
1. Create the page and JSF Handler.
2. Design the page and populate the page with JSF controls that are bound to
variables and functions in the JSF Handler.
3. Indicate the area of the page that you want to change as a result of the AJAX
request. No other part of the page will be affected.
4. On the page, indicate the user event that will trigger the AJAX request, such as
selecting or moving away from a particular text control.
5. Define the request to send from the page to the JSF Handler, including the type
of request (refresh, submit, or external) and any parameters to include with the
request.
6. Write code in the JSF Handler to process the request.
There are three types of AJAX requests available to Web pages in EGL:
Refresh
This type of request prompts the servlet to update the values of the
controls in a specified area of the page; however, it does not provide
information on the state of the page to the JSF Handler. In other words, if
the user changes the value of input controls on the page, the JSF Handler
is not aware of the changes; the variables in the JSF Handler are not
Example
</TBODY>
</TABLE>
</h:form>
</hx:scriptCollector>
</body>
</f:view>
</html>
The following is the code of the JSF Handler that goes with this page:
package jsfhandlers;
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")
With this type of request, you specify an area of the page to be updated, an event
to trigger the request, and optionally any parameters to be passed along with the
request. Then, you configure the JSF Handler’s onPreRenderFunction to update
the specified part of the page.
Follow these steps to add an AJAX refresh request to a Web page. The following
steps assume that you have a JSF Handler with variables bound to controls on a
Web page:
1. On the Web page, indicate the area of the page that you want to update with
the AJAX request by creating a JSF panel control on the page.
AJAX requests in EGL can update only the parts of the page within a JSF panel
control. JSF panel controls serve mainly as containers and organizers for other
JSF controls. The Panel - Group Box control, found in the Enhanced Faces
Components drawer of the Palette view, is a good control to use because it is
only a container and is not visible on the page.
2. Set the ID attribute of the panel control to a value that is unique on the page.
You will need to specify this ID in the AJAX request.
3. Place the JSF controls that you want to update inside the panel control and
make sure that the controls are bound to EGL variables.
The code of the panel control might look like the following example. In this
case, only a single output control is within the panel.
<h:panelGrid id="updatablePanel" styleclass="panelGrid">
<h:outputText id="textToUpdate" value="#{myPage.message}"
binding="#{myPage.message_Ref}" styleClass="outputText" />
</h:panelGrid>
4. Set the ID attributes of any controls on the page that you want to pass as
parameters in the request. These controls do not need to be within the panel
control, but their ID attributes must be unique on the page, and they must be
input controls.
5. Specify the user event that will trigger the AJAX request.
Do this by adding a JSF behavior to an input control on the page and then
selecting an event to trigger the request. The control containing the behavior
does not need to be within the panel control, but only input controls can
trigger requests.
6. Create the request by specifying the panel to update and the parameters for the
request:
a. On the Web page, select the panel control.
b. With the panel selected, open the Properties view.
c. On the properties view, go to the Ajax tab under the type of panel control.
d. On the Ajax tab, select the Allow Ajax updates check box.
e. Click Refresh as the type of request.
f. Under the types of requests, click the button labeled Click to edit Ajax
request properties.
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
For an example of an AJAX refresh request, see “Updating portions of a Web page
with AJAX requests” on page 432.
Related tasks
“Updating portions of a Web page with AJAX requests” on page 432
Asynchronous JavaScript and XML (AJAX) is a development technique that you
can use to create Web pages that relay information to and from a server only
for the portions of pages that users edit, while still displaying the rest of the
page. This technique can make Web applications faster and more efficient than
if an entire page had to reload after each user action. You can set up an
EGL-controlled JSP file to call the JSF Handler’s onPreRenderFunction and
provide a limited update to the page.
“Updating a page with a submit request”
“Updating a page with a portion of another page” on page 442
With this type of request, you specify an area of the page to be updated and an
event to trigger the request. Then, you configure the JSF Handler’s
onPreRenderFunction to update the specified part of the page.
Follow these steps to add an AJAX submit request to a Web page. The following
steps assume that you have a JSF Handler with variables bound to controls on a
Web page:
1. On the Web page, indicate the area of the page that you want to update with
the AJAX request by creating a JSF panel control on the page.
AJAX requests in EGL can update only the parts of the page within a JSF panel
control. JSF panel controls serve mainly as containers and organizers for other
JSF controls. The Panel - Group Box control, found in the Enhanced Faces
Components drawer of the Palette view, is a good control to use because it is
only a container and is not visible on the page.
2. Set the ID attribute of the panel control to a value that is unique on the page.
You will need to specify this ID in the AJAX request.
3. Place the JSF controls that you want to update inside the panel control and
make sure that the controls are bound to EGL variables.
The code of the panel control might look like the following example. In this
case, only a single output control is within the panel.
Building EGL JSF Web applications 439
<h:panelGrid id="updatablePanel" styleclass="panelGrid">
<h:outputText id="textToUpdate" value="#{myPage.message}"
binding="#{myPage.message_Ref}" styleClass="outputText" />
</h:panelGrid>
4. Specify the user event that will trigger the AJAX request.
Do this by adding a JSF behavior to an input control on the page and then
selecting an event to trigger the request. The control containing the behavior
does not need to be within the panel control, but only input controls can
trigger requests.
For example, you can make the AJAX request occur when the user moves the
focus into a particular control. In this case, you use the onFocus event. To
perform the request when the user moves focus away from a particular control,
you use the onBlur event. Other commonly used events include onClick,
onMouseOver, and onSelect.
a. On the Web page, select the input control that you want to use as the
trigger.
b. With the control selected, open the Quick Edit view.
c. In the Quick Edit view, select the event, such as onBlur, from the left side of
the view.
d. Select the Use pre-defined behavior check box.
e. In the Action list, select Invoke Ajax behavior on the specified tag.
f. In the Target list, select the ID of the panel you want to update.
Now the behavior to trigger the AJAX request is attached to the control. For
example, if you attach a behavior to an input text control and set it to use the
onBlur event, the code on the page might look like this:
<h:inputText id="nameText" value="#{myPage.name}"
binding="#{myPage.name_Ref}" styleClass="inputText" >
<hx:behavior event="onblur" id="behavior1"
behaviorAction="get" targetAction="updatablePanel">
</hx:behavior>
</h:inputText>
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.
end
7. Once you have determined that the onPreRenderFunction has been called as
the result of an AJAX request, you can update the controls on the page by
setting the values of the variables bound to those controls. You can update only
the controls within the panel in the request.
Related tasks
“Updating portions of a Web page with AJAX requests” on page 432
Asynchronous JavaScript and XML (AJAX) is a development technique that you
can use to create Web pages that relay information to and from a server only
for the portions of pages that users edit, while still displaying the rest of the
page. This technique can make Web applications faster and more efficient than
if an entire page had to reload after each user action. You can set up an
EGL-controlled JSP file to call the JSF Handler’s onPreRenderFunction and
provide a limited update to the page.
“Updating a page with a refresh request” on page 436
“Updating a page with a portion of another page”
With this type of request, you specify an area of the first page to be updated, an
event to trigger the request, and optionally any parameters to be passed along with
the request. Unlike the other types of request, the external AJAX request goes to
another page, so the request must specify the page to send the request to and the
control from that page to use in place of the first page.
if (J2EELib.getQueryParameter("$$ajaxmode") == NULL)
//The page is loading for the first time.
//Perform page loading operations here.
else
//The page is loading as the result of an AJAX request.
//Perform AJAX updating operations here.
end
end
e. Once you have determined that the onPreRenderFunction has been
invoked as the result of an AJAX request, you can update the controls on
the page by setting the values of the variables bound to those controls. You
can update only the controls within the panel in the request.
You can retrieve the parameters passed with the request by using the
J2EELib.getQueryParameter() system function. For example, if you passed
the value of a text control with the ID nameText, you can retrieve the value
of that parameter with the following code:
outputText = "Hello "::J2EELib.GetQueryParameter("nameText")::"!";
2. Create the target page into which the content will be placed:
a. Create a JSP file and JSF Handler as you would ordinarily create an
EGL-controlled Web page.
b. On this page, add a panel control and give it an ID unique on the page. The
contents of this panel will be replaced with the panel on the source page.
c. Optionally, add JSF controls to the panel. The panel can be blank or
populated with controls when the AJAX request replaces it with the panel
on the source page.
3. Specify the user event that will trigger the AJAX request.
Do this by adding a JSF behavior to an input control on the page and then
selecting an event to trigger the request. The control containing the behavior
does not need to be within the panel control, but only input controls can
trigger requests.
For example, you can make the AJAX request occur when the user moves the
focus into a particular control. In this case, you use the onFocus event. To
perform the request when the user moves focus away from a particular control,
you use the onBlur event. Other commonly used events include onClick,
onMouseOver, and onSelect.
a. On the Web page, select the input control that you want to use as the
trigger.
b. With the control selected, open the Quick Edit view.
c. In the Quick Edit view, select the event, such as onBlur, from the left side of
the view.
d. Select the Use pre-defined behavior check box.
e. In the Action list, select Invoke Ajax behavior on the specified tag.
f. In the Target list, select the ID of the panel you want to update.
Now the behavior to trigger the AJAX request is attached to the control. For
example, if you attach a behavior to an input text control and set it to use the
onBlur event, the code on the page might look like this:
4. Create the request by specifying the panel to update and the parameters for the
request:
a. On the target page, select the panel control.
b. With the panel selected, open the Properties view.
c. On the properties view, go to the Ajax tab under the type of panel control.
d. On the Ajax tab, select the Allow Ajax updates check box.
e. Click External as the type of request.
f. Under the types of requests, click the button labeled Click to edit Ajax
request properties.
g. In the Target list, select the ID attribute of the panel on the target page you
want to update.
h. In the URL field, enter the relative path to the source page. Be sure to use
the correct extension of .faces or .jsp for the target page, as explained in
“Running a Web page on a server” on page 448.
i. In the Source field, enter the ID of the panel control on the source page. The
contents of this panel will replace the contents of the panel on the target
page.
If you leave this field blank, the request will retrieve the entire source page
(that is, everything within the <body> tag), not just the panel control.
j. Add parameters to the request by clicking one of the Add Parameter
buttons:
The parameters in the table labeled Parameter values sent from the browser
refer to the value of input controls on the target page. For example, if you
want to pass the current value of an input control on the page as a
parameter, add that input control’s ID here.
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.
<h:selectOneRadio disabledClass="selectOneRadio_Disabled"
enabledClass="selectOneRadio_Enabled" id="fruitName"
styleClass="selectOneRadio">
<f:selectItem itemValue="bananas" itemLabel="bananas" />
<f:selectItem itemValue="apples" itemLabel="apples" />
<f:selectItem itemValue="grapes" itemLabel="grapes" />
</h:selectOneRadio>
</h:panelGroup>
<hx:ajaxExternalRequest id="ajaxExternalRequest1"
target="targetPanel" href="sourcePage.faces"
source="sourcePanel" params="fruitName">
</hx:ajaxExternalRequest>
</h:form>
</hx:scriptCollector>
</body>
</f:view>
</html>
The following are some technical details about the target page:
v The tag <h:panelGroup> is the JSF panel control that will be updated. It has the
ID attribute targetPanel.
v The tag <h:outputText> is a JSF output text control that displays a static
message as a prompt.
v The tag <h:selectOneRadio> is a JSF check box group control that offers three
options. This check box group has the ID attribute fruitName, which will be the
parameter passed along with the request.
v The tag <hx:behavior> specifies the event that triggers the AJAX request. The
behavior’s attributes point to the ID of the panel control and the radio button
group. In this case, the event is onchange, which means that the AJAX request is
triggered when the selection in the radio button group changes.
v The tag <hx:ajaxExternalRequest> defines the AJAX request itself. This tag’s
target attribute points to the panel control, indicating that this request will run
when the panel’s event is triggered. The other attributes of the request point to
the location of the source page, the ID of the panel to retrieve from the source
page, and the parameter to pass with the request. In this case, the request
includes the selection in the check box group as a parameter.
The following is the JSF Handler that would go with this page, named
targetPage.egl:
package jsfhandlers;
</hx:scriptCollector>
</body>
</f:view>
</html>
This page contains a panel control that will be used to replace the panel on the
target page. In this case, the panel contains a single output field that is bound to a
variable in the page’s JSF Handler. The page looks like this:
Following is the JSF Handler that would go with this page, named sourcePage.egl:
package jsfhandlers;
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
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.
You can deploy the following kinds of EGL applications on the i5/OS integrated
Web application server:
v The application has to be a JSF handler program with or without database
access.
v The application can access the rununit.properties file generated from the project
build descriptor. The properties file contains key-value properties such as
database connection and EGL environment variables, which can be used to affect
the runtime behaviors of the deployed application.
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.
Copy the WAR file to the i5/OS environment by following these steps:
1. Map a network drive on your local system to access the remote i5/OS system:
>> net use z: \\lp11ut8.rchland.ibm.com\root
2. Create a directory in i5/OS to store the WAR file. For example, make a folder
in the network drive z:
>> md eglwars
3. Copy the local WAR file to the remote i5/OS system:
>> copy d:\genout\EglWebProj.war z:\eglwars
Use the following steps to install an application WAR or WAB file to the server
instance:
1. On the Manage All Servers screen, select the server instance (EGLi501 in this
example), and click Manage Details.
2. On the Manage Integrated Web Application Server screen, click Manage
Installed Applications.
3. On the Manage Installed Applications screen, click Install.
4. On the Install New Application screen, enter the path name of the application
WAR or WAB file, or click Browse to navigate to the file. Click Next.
5. On the Provide options to perform the install screen, click Next to accept the
default values.
6. On the Context Root Port Mapping screen, click Next to accept the default
values.
7. On the Summary screen, click Finish.
Test a JSF handler with the Web Application Server by entering the URL for the JSF
application into a browser in the following form:
http://hostName:portNum/contextRoot/pageName.faces
hostName
The host name for the i5/OS system.
portNum
The port ID for the server instance.
You also may want to review the documentation for your Web application server.
In JEE security, permission to access Web resources is based on a security role such
as clerk or manager. Each role is a developer-assigned status and is stored in the JEE
deployment descriptor (web.xml) that accompanies the application code. Also
stored in web.xml is a set of constraints that define which Web pages are available
to the users who are ultimately assigned to a given role.
If you are using the Form authentication method, you can customize the following
JSP pages:
v Sample login JSP
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
This section mentions issues that are specific to WebSphere Application Server 6.1.
For a more detailed review, see IBM WebSphere Application Server V6.1 Security
Handbook, which is an IBM Redbook (SG24-6316-01) that can be accessed at
http://www.redbooks.ibm.com/abstracts/sg246316.html.
import com.ibm.egl.jsf.*;
myViewRoot UIViewRoot;
myInputVar string = "Hello";
function changeColor()
myInputField HtmlInputText;
myInputField = viewRoot.findComponent("form1:text1");
myInputField.setStyle("color : red");
end
end
This example assumes an input control on the JSP named text1 that is bound to
the myInputVar variable and a command button on the JSP that is bound to the
changeColor function.
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
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.
You can change the style class of a JSF control on a Faces JSP file from one class to
another. To make smaller changes to a JSF control’s style, such as changing the text
color, see “Changing the style of a JSF control” on page 458.
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:
The JavaScript function that is used as an event handler must be available to the
page, either in a <script> tag on the page itself or in a script file that is linked to
the page. You cannot use an EGL function as an event handler for a JSF control.
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.
Follow these steps to change the size of a JSF image control with an EGL JSF
Handler:
Adding support for the JSF component interface adds a package named
com.ibm.egl.jsf to your project. As explained in “Accessing the JSF component
tree with the source assistant” on page 454, this package contains ExternalType
parts that you can use to access JSF components on the page.
You cannot remove support for the JSF component interface from a project.
To specify preferences for Web projects and JSF Handler parts, follow these steps:
1. From the main menu, click Window → Preferences.
2. From the navigation tree, expand EGL and click Page Designer.
3. In the JSFHandler Package field, specify the location of JSF Handler parts in
your EGL Web projects.
4. In the Loadbundle variable field, set the name of the variable to use to
represent resource bundles in your pages. The default value is labels, but you
can change this value as explained in “Localizing text in Web applications” on
page 426.
5. Set preferences for refactoring EGL Web projects and JSF Handler parts in the
check boxes at the bottom of the page. These check boxes tell EGL to delete the
JSP file that is associated with a JSF Handler if you delete the JSF Handler, and
vice versa. You can also delete the generated output when you delete a JSF
Handler.
6. Click Apply to save the changes and remain in the Preferences window. Click
OK to save the changes and exit the window.
Related concepts
“Preferences” on page 172
EGL preferences affect the way the workbench displays and works with EGL.
Related Reference
JSF Handler part
In an EGL portlet application, the EGL logic parts control portlets. These parts
allow you to put data in a Portal and get input from users. EGL portlet
development follows the EGL Web application programming model, and differs
only in the ways noted in this section.
Portlet overview
WebSphere Portal Server is a content aggregator. It uses programs called portlet to
process user requests and generate dynamic content. The portal acts as a container
for the portlets, managing the lifecycle of, and providing various services to, the
portlets and combining their output into a single Web page.
Each page of a portal is divided into “windows” that display the dynamic content
generated by a single portlet. Portlet windows have two user modifiable
properties, mode and window state.
Portlet mode
A portlet mode is an indication of the function that the portlet will perform to
produce specific content or perform a certain task. Common portlet modes are
View, Edit, and Help.
All portlets are required to provide View mode support. In this mode, portlets
generate their normal dynamic content. For example, you can have a portlet that
displays the local weather in the portlet window.
Portlet can also be displayed in Edit mode. In our weather portlet example, if we
had displayed the portlet in Edit mode, it would wait for the user to enter the
local zip code in order to customize the weather display. Each user is able to
provide this customization data, which means that the portlet will display different
data depending on who is logged in. Edit mode support is optional.
Help mode causes the portlet to display information on the use of the portlet. The
help can be a single screen displaying help for the entire portlet, or may be more
context specific. Help mode support is optional.
Window state
The window state of a portlet is an indicator of the amount of page real estate that
the portlet will occupy. Portlets can have three possible states: normal, maximized,
and minimized.
The normal window state indicates that the portlet may be sharing the page with
any either any number of other portlets. Because the portlet window might be
small, the portlet author might want to limit the amount of page space that the
portlet requires. For instance, in the example weather portlet, we can choose to
limit its display to the temperature and a graphic that indicates the current
weather conditions.
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
When you use the New EGL Portlet wizard to create a portlet named MyPortlet,
and specify that it will support view and edit modes, the wizard will create two
JSF Handlers called MyPortletView and MyPortletEdit
Window state
Portlet sessions do have one major difference. Unlike Web application sessions, a
Portlet session has scope. A session attribute that is placed in the portlet scope is
easily accessible only to the portlet that added it.
When you add an attribute to the session, you must specify the level of access to
the attribute within the portlet application. Do this through the scope parameter of
the portalLib.setPortletSessionAttr() function. This parameter takes an enumerated
value of type SessionScopeKind. For example, to add a session attribute that is
only accessible to the declaring portlet, use the following function call in the JSF
Handler:
portalLib.setPortletSessionAttr(“myKey”, “myValue”, SessionScopeKind.portletScope);
Related concepts
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
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.
The new portlet will be created in the target project. The faces-config.xml and
portlet.xml files will be updated to support the new portlet. A JSP and
corresponding JSF Handler will be created for each supported portlet mode.
Related concepts
“Building EGL portlet applications” on page 467
A portal page combines a number of independent windows, or portlets, under
the control of a portal server.
“Elements of a Portlet Application” on page 468
“Managing Portlet Sessions” on page 469
“Inter-Portlet Communication” on page 470
“J2EELib” on page 471
Related tasks
“Creating a Web Page” on page 471
“Adding Support for Additional Portlet Modes” on page 473
Related reference
EGL library portalLib
The relative independence of the service and other software is called loose coupling.
The flexibility offered by loose coupling protects your company from excessive
costs when business or technical requirements change.
A service can handle interactions within your company, as well as between your
company and its suppliers, partners, and customers. The location of service
requesters can extend worldwide, depending on security issues and on the runtime
software used to access a particular service.
The requesting code usually has no details on the service location. Like the
requester, the service can be almost anywhere. The location is set when the service
is deployed. At run time, a requester or network may be able to redirect a request
to a service at a different location.
SOA implies a style of development, with concern for the business as a whole and
with an increased focus on modularity and reuse. From the point of view of a
developer, a change to a service orientation is a change in emphasis, and many
aspects of the development task are unaffected.
Service-oriented application
Integration
service
Business Business
service service
Databases
The topmost level contains one or more integration services, each of which controls
a flow of activities such as processing an applicant’s request for insurance
coverage. Each integration service invokes one or more business services.
The second level is composed of services that each fulfill a relatively low-level
business task. For example, an integration service might invoke a series of business
services to verify the details provided by an insurance-policy applicant. If the
business services return values that are judged to mean ″issue a policy,″ the
integration service invokes yet another business service, which calculates a quote
and returns the quote to the software (for example, a Web application) that
invoked the service-oriented application.
The third level consists of data-access services, each of which handles the relatively
technical task of reading from and writing to data-storage areas such as databases
and message queues. A data-access service is most often invoked from the business
layer, but the easy access of services means, for example, that the Web application
can access a data-access service to assign initial values in a form.
SOA has several important implications for business. First, to the extent that loose
coupling is in effect, changes made to the service logic won’t force significant
changes to requesters of that software. When each component is a relatively
Last, well-designed services are more likely to be reusable. Your company benefits
from reuse in at least two ways: first, by avoiding the expense of developing new
software, and second, by increasing the reliability of the software inventory over
time. The firm can do less extensive testing if an existing service is placed in a new
application, in comparison to the testing required to deploy software that was
written from scratch.
Notice
The preceding overview of service-oriented architecture is largely from SOA for the
Business Developer (http://www.mc-store.com/5079.html), published by MC Press.
Related concepts
“Elements of a service-oriented application” on page 478
The major elements of an EGL service-oriented application are the service part,
interface part, and deployment descriptor file. In general, each of these files and
parts has a role in both services and service requesters.
“Types of services” on page 481
You can generate your service parts as EGL services, as SOAP (Web) services,
or as REST services. An EGL-based requester can access EGL services; or SOAP
(Web) services, which may be written in a language other than EGL; or native
services, which currently include service programs on IBM i. The only
EGL-application that can access a REST service is a Rich UI application, and the
accessed service in that case may be written in EGL or another language.
Related tasks
“Adding service client binding information from a WSDL file” on page 489
Service client binding information tells how the EGL runtime connects to a
service being invoked by your EGL code. This topic concerns SOAP (Web)
service invocation.
“Calling a remote service” on page 485
You can call remote services from your EGL logic parts.
“Calling a local service” on page 483
You can call an EGL or native service that is local to your application without
exposing that service as a Web service.
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.
end
Interface part
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.
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;
end
The EGL deployment descriptor file (extension .egldd; not to be confused with JEE
deployment descriptor files) contains information that describes either how a
service part from your application is exposed to other applications or how an
external service will be used in your application. Therefore, there are two major
items in the deployment descriptor file:
v Service client bindings represent services from other applications that you want to
use in your application’s logic parts. The service client binding information often
includes a WSDL file that describes the external service and the name of an EGL
part in your project that will represent the service within your application.
v Web service deployment information lists service parts in your application that you
want to expose to other applications. The information in the deployment
descriptor includes details about how the service will be deployed and made
available to other applications.
The EGL deployment descriptor is distinct from JEE deployment descriptors. For
information on JEE deployment descriptors, see Defining JEE enterprise
applications (EARs).
You might encounter WSDL files in your EGL applications in two areas:
v When acting as a requester of a service, you can create parts and binding
information directly from the WSDL file of the particular service. See “Adding
service client binding information from a WSDL file” on page 489 for more
information.
v When you generate a service part as a Web service, EGL creates a WSDL file that
other services can use to invoke your service. In this case, treat the WSDL file as
you treat any generated output, because it will be overwritten each time you
generate the deployment descriptor file.
For more information on Web Services Description Language (WSDL), see Web
Services Description Language (WSDL).
Related concepts
“Types of services” on page 481
You can generate your service parts as EGL services, as SOAP (Web) services,
or as REST services. An EGL-based requester can access EGL services; or SOAP
(Web) services, which may be written in a language other than EGL; or native
services, which currently include service programs on IBM i. The only
EGL-application that can access a REST service is a Rich UI application, and the
accessed service in that case may be written in EGL or another language.
“Overview of service-oriented architecture (SOA)” on page 475
Overview of service access
Related tasks
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.
EGL services are based on the Service part, a logic part similar to a library. A
Service part can contain other parts, but only the Service part can be exposed to a
requester. After you have written the Service part, you expose it by adding
deployment information in the EGL deployment descriptor file. For details, see
“Exposing a service to other applications” on page 493.
Any EGL logic part, including a Service part, can behave as a requester. When
coding a requester, do as follows:
v Add a service client binding in the deployment descriptor, and in this way
provide the details necessary to access the service. The service client binding has
a binding key–essentially, a name–along with service-access details that are
associated with that key.
v Create a variable based on the Service part or on an equivalent Interface part.
v Relate the variable to the service client binding. You must set the complex
property @BindService in the variable declaration; but if you fail to specify a
In this context, a local service is either an EGL service part (in your project or in a
project that is in your project’s build path) or is a System i service program being
accessed from an EGL-generated COBOL program that runs on the same machine.
For other cases, see “Calling a remote service” on page 485.
end
2. Create a client binding in the deployment descriptor file. The client binding
information tells EGL where to find the service at run time.
a. Open the client project’s deployment descriptor file. If the project does not
have a deployment descriptor file, create a new one and add it as the value
of the deploymentDescriptor build descriptor option. For more information,
see “Creating a deployment descriptor” on page 94.
b. On the Service Client Bindings page of the deployment descriptor editor,
under the heading Service Client Bindings, click Add. The Add a Service
Binding window opens.
localEGLService CalculatorService;
function main()
end
end
5. Apply the @BindService complex property to the variable and set the
bindingKey property field to the name of the client binding. In the previous
examples, this binding was named CalculatorService.
import services.CalculatorService;
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;
localEGLService CalculatorService
{@BindService{bindingKey = "CalculatorService"}};
function main()
SysLib.writeStderr("Calling local EGL service: ");
outputString string;
outputString = "5+5=";
outputString += localEGLService.addIntegers(5,5);
SysLib.writeStderr(outputString);
end
end
7. Save, generate, and run the program.
Related concepts
“Overview of service-oriented architecture (SOA)” on page 475
Related tasks
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.
“Creating a deployment descriptor” on page 94
The EGL deployment descriptor provides service-binding detail when you are
generating a service, as well as service-binding detail when you are generating
a logical unit (program, library, handler, or service) that invokes a service.
“Calling a remote service”
You can call remote services from your EGL logic parts.
“Creating a service-access variable and binding it to a service” on page 491
After you have created binding information for a service, you can use the
service in an EGL logic part with a variable that represents the service.
Related reference
Interface part
Interface parts provide access to a remote service, such as a Web service.
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.
To add the service client binding information for a remote service, do as follows:
1. Open the deployment descriptor in the deployment descriptor editor.
2. On the Service Client Bindings page of the deployment descriptor editor, under
the heading Service Client Bindings, click Add.
3. In the Add a Service Binding window, click SOAP (Web) Binding, REST (Web)
Binding,EGL Binding, or Native Binding and then click Next.
4. For SOAP (Web) Binding, follow the steps described in Adding service client
binding information from a WSDL file.
5. For REST (Web) Binding, you must be accessing the service from a Rich UI
application. Specify the following details, which are explained in Creating an
Interface part to access a REST service and Declaring an interface to access a REST
service:
v Specify the EGL binding name. In most cases, click Browse next to the EGL
Binding Name field name and retrieve an Interface or Service part. The
name will be the value of the property @BindService, property field
bindingKey, as used when you declare a variable to invoke the service.
v In the baseURI field, specify a string that identifies the first qualifiers in the
URI being used to access the service.
v In the Session Cookie ID field, specify a string that identifies the session
cookie provided to the EGL Rich UI Proxy from a service.
6. For EGL Binding, follow the steps described in Adding service client binding
information for an EGL service.
7. For Native Binding:
a. Next to the Native Binding Name field, click Browse. This name will be the
value of the bindingKey property field when you declare a variable to
invoke the service.
For details on adding binding information for a Web service, see “Adding service
client binding information from a WSDL file” on page 489.
Prerequisites
v An EGL project
v An EGL deployment descriptor
v An interface part or service part that represents the external service at design
time:
Now you can use the binding in your code as explained in “Creating a
service-access variable and binding it to a service” on page 491.
Alternately, if you have the service part in your workspace already, you can create
the binding information directly from that service part. Right-click the part and
then click EGL Services → Create EGL Service Client Binding. Then, choose a
deployment descriptor file and fill in the protocol and attribute information for the
binding as in the steps above.
Related tasks
“Overview of service-oriented architecture (SOA)” on page 475
“Creating a deployment descriptor” on page 94
The EGL deployment descriptor provides service-binding detail when you are
generating a service, as well as service-binding detail when you are generating
a logical unit (program, library, handler, or service) that invokes a service.
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.
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.
A service behaves much like a library in that they are both a group of functions
that are available for use by other logic parts. However, calling a service requires
more preparation than calling a library.
When you call a function within a library, you type the name of the library, a
period, and the name of the function, followed by any arguments the function
expects:
myInt int = MathLib.abs(-5);
A call to a function within a service looks the same because the call uses similar
syntax:
mySum int = Calculator.addIntegers(1, 2);
However, the call to a service is different because the code is not calling the service
directly (as the example above called MathLib.abs() directly), but instead is using
a variable that represents that service. In the previous example, Calculator is a
variable that is created from a Service part or Interface part and then linked, or
bound, to the service itself. The binding information in the deployment descriptor
file tells EGL how to bind that variable to the service at run time.
Prerequisites
v An EGL project
v Client binding information for a Web service or an EGL service.
v An Interface part or Service part.
v Any EGL logic part, such as a Program, Library, Service, or Handler
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);
Dynamic binding enables you to choose a service at run time, or to change the
service to which a variable is bound. To bind a variable dynamically, use functions
in the EGL library ServiceLib instead of the @BindService property. This option is
not available for local access of a native service on System i.
Suppose that you have created entries in the deployment descriptor file for two
slightly different service implementations:
<webBinding interface="interfaces.SpeechTranslator"
name="TranslateSpanish" port="SpanishPort"/>
<webBinding interface="interfaces.SpeechTranslator"
name="TranslateGerman" port="GermanPort"/>
You could create and bind two variables, one for each of these entries. An alternate
way is to create one variable based on the Interface part that the entries share, and
then use the ServiceLib.bindService() system function to bind the variable to the
service that you want to use.
1. Create a variable that is based on the Interface or Service part in the
deployment descriptor entry:
myTranslator SpeechTranslator;
2. Use the bindService() function to bind the variable to the service
implementation:
myTranslator = ServiceLib.bindService("TranslateSpanish");
interface calculatorInterface
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.
You code a Service part in much the same way as a Library part.
1. Create an EGL Service part. See “Creating EGL source files” on page 90.
2. If you want the Service part to use an interface, add an implements clause to
the service part:
package services;
end
Alternately, you can select an interface to implement when you create the
service. In this case, EGL creates stub functions for the functions that are
defined in the interface.
When a service implements an interface, that service must define each function
that is listed in the interface, and the input and output parameters of those
functions must match those of the prototypes in the interface. EGL produces an
error if any function in a service does not match the prototype of the same
name in the interface, as well as if any function prototype in the interface is not
defined in the service. Also, a service can implement more than one interface.
In that case, the service must define each function that is prototyped in each
interface.
3. Write the code for the functions in the service, including any functions defined
in the interface and any private functions your services may need:
package services;
end
Now, EGL requesters can access your Service part directly. However, for non-EGL
requesters to access the service, you must expose your service as a SOAP or REST
service, which involves adding Web service deployment information to the
deployment descriptor file. See Adding Web service deployment information to the
deployment descriptor.
After you have coded and deployed your service application, you must distribute
its information so client applications can use the service. For an EGL client
application to access your service, you need only distribute the binding
information that the client needs. For a non-EGL client application to access the
service, or for an EGL client application to access the service through a Web service
connection, you must distribute the WSDL file that is created when you generate
the project.
Related tasks
“Adding Web service deployment information to the deployment descriptor”
on page 496
After you have coded a service part that you want to expose as a Web service,
you must add information to the deployment descriptor that tells EGL to
generate the necessary Web service wrapper.
“Creating EGL source files” on page 90
The creation process is essentially the same for most EGL source files.
“Creating a deployment descriptor” on page 94
The EGL deployment descriptor provides service-binding detail when you are
generating a service, as well as service-binding detail when you are generating
a logical unit (program, library, handler, or service) that invokes a service.
“Calling a remote service” on page 485
You can call remote services from your EGL logic parts.
“Calling a local service” on page 483
You can call an EGL or native service that is local to your application without
exposing that service as a Web service.
Related reference
Interface part
Interface parts provide access to a remote service, such as a Web service.
Service part
Service parts provide requesters with access to the functions in the service. A
requester can be a local or remote program, handler, library, or other service.
Function prototypes
Prerequisites
v An EGL project
v A Service part
v An EGL deployment descriptor file
You can use the EGL Text UI technology to create a very basic user interface, like
one you would find on a mainframe. This means you can generate programs for
both COBOL and Java that present an identical interface to the user.
Text UI interfaces are based on forms. A form contains fields that are displayed
together on a screen page or sent together to a printer. Properties determine how
each field is displayed or printed within the form.
Text UI programs carry on a conversation with the user. The EGL converse
statement gives control to the form; when the user presses a key, control returns to
the program and the program processes the information in the form.
Example
To create a simple Text UI program, first create a FormGroup in a new EGL source
file:
FormGroup myFormGroup
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.
You can also create forms based on the templates in the Palette view. These
templates create forms with predefined appearances and fields. See “Creating a
form from a template” on page 505.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
“Display options for the EGL Text Form editor” on page 510
Related tasks
“Filtering the editor” on page 509
“Creating a popup form” on page 506
“Creating a popup menu” on page 507
“Creating a constant field”
“Creating a variable field” on page 503
“Creating a form from a template” on page 505
The EGL Text Form editor uses templates to create commonly used types of
forms and fields. These templates are listed in the Templates drawer of the
Palette view.
Related reference
Form part
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.
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.
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
Because variable fields have no default value, they can be invisible if they are not
highlighted. To mark each variable field with appropriate sample text, click the
Toggle Sample Values button at the top of the editor.
After you have created a variable field, you can double-click it in the editor to
open the Edit Type Properties window. From this window you can edit the field in
the following ways:
v Change the field’s name by typing a new name in the Field Name field.
v Select a new type of field from the Type list.
v Change the precision of the field by specifying a new number in the Precision
field.
When you are finished editing the field’s properties in the Edit Type Properties
window, click OK.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
Related tasks
“Setting preferences for the Text Form editor palette entries” on page 512
“Creating a constant field” on page 502
Related reference
Form part
The Text Form editor can create forms from templates. These forms have pre-made
borders, sections, and fields. To create a form from a template, see“Creating a
popup form” on page 506 or “Creating a popup menu” on page 507.
The Text Form editor can create a group of fields using an EGL record as a
template. To create fields representing data from an EGL record, see “Displaying a
record in a text or print form” on page 507.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
“Creating a form from a template”
The EGL Text Form editor uses templates to create commonly used types of
forms and fields. These templates are listed in the Templates drawer of the
Palette view.
Related tasks
“Setting preferences for the Text Form editor” on page 510
“Creating a simple text or print form” on page 502
“Creating a constant field” on page 502
“Creating a variable field” on page 503
“Creating a popup menu” on page 507
Note: The total number of rows in the popup field’s sections cannot exceed
the total number of rows in the popup field. When adding sections, pay
attention to the Remaining Effective Rows field and remember that
dividers between the sections require an additional row for each new
field.
11. When you are finished adding sections to the popup field, click Finish. The
new popup form is created in the editor.
12. Add fields to the form as appropriate. See“Creating a constant field” on page
502 and “Creating a variable field” on page 503.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
“Creating a form from a template” on page 505
The EGL Text Form editor uses templates to create commonly used types of
forms and fields. These templates are listed in the Templates drawer of the
Palette view.
Related tasks
506 EGL Programmer’s Guide
“Setting preferences for the Text Form editor” on page 510
“Creating a simple text or print form” on page 502
“Creating a constant field” on page 502
“Creating a variable field” on page 503
“Creating a popup menu”
You can switch between active filters with the list next to the Filters button at the
top of the editor. To create, edit, or delete filters, click the Filters button.
From the Filters window, you can manage your filters by using the following
functions:
v Select filters from the list.
v Add a new filter by clicking New.
v Delete a filter by selecting it from the list and clicking Remove.
v Select which forms are displayed when the filter is active.
To create a new filter in the EGL Text Form editor, follow these steps:
1. Open a form group in the Text Form editor.
2. In the Text Form editor, click the Filters button. The Filters window opens.
3. In the Filters view, click the New button. The New Filter dialog box opens.
4. In the New Filter dialog box, type a name for the filter and click OK.
5. Select the forms to be displayed while the filter is active by doing one or more
of the following steps:
v Clear the check boxes next to the forms that you want hidden by the filter.
v Select the check boxes next to the forms that you want shown by the filter.
v Click the Select All button to show every form.
v Click the Deselect All button to hide every form.
6. Click OK.
The new filter is active. You can switch filters by using the list next to the
Filters button.
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
“Display options for the EGL Text Form editor” on page 510
Related tasks
“Creating a simple text or print form” on page 502
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”
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”
Note: You can restore all of the palette entries to their default settings by
clicking Restore Defaults.
4. When you are finished setting the preferences for the palette entries, click OK
Related concepts
“Building EGL Text User Interface applications with the Text Form editor” on
page 500
Related tasks
“Setting preferences for the Text Form editor” on page 510
“Creating a constant field” on page 502
“Creating a variable field” on page 503
Related reference
Form field properties
As the term character-based suggests, a console user interface shows only text on the
screen, no graphics or buttons, and it responds only to the keyboard, not the
mouse. However, with EGL, you to enhance your Console UI programs with
mouse functionality and rich client widgets by running your applications in rich
client platform (RCP) mode. See “Console UI modes” on page 529.
Related concepts
“Elements of a Console UI application”
A Console UI application can use several different types of EGL parts to supply
data and several different types of EGL variables to create the interface.
“Console UI modes” on page 529
EGL supports three modes in which you can run Console UI applications:
Swing, Curses, and rich client platform (RCP). The three modes have different
abilities, but in general a Console UI application behaves the same way in each
mode.
Related tasks
“Creating a Console User Interface” on page 516
Console UI relies on the openUI statement to define which forms and fields are
shown on the interface, which variables those forms and fields are bound to,
and which actions happen when the user performs tasks in the interface.
“Adding rich client widgets to a Console UI program” on page 519
When running in rich client platform (RCP) mode, you can use additional
Console UI components called widgets to add additional functionality.
“Running Console UI applications” on page 528
The process for running a Console UI application differs slightly depending on
the mode you are running in.
Related reference
Console UI parts
openUI
Like many types of applications with user interfaces, EGL Console UI applications
separate the interface from the logic used to create that interface. An ordinary EGL
program provides the logic for the application, while several different types of
parts can represent the interface itself.
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.
In Console UI, a menu is a set of options from which the user is expected to
choose one. When showing a menu on the interface, you define a menu part and
then define the options as an array of menuItem parts in the menuItems menu
property. For example, the following menu defines three options from which the
user can choose:
new Menu {labelText = "Choose an option: ",
menuItems = [
new MenuItem{name = "One", labelText = "Option One"},
new MenuItem{name = "Two", labelText = "Option Two"},
new MenuItem{name = "Three", labelText = "Option Three"}
]}
See “Creating a Console User Interface” on page 516 for an example of how to
respond when the user selects one of the options.
ArrayDictionary part
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 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.
With EGL, you can run your Console UI projects in a variety of modes. If you
want to run your Console UI application in rich client application (RCP) mode,
you need to convert your project to an EGL plug-in project.
For more information about the modes you can run your Console UI application
in, see “Console UI modes” on page 529. For more information on EGL plug-in
projects, see “Creating an EGL plug-in project” on page 74.
Related tasks
“Creating a Console User Interface” on page 516
Console UI relies on the openUI statement to define which forms and fields are
shown on the interface, which variables those forms and fields are bound to,
and which actions happen when the user performs tasks in the interface.
“Adding rich client widgets to a Console UI program” on page 519
When running in rich client platform (RCP) mode, you can use additional
Console UI components called widgets to add additional functionality.
“Running Console UI applications” on page 528
The process for running a Console UI application differs slightly depending on
the mode you are running in.
Related reference
Menu
Using an array dictionary in Console UI
function main()
myWindow Window {name = "My Window",
position = [1,1]};
myConsoleRec CustomerConsoleRecord{name = "myForm"};
ConsoleLib.openWindow(myWindow);
ConsoleLib.displayForm(myConsoleRec);
end
end
However, this interface is not very useful because it does not enable the user to
interact with the form or window at all. Because this form does not enable any
interaction, the window closes as soon as it opens. You need to bind EGL variables
to the fields with the openUI statement to make the fields on the interface
meaningful and keep the window open while the user works with the interface.
Like many other types of applications with user interfaces, Console UI applications
separate the interface from the data being managed by the interface. When you
create a Console UI in EGL, you create the interface with parts like consoleForms
and then use the openUI statement to connect, or bind, those parts to variables in
your program. Then, when the person using the interface changes a value in the
consoleForm, the value of the variable changes to match. Conversely, when your
code changes the value of the variable, the value in the form changes to match.
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
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.
For your Console UI to react to actions that the user performs in the form, you
must define event handlers that tell EGL what to do in response to the action. An
event handler contains EGL statements like a function, but it begins with a
description of an event, such as a key being pressed or a value being typed in a
field. When the user presses a key or types a value in a field, the event handler
that is associated with that action is called.
The following example adds an event handler to the previous example. This event
handler is called when the user types a value in the customer_id field and moves
the cursor out of the field:
program basicConsole type BasicProgram
function main()
myWindow Window {name = "My Window", position = [1,1]};
myConsoleRec CustomerConsoleRecord{name = "myForm"};
ConsoleLib.openWindow(myWindow);
ConsoleLib.displayForm(myConsoleRec);
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
function main()
openUI
new Menu {labelText = "Choose an option",
menuItems = [
new MenuItem{name = "One",labelText = "Option One"},
new MenuItem{name = "Two",labelText = "Option Two"},
new MenuItem{name = "Exit",labelText = "Exit"}
]}
onEvent(MENU_ACTION:("Exit"))
exit openUI;
onEvent(MENU_ACTION:("One"))
consolelib.displayAtLine("You chose option One", 5);
onEvent(MENU_ACTION:("Two"))
consolelib.displayAtLine("You chose option Two", 5);
end
end
end
In this example, the window provides a feedback message when the user selects
one of the first two options and closes when the user selects the ″Exit″ menu
option.
In general, using a rich client widget in your Console UI program involves these
steps:
1. Create the widget as a field in a console form and specify the properties for the
field.
2. In the Console UI program, create a variable to represent the state of the
widget:
v For check boxes, create a BOOLEAN variable.
v For single-selection widgets, create an INT variable.
v For buttons, no variable is needed.
3. With the bind clause of the openUI statement, bind the variable to the widget.
This step is not required for button widgets because the button widgets do not
need a variable.
4. Create an event handler for the widget:
v For check boxes, use the ConsoleCheckbox.STATE_CHANGED event.
v For combo boxes, use the ConsoleCombo.SELECTION_CHANGED event.
v For radio button groups, use the
ConsoleRadiogroup.SELECTION_CHANGED event.
v For list boxes, use the ConsoleList.SELECTION_CHANGED event.
v For buttons, use the ConsoleButton.PUSHED event.
These widgets are supported only when running in RCP mode. See “Console UI
modes” on page 529.
import forms.buttonForm
textValue string;
counter int=0;
function main()
myWindow WINDOW {name="myWindow",
position = [1,1]};
openWindow(myWindow);
end
A complete example of a Console UI program that uses a check box in this way
follows:
import forms.checkForm;
function main()
myWindow WINDOW {name="myWindow", position = [1,1]};
openWindow(myWindow);
end
Like the check box widget, the single-selection widgets must be bound to a
variable that represents their states. However, instead of a boolean variable, the
single-selection widgets must be bound to an INT variable to represent the index
of the currently selected option.
1. In a console form, create the widget using the predefined parts:
record singleSelectForm type ConsoleForm
{ formsize=[12,40] }
myRadio consoleRadioGroup
{name = "radio", bounds = [1,2,4,17]};
myCombo consoleCombo
myForm.myCombo.items =
["Option One", "Option Two", "Option Three"];
myForm.myRadio.items =
["Option One", "Option Two", "Option Three"];
myForm.myList.items =
["one","two","three","four","five","six"];
displayForm(myForm);
5. With an openUI statement, open the form and bind the variables to the
widgets:
openUI myForm
bind radioValue, comboValue, listValue
//event handlers go here
end
6. Within the openUI statement, specify an event handler for the widget’s
SELECTION_CHANGED event:
onEvent (ConsoleRadioGroup.SELECTION_CHANGED : "radio")
SysLib.writeStdout("Radio selected: "::radioValue);
onEvent (ConsoleCombo.SELECTION_CHANGED : "combo")
SysLib.writeStdout("Combo selected: "::comboValue);
onEvent(ConsoleList.SELECTION_CHANGED : "list")
SysLib.writeStdout("List selected: "::listValue);
A complete example of a Console UI program that uses a combo box widget and
radio button group widget in this way follows:
import forms.singleSelectForm;
function main()
myWindow WINDOW {name="myWindow", position=[1,1]};
openWindow(myWindow);
myForm singleSelectForm{};
myForm.myCombo.items =
displayForm(myForm);
openUI myForm
bind radioValue, comboValue, listValue
onEvent (ConsoleRadioGroup.SELECTION_CHANGED : "radio")
SysLib.writeStdout("Radio selected: "::radioValue);
onEvent (ConsoleCombo.SELECTION_CHANGED : "combo")
SysLib.writeStdout("Combo selected: "::comboValue);
onEvent(ConsoleList.SELECTION_CHANGED : "list")
SysLib.writeStdout("List selected: "::listValue);
end
end
end
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:
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.
For information on the different modes available for Console UI applications, see
“Console UI modes” on page 529.
To run a Console UI program in rich client platform (RCP) mode, the Console UI
program must be in an EGL plug-in project. See “Creating an EGL plug-in project”
on page 74.
Running a Console UI program in RCP mode is different from running other types
of EGL programs because you run the application from the EGL file, not the Java
file:
1. Save all changed files and generate the project.
2. In your EGL project, right-click the file that contains the Console UI program
part and then click Run As RCP. The program opens in a new window. In this
window, you can use the enhanced GUI features of the workbench, including
using the mouse to select fields, and copying and pasting text between fields.
Related concepts
“Building EGL Console User Interface applications” on page 513
Console User Interface, or Console UI, is a style of user interface similar to that
used on a UNIX-based program that interacts with a character-based terminal.
“Console UI modes” on page 529
EGL supports three modes in which you can run Console UI applications:
Swing, Curses, and rich client platform (RCP). The three modes have different
abilities, but in general a Console UI application behaves the same way in each
mode.
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.
Each engine has its particular advantages and drawbacks, as detailed in the
following sections. One common drawback is that these reports run on Java only.
You must create custom report programs for COBOL.
JasperReports engine
The JasperReport engine allows the greatest complexity. You use a design file to
dictate the layout, which can be quite complex. You can nest as many subreports as
you want to any depth, passing information to the subreport from the report or
subreport that calls it. The addition of an EGL JasperReports handler means you
can create dynamic reports that respond to events that occur as the report is
generated, such as reaching maximum values on subtotals, or changing between
various commission structures. Output options include PDF, HTML, XML, plain
text, and comma separated values (CSV) for use with Excel.
With greater flexibility comes increased effort required in using the product.
Mastering the design file is difficult enough that third-party applications are
available to help you. These applications, including JasperReports, are third-party
products, not affiliated with IBM.
If all you need is a simple text report, JasperReports may be a more powerful tool
than you need, like using a jet plane for a short trip down the street.
BIRT engine
BIRT is an Eclipse-based reporting system that allows for sophisticated output in
PDF or HTML format, including graphics, tables, graphs, and charts.
You can design a report in the Report Design perspective of your Workbench and
then write EGL code that drives report creation. EGL support is available in JSF
handlers and in programs generated for Java.
To create and export a report using the JasperReports framework in EGL, follow
these general steps:
1. Create and compile a JasperReports report design file. See “Creating the
JasperReport design file” on page 534.
2. Write a report driver program. See “Writing code to drive a report of type
JasperReport” on page 538.
3. Optionally, create a report handler with additional functions that are called by
the report design file. See “Creating an EGL JasperReport handler” on page
541.
4. Generate the project and run the report driver program. See “Running a report
of type JasperReport” on page 545
EGL does not require that you perform these tasks in a particular order, but you
must be aware of dependencies between the files. For example, if your report
design file calls functions in the report handler, you must write and generate the
report handler first and then compile the report design file. EGL compiles the
report design file each time you save a change to the report design file, or you can
direct EGL to compile the report design file by clicking Project → Clean → Clean all
projects.
EGL does not automatically refresh exported reports. If you change the report
design or if the data used in the report changes, you must run the report driver
program again.
Related concepts
EGL reports
“Elements of an EGL JasperReport application” on page 533
The main elements of a JasperReport application in EGL are a program to run
the report and a report design file to control the layout of the report.
Additionally, a report handler can give you greater control over the data put
into the report.
Related tasks
The report design file is an XML file with a .jrxml extension that describes how the
report will look and where the data will be displayed. You can code the XML file
yourself or use a third-party tool. The workbench does not provide a graphical
way to create report design files.
When you have finished writing the report design file, EGL compiles it into a
.jasper file, which your report driver program uses to create the report. For more
information on the report design file and an example, see “Creating the
JasperReport design file” on page 534.
Generally, an EGL program does the work of populating the report with data and
exporting its output. The report driver program performs the following tasks:
v Creates a Report variable to represent the report
v Populates that report variable with a report design file and information about
where the completed report will go
v Creates a ReportData variable to represent the data in the report
v Connects to a data source, retrieves data for the report, and puts that data into
the ReportData variable
v Calls functions in the EGL library ReportLib to run and export the report
For an example of a report driver program, see “Writing code to drive a report of
type JasperReport” on page 538.
Report handler
The report handler is an EGL logic part that provides additional functions to be
executed when the report runs. You can define a function in the report handler and
then call that function from a specific place in the report design file. Also, the
report automatically calls functions in the report handler at certain points during
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
For more detailed information than you will find in this topic, see the following
Web site:
http://jasperforge.org
You can use a file with the .xml extension for your source, although this can slow
your compilation. JasperReports works best with the .jrxml extension.
<jasperReport name="simpleReport">
<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>
<textField>
<reportElement x="420" y="0" width="70" height="24" />
<textFieldExpression>
<![CDATA[$F{PHONE}]]>
</textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
This example report design file prints four columns of information: an ID number,
a first name, a last name, and a phone number. The <pageHeader> section prints
column headers, and the <detail> section prints rows of data based on the data
provided by the report driver program.
The following sections offer specifics for the different types of XML source files.
This information covers very simple cases; for more complex examples see either
the JasperReports Web site mentioned earlier or the documentation for your design
tool (if you decide to use one).
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
EGL places the compiled .jasper file in the Java Resources\package_name directory
that is parallel to EGLSource\package_name. When you successfully generate your
EGL report driver, the product places a linked copy of the .jasper file in the
parallel bin\package_name directory. You can manually create and copy the .jasper
file by selecting Project → Build All or Project → Clean.
The following example shows a report driver program that uses data from a
specified database connection:
program reportDriverProgram type BasicProgram
function main()
SQLLib.defineDatabaseAlias("customer",
"jdbc:derby:C:\\databases\\CustomerDatabase");
SQLLib.connect("customer", "admin", "admin");
reportLib.fillReport(myReport, DataSource.sqlStatement);
reportLib.exportReport(myReport, ExportFormat.pdf);
end
end
Because the backslash character (\) is used in escape sequences, you must use a
double backslash in path names.
Code Explanation
SQLLib.defineDatabaseAlias("customer", Connects to a database and defines an alias
"jdbc:derby:C:\\databases for the database using functions in the EGL
\\CustomerDatabase"); library SQLLib
SQLLib.connect("customer",
"admin", "admin");
myReport Report = new Report(); Creates a new report variable to represent
the report
myReportData ReportData = Creates a new report data variable to
new ReportData(); represent the data in the report
myReport.reportDesignFile = Sets the location of the .jasper file that is
location; compiled from the report design file
myReport.reportDestinationFile = Sets the location of a temporary file that is
location; used while processing the report
myReport.reportExportFile = Sets the location of the exported report
location;
myReportData.connectionName = Sets the database connection that the report
"customer"; uses, in terms of the database alias defined
earlier
myReportData.sqlStatement = Sets the database access statement that
SQL statement; provides the data for the report
myReport.reportData = myReportData; Associates the report variable with the
report data variable
reportLib.fillReport(myReport, Fills the report with data
DataSource.sqlStatement);
reportLib.exportReport(myReport, Runs and exports the report
ExportFormat.pdf);
The following code snippet shows how you might fill a report using your own
internal record as the data source. First, define a record like the following example,
somewhere outside the program:
Record myRecord type BasicRecord
author String;
description String;
title String;
end
recArray myRecord[];
recArrayElement myRecord;
function populateReportData()
recArrayElement.author="Jane Austen";
recArrayElement.title="Northanger Abbey";
recArrayElement.description = "British Novel";
recArray.appendElement(recArrayElement);
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);
The New EGL Report Handler wizard will give you a list of function names that
correspond to report fill events. For example, JasperReports will invoke
″beforePageInit()″ before entering a page. You must create the code for these
functions.
These few examples cannot address all the complexities possible in a report
handler. For more detail, see the JasperReports documentation.
// Use Declarations
use usePartReference;
// Constant Declarations)
const constantName constantType = literal;
// Data Declarations
identifierName declarationType;
function afterReportInit()
end
function beforePageInit()
end
function afterPageInit()
end
function beforeColumnInit()
end
function afterColumnInit()
end
function beforeDetailEval()
end
function afterDetailEval()
end
end
// Data Declarations
report_title String;
end
// Data Declarations
item_count int;
function afterDetailEval()
setReportVariableValue("itemCount", (item_count + 1));
end
end
You must match variable types in the report handler with those in your XML
source file.
// Data Declarations
employee_first_name String;
// Data Declarations
customer_array customerRecordType[];
c customerRecordType;
<subreport>
<dataSourceExpression>
<![CDATA[(JRDataSource)(((subreports.SubReportHandler)
$P{REPORT_SCRIPTLET}).getReportData( new String("saveCustomer")))]]>;
</dataSourceExpression>
<subreportExpression class="java.lang.String">
<![CDATA["C:/RAD/workspaces/customer_subreport.jasper"]]>;
</subreportExpression>
</subreport>
...
</jasperReport>
<summary>
<band height="40">
<textField>
<reportElement positionType="Float" x="0" y="20" width="500" height="15"/>
<textElement textAlignment="Center">
<font reportFont="Arial_Bold" size="10"/>
</textElement>
<textFieldExpression class="java.lang.String">
<![CDATA[((my_package.my_report_handler)$P{REPORT_SCRIPTLET}).hello()]]>
</textFieldExpression>
</textField>
</band>
</summary>
...
</jasperReport>
To create and fill a report for an EGL project, follow these steps:
1. Build the EGL project by clicking Project → Build or Project → Clean. EGL
automatically generates Java code from any EGL source files that have changed
since the last build and compiles any changed design document source files.
2. Run the Java program that contains the generated report driver program. One
way to do this in the Package Explorer view is to navigate to and right-click
the .java file that contains the code. Then select Run As → Java Application
from the menu.
When you create a report, the JasperReports engine first creates an intermediate
destination file (extension .jrprint), from which it can create multiple export files in
different formats (.pdf, .html, .xml, .txt, or .csv). You specify locations for all of
these files in the report driver.
Related concepts
“Creating reports with EGL” on page 531
EGL offers different ways to create reports, using external engines to generate
the report contents.
“Elements of an EGL JasperReport application” on page 533
The main elements of a JasperReport application in EGL are a program to run
To fill and export a report through JasperReports, choose any of these data sources
for the report:
v Database connection
v Custom report data
v Result object from a specified SQL query
To add a report handler template to your source file, follow these steps:
1. Open a new file in your text editor.
2. Type handler, then press Ctrl+space
3. The editor will replace the word ″handler″ with template code. Work through
the code and add statements for the functions that you want to use. For more
information, including code examples, see Creating an EGL report handler.
In complex cases you might need a report handler to provide data for the
subreport; see Creating an EGL report handler. In some simple cases, you can add a
subreport in two simple steps:
1. Add subreport code to the design file for the main report.
2. Create one or more design files for the subreport or subreports.
Here is an elementary example of how you can create a subreport and add it to
your report. Given a report that prints all the customers from the table
CUSTOMER, you can add a subreport that shows all invoices for each customer,
drawn from the table ORDERS.
1. This is a section of code from the main report design file. This code was
originally written to print one line for each customer in the table CUSTOMER.
Add the code shown in bold in the following example:
<queryString><![CDATA[SELECT * FROM ADMINISTRATOR.CUSTOMER]]></queryString>
<field name="CUST_NO" class="java.lang.Integer">
</field>
<field name="CUST_NAME" class="java.lang.String">
</field>
<detail>
<band height="100">
<subreport>
<reportElement positionType="Float" mode="Opaque" x="0" y="31"
width="709" height="12" isRemoveLineWhenBlank="true"/>
<subreportParameter name="CURRENT_CUST">
<subreportParameterExpression>
<![CDATA[$F{CUST_NO}]]>
</subreportParameterExpression>
</subreportParameter>
<connectionExpression>
<![CDATA[$P{REPORT_CONNECTION}]]>
</connectionExpression>
<subreportExpression class="java.lang.String">
<![CDATA[new String("C:\\workspace\\report_project\\bin
\\report_package\\my_subreport.jasper")]]>
</subreportExpression>
</subreport>
<textField>
<reportElement positionType="Float" x="57" y="11"
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
Adding Jasper report support adds JAR files to your project that enable EGL to
compile report design files. You only need to do this once for each project that uses
Jasper reports, and there is no need to remove support from a project.
You can add support for Jasper reports only to EGL projects, not to EGL Web
projects.
1. In the Project Explorer view, right-click your EGL project and then click
Properties. The Properties window opens.
2. In the Properties window, click EGL Project Features.
3. Under EGL Project Features at the right side of the window, select the EGL
with Jasper report support check box. If this check box is already selected,
leave it selected.
4. Click OK.
Alternately, you can enable Jasper report support in a new project. Select the EGL
with Jasper report support check box in the New EGL Project wizard. Selecting
this check box has the same effect as selecting the check box in the Properties
window.
To compile a report design file, EGL needs a Java compiler in your system’s PATH
environment variable.
Use a Java compiler with the same version as the version of Java you are using to
generate EGL. Follow these steps to tell what level of Java you are using:
1. Right-click an EGL project and then click Properties.
2. In the Properties window, click Java Compiler.
This page shows settings for the project’s Java compiler. By default, the Enable
project specific settings check box is cleared and the rest of the fields on the
page are disabled.
3. If the Enable project specific settings check box is selected, the version of Java
that you are using in this project is shown in the Compiler compliance level
field.
If you want to export reports in Portable Document Format (PDF), follow these
additional steps after adding support for Jasper reports:
1. Download the file iText-1.3.jar from the following Web site:http://
prdownloads.sourceforge.net/itext.
2. In the Project Explorer view, right-click your project and then click Properties.
3. In the Properties window, click Java Build Path.
4. On the Libraries tab, click Add External JARs.
5. In the JAR Selection window, select the iText-1.3.jar file that you just
downloaded and click Open.
Now the iText-1.3.jar file is listed under JARs and class folders on the build
path.
6. Click OK.
If you are creating reports in a Console UI application that is running in rich client
platform (RCP) mode, you must set the osgi.user.area system property to the
location where you want to store reports. Otherwise, reports will be created in the
product installation directory.
1. Click Run → Run. The Run window opens.
2. From the list of runtime configurations, expand Eclipse Application and then
click the run configuration for the program.
3. On the Arguments tab of the run configuration, add the following code:
-user "<location>"
In place of <location>, use the directory to which you want to generate the
reports.
4. Click Apply to save changes to the run configuration.
Related concepts
“Creating reports with EGL” on page 531
EGL offers different ways to create reports, using external engines to generate
the report contents.
“Elements of an EGL JasperReport application” on page 533
The main elements of a JasperReport application in EGL are a program to run
the report and a report design file to control the layout of the report.
Additionally, a report handler can give you greater control over the data put
into the report.
You can begin designing your output by opening the Report Design perspective of
the Workbench and creating a Report project. Alternatively, you can do all your
work in an EGL or Web project.
You create a report, which (in the context of your output-design work) is an XML
file whose default extension is .rptdesign. The steps are as follows:
1. Click File or right click on the project
2. Select New > Other
3. At the Select a Wizard dialog, choose Business Intelligence and Reporting Tools
> Report
4. Specify a parent folder and report name, and click Next
5. At the New Report dialog, select a template that will be the basis of your
report. Help is available if you press the question icon, and details on report
design will be displayed subsequently if you check Show Report Creation
Cheat Sheet.
6. Click Finish.
7. Your subsequent tasks include specifying a data source (for example, a JDBC
connection), specifying a data set (for example, the database columns specified
in an SQL SELECT statement), and using a palette to drag and drop elements
such as labels and tables. You can rely on the cheat sheet and can get a fuller
introduction to report design by accessing the tutorial and background detail at
the following Web site:
http://www.eclipse.org/birt
Working at the EGL or Web perspective, you create EGL code that drives output
creation. The creation can have two steps:
1. The report (hereafter called the design file) is converted to a second file, called a
document file, which has a default extension of .rptdocument and contains data
in an intermediate format
2. The document file is converted to the PDF or HTML output
You can use a cascading style sheet (CSS) to control display characteristics of the
report.
Related concepts
“Creating reports with EGL” on page 531
EGL offers different ways to create reports, using external engines to generate
the report contents.
Related tasks
You can add support for BIRT as you create a project. On the second screen in the
New EGL Project wizard, check Show Advanced Settings, and at the next screen,
select the EGL with BIRT report support check box.
Also, if you need to reference graphics that are stored in the BIRT resource folder,
click Windows -> Preferences ->Report Design -> Resource and specify the folder.
For additional details on graphics and BIRT, see ″External types in BIRT
report-layout event handler″; in particular, the section on ImageInstance.
If you want to export reports in Portable Document Format (PDF), you have an
additional step after adding support for BIRT reports.
Before you can work with BIRT, you need to download BIRT runtime code and set
the birtEngineHome build descriptor option, but only if you are working in a
General project. Here are the steps:
1. Go to http://www.eclipse.org/birt
2. Access the runtime code of interest. At this writing, the procedure is as follows:
a. On the left of the page, click Download
b. At the next page, go to the More Downloads section and click Recent
Builds Page
c. At the next page, go to the Latest Releases section and, in the Build Name
column, click 2_3_0
d. At the next page, go to the Report Engine section and click
birt-runtime-2.3.0.zip
e. At the next page, click a mirror location and follow the displayed
instructions to download the code
Note: Rational Business Developer 7.5 supports BIRT version 2.3.0 and no
others.
3. Unzip the downloaded code into a directory of your choice; for example,
C:\birt
4. In the project build descriptor, set the birtEngineHome option to the fully
qualified path of the ReportEngine directory; for example, C:\birt\birt-runtime-
2_3_0\ReportEngine
To deploy code that runs a BIRT report, ensure that you deploy a set of jar files
that are found in the ReportEngine\lib subdirectory of the directory that contains
the BIRT runtime code; for example, in C:\birt\birt-runtime-2_3_0\ReportEngine\
lib.
For an overview of EGL support for BIRT, see ″Creating reports with BIRT.″
Related concepts
“Creating reports with BIRT” on page 551
Business Intelligence and Reporting Tools (BIRT) is an Eclipse-based reporting
system that allows for sophisticated output in PDF or HTML format, including
graphics, tables, graphs, and charts. EGL support for BIRT is available when
you code either JSF handlers or programs generated for Java.
Related tasks
“Creating an EGL BIRT handler” on page 555
An EGL BIRT handler (that is, an EGL handler of type BIRTHandler) contains
functions that are invoked when EGL is creating a report document. The
process of creating a BIRT handler is to create a source file and, within that file,
to code the handler. For details on what to code, see ″EGL BIRT handler″ in the
Reference Guide.
“Adding support for BIRT reports to a project” on page 553
Before your EGL code can create BIRT reports, you must add support to your
project. You need to add support only once for each project, and you do not
need to remove support if you stop using BIRT reports. During this beta,
support is available for General and Plug-in projects.
Related reference
BIRT Reports
Central to EGL’s support for Business Intelligence and Reporting Tools (BIRT) is
the external type called BIRTReport. This topic describes how to create a
variable of that type and how to use it to create output.
EGL BIRT handler
An EGL BIRT handler part contains event handlers, which are functions
invoked during report creation. For an overview of EGL support for BIRT, see
″Creating reports with BIRT″ in the Programmer’s Guide.
The following steps provide a broad overview of the process of creating an EGL
text report:
1. Create a basic Handler part. This program performs the following actions:
v It declares a report variable that has access to the functions and variables of
the report engine (the Java class). The declaration can optionally change
For a sample text report program and handler, see “Writing code to print a text
report” on page 558.
The text report engine includes functions for most of the tasks that you perform in
the handler, including functions to start and finish the report, to print lines, text, or
white space, to manage headers and footers, and more. For a complete list of these
functions, see Text report functions.
For more information on converting existing I4GL reports to EGL, refer to the IBM
Informix 4GL to EGL Conversion Utility User’s Guide.
Related concepts
“Creating reports with EGL” on page 531
EGL offers different ways to create reports, using external engines to generate
the report contents.
“Handler events for a text report”
The TextReport external type defines the events that a basic text report handler
can react to.
“Writing code to print a text report” on page 558
This topic provides a sample text report program and handler.
Text report functions
Each event is a variable that you reference through the text report variable. You
can code a function for any of these events. The text report engine calls the
corresponding function whenever the event occurs. Use a simple EGL assignment
statement in the handler to associate a function with an event, as in the following
example:
myReport.onFirstPageHeaderListener = printHeader1;
If you assign a function name to one of these event variables, you must create a
matching function in the handler. The matching functions must have a single
argument, a TextReportEvent type variable.
For a complete list of event variables, see Text report variables. For a sample text
report program and handler, see “Writing code to print a text report” on page 558.
Related concepts
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.
myCustomer CustomerRecord;
myHandler textReportHandler{};
function main()
myHandler.start(); // passes control to handler
function start()
myReport.onEveryRowListener = onEveryRow;
myReport.onLastRowListener = onLastRow;
function finish()
// pass control to the report engine again
// onLastRow is called
myReport.finishReport();
end
The central idea of Web transactions is similar to the one behind Text UI:
v A VGWebTransaction program (comparable to a Text UI program) presents a
Web page for user input.
v The Web page is based on a VGUIRecord (comparable to a Text UI form). EGL
transforms fields in the record into controls on the Web page, using field
properties to determine the type of control to create.
When generating COBOL, EGL simply includes the VGUIRecord in the compiled
program. When generating Java, EGL creates the following JSP files:
v filename.jsp, for each VGUIRecord file, where filename.egl is the source file
name.
v EGLWebStartup.jsp, a Web page that displays a list of your VGWebTransaction
programs. You select a program and run it from this page rather than running
the associated filename.jsp page.
v CSOERRORUIR.jsp, the error page that you customize to report on TCP/IP
communication problems and on problems internal to a Web transaction.
v Vagen1EntryPage.jsp, the default selection list for EGLWebStartup.jsp.
v A series of sample files that show how to perform common tasks:
– reqPage.jsp
– usrMsgPage.jsp
– Vagen1ErrorPage.jsp
– Vagen1ExpiredPasswordPage.jsp
– Vagen1LogonPage.jsp
You can customize these JSP files using Page Designer (see “Using EGL with the
Eclipse IDE” on page 1).
To run Web transactions in EGL, you must perform the following steps:
1. Modify configuration files (see “Web transaction configuration files” on page
563).
2. Get a Web server running in your workspace (see “Adding a Web server” on
page 393).
3. Customize Vagen1EntryPage.jsp to list your VGWebTransaction programs (see
“Running VGWebTransaction programs” on page 564).
4. Launch your programs through EGLWebStartup.jsp (see “Running
VGWebTransaction programs” on page 564).
Add support for Web transactions at the time you create a project:
v Create a new EGL Web project and select the Show Advanced Settings check
box on the general settings page of the New EGL Project wizard.
v Select the EGL support with Legacy Web Transactions check box on the Project
Facets page. The Project Facets page is the second page after the general settings
page.
Add support for Web transactions to an existing EGL Web project:
1. In the Project Explorer view, right-click the EGL Web project and then click
Properties. The Properties window opens.
2. In the Properties window, click Project Facets.
3. Click Add/Remove Project Facets.
4. In the Project Facets window, select the EGL support with Legacy Web
Transaction check box.
5. Click Finish.
6. Click OK.
Adding support for Web transactions makes the following changes to the project:
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
You will have to edit the csogw.properties file (or whatever file you use to specify
your linkage) before your programs will run properly. The following instructions
cover the simplest case; for more complex cases, and for more information, see
″Web transaction linkage properties″ in the EGL Generation Guide.
1. You can configure the file to look for your Web transaction programs in
different locations depending on the file name. In this example, assume all your
files are located in a single local directory. The asterisk in the following line is a
wildcard that represents any character or string of characters:
application.*=allfiles
2. You have now associated the name allfiles with any application EGL is
looking for. Tell EGL that the files are local with the following line:
You do not directly run either a VGWebTransaction program or a JSP file based on
a VGUIRecord. Instead EGL manages the interaction between the program, the JSP,
and the related bean by means of a Web page, EGLWebStartup.jsp, that is
generated for you automatically when you associate the project with runtime Web
server.
Most UI controls involve setting the uiType property to one of the following
values:
v input
v inputOuput
v output
10 SELECTEDID int {
uiType = none
};
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
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
The following example shows a field that generates a <FORM> tag and all
associated contents on the browser:
10 MYFORM01 char(60) {
displayName = "MyForm01",
uiType = uiForm,
@programLinkData {
programName = "DEST_PGM",
uiRecordName = "DEST_PGE",
newWindow = no,
linkParms = [
@linkParameter { name = "PARM", value="ParmData" }
]
}
};
Substructure fields below MYFORM01 declare fields within the form, such as any
of the input or output controls shown earlier, or the following submit button:
20 BUTTON1 char(8) {
displayName = "Submit",
uiType = submit
} = "SUBMIT";
When the user submits the form, The VGWebTransaction program calls the
program in the programName property using the show command. For information
about how field values are passed to the called program, see ″show″ in the EGL
Language Reference.
Related concepts
“Working with Web transaction applications in EGL” on page 561
Related reference
show considerations for Web transactions
JavaServer Pages (JSP files) are ASCII files that have a .jsp suffix and contain a
mixture of HTML tags and JSP syntax. A Web application server transforms a JSP
file into a Java servlet by a process known as page compilation.
Scriptlets
Pieces of Java code called scriptlets can be inserted into JSP files. Scriptlets can be
placed anywhere in the JSP source. At run time, the Java code in the scriptlet runs
on the server side, but the Java code itself is not included with the HTML sent to
the browser. Methods specific to UI record beans are covered in “UI record bean
API” on page 570.
In this way, scriptlets let you access data in the VGUIRecord and use that data on
the page. For specific methods for accessing a UI record bean, see “UI record bean
API” on page 570.
Bean tags
The JSP file created to go along with the VGUIRecord references a UI record bean.
This UI record bean gives the scriptlets in the JSP access to the data in the
VGUIRecord. The JSP file references this bean with the <jsp:useBean> tag.
For example, the following code references a bean to be used in a JSP file:
<jsp:useBean id="referenceName"
class="beanClassName"
type="interfaceName"
scope="beanScope" />
referenceName
The name of the bean. Other scriptlets in the JSP file can use this bean by
referring to its name as defined in the <jsp:useBean> tag.
beanClassName
The fully qualified class name of the bean, such as java.lang.String.
interfaceName
A interface implemented by a bean. This attribute is optional.
beanScope
The scope of the bean. Valid values are:
session
The bean is stored in the HttpSession object.
request
The bean is stored in theHttpServletRequest object.
page The bean is stored in the JSP page context.
application
The bean is stored in the servlet context.
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.
The String class is used by all get and set methods implemented for variables with
a uiType property of input, output, or inputOutput in the Java Bean generated for
the UI record.
Set and get methods implemented for variables that are defined with a uiType of
none return the appropriate Java class for the variable.
The get and set methods implemented for the UI record bean are described in this
section. These methods get and change information about the VGUIRecord as a
whole.
String getTitle();
Returns the default title of the page from the title property of the
VGUIRecord.
String getHelpText();
Returns the text from the help property of the VGUIRecord.
String getGatewayURL();
Returns the gateway URL and is used as the ACTION of an HTML form.
VGDataElement Interface
The debugger uses JDBC for SQL access, which creates the following differences
from running on environments where JDBC is not used:
v JDBC does not support two-phase commit. There are separate calls to the SQL
manager and MQ series manager for commit and rollback. Therefore, if a
problem occurs, it is possible for one resource to commit or rollback without the
corresponding commit or rollback for the other resource.
v JDBC always runs dynamic SQL. Generated COBOL uses static SQL except
when you use the EGL prepare statement or a table name host variable
(tableNameVariables property in the SQLRecord definition). Therefore, there are
the following differences:
– In dynamic mode, single row select can result in more than one row being
returned without setting sysVar.sqlData.sqlCode to -811. As long as there is
only one row that satisfies the criteria you do not notice a difference. See the
following sample technique for how you can address this difference if it is
important to you.
– JDBC converts data that is defined on the host as a CHAR, DBCHAR, or
MBCHAR SQL column with the ″FOR BIT DATA″ option. If you have this
situation, set the asBytes property to YES for the field that corresponds to the
SQL column that is defined as ″FOR BIT DATA″.
The following limitations also apply to both Debug and Java programs. There is a
difference between Debug and generated COBOL programs, but no difference
between Debug and generated Java programs:
v Be sure to use the DATE, TIME, and TIMESTAMP primitive types when
defining fields for SQL columns that contain these types. You can use the CHAR
primitive type, as long as the CHAR variable has the sqlDataCode property set
to indicate the type of the SQL column. You can also use CHAR without the
There is a technique you can use when the debug environment is different from
the host environment: In the EGL -> Debug preferences, select Set systemType to
DEBUG. In the EGL program you can include logic such as the following:
if (sysVar.systemType is debug)
// do nothing
else
// check for sysVar.sqlData.sqlCode = -811
end
This enables you to include system-specific logic that is only valid on the host
system.
For information on the keyboard differences, see the EGL function key mapping
table in validationBypassKeys or helpKey.
Debugging programs
To debug programs that do not run under JEE, you can start the debug session as
described in “Stepping through an application in the EGL debugger” on page 575.
The debugger always starts debugging from a program part. If you want to debug
another logic part, such as a library, you must step into the other logic part from a
program. In some cases you might benefit from writing a simple program with no
other function than to call the logic part that you want to debug.
Prerequisites
v An EGL project
v An EGL program to debug
The following example provides a program with a simple error that you can use to
test the debugger:
program myDebugTestPgm type BasicProgram
function main()
counter int;
orderTotal float=0;
return (quantCost);
end // function discountPrice
end // program
If you generate this program and run it, EGL will return an error pointing to the
discountPrice function and the expression 1/0. In this case, the error is easy to
see, but in other cases you might not be able to find the error so easily. Your first
step in identifying the source of the error might be to run the program in the
debugger with breakpoints to find where the program fails.
Adding breakpoints
You can mark one or more lines of code as breakpoints. When the debugger
encounters a breakpoint, it pauses before running the associated line of code. You
then have the option of checking the current values of program variables before
telling the debugger how to proceed. Breakpoints do not affect the generated
source in any way; they are meaningful only during the debugging process.
To add a breakpoint, double-click the gray margin to the left of the code in the
EGL editor. In the previous example, you might want to add breakpoints
throughout the discountPrice function because the error tells you that this
576 EGL Programmer’s Guide
function is where the error occurred. Breakpoints are marked with blue circles in
this gray area:
You can add a breakpoint at most lines of EGL code that conduct logic, including
the following examples:
v An assignment statement, such as:
myString = "Hello";
v A variable declaration that includes an assignment, such as:
myInt int = 5;
v A call to a system function or other EGL function, such as:
SysLib.writeStderr("Hello");
v A loop or comparison statement, such as:
if (myInt == 5)
For more instructions on using breakpoints, see “Using breakpoints in the EGL
debugger” on page 584.
You can debug a program without using breakpoints. If you check the preference
Window → Preferences → EGL → Debug → Stop at first line of a program, it has the
same effect as setting a breakpoint at the first executable line inside the main()
function of the program. From this point you can step through or around
succeeding lines of code, that is, execute a single line and pause. For more on the
step commands, see “EGL debugger commands” on page 580.
After you have added breakpoints to your program, or set the Stop at first line
option (see ″Adding breakpoints″ earlier in this topic), you can run it in the
debugger.
The debugger requires a launch configuration to describe how it will run the
application. There are two ways to create a launch configuration:
v Have the debugger to create a launch configuration automatically when you
start debugging.
v Create a launch configuration manually. See “Creating a launch configuration in
the EGL debugger” on page 588 for more information.
For most programs, you can use the automatically created launch configuration.
1. In the Project Explorer view, right-click the EGL source program that you want
to debug and then click Debug EGL Program. The debugger performs the
following tasks:
v If no launch configuration exists for the program, the debugger creates a
default launch configuration. You can view this configuration by clicking
Run → Debug.
v Depending on your workbench preferences, the debugger might switch to
the Debug perspective automatically or prompt you to do so. You can switch
perspectives manually by clicking Window → Open Perspective → Other →
Debug.
v The debugger begins running the program.
2. After the debugger has started running the program, it continues until it
encounters a breakpoint, or, if you have set the preference for it, finds the first
line of executable code. At this point, the debugger pauses and displays the
following information:
v The EGL editor highlights the line about to be executed.
v The Variables view shows the value of all the variables in the current logic
part, including the value of system variables. You can use this view to track
the value of a variable through the program. You can also change the value
of a variable while the debugger is paused at a breakpoint.
v The Debug view lists the threads running within the current run unit. In
simple terms, this view shows which program or logic part is currently
running. Use this view to resume or stop the debugging process.
v The Breakpoints view lists the breakpoints in the program. From this view,
you can disable a breakpoint temporarily by clearing its check box.
3. When you want the debugger to continue, click the Resume button at the top
of the Debug view. The debugger continues to the next breakpoint. You can
also use one of the Step buttons to see the program execute the next line and
pause again.
In the example program, you can run the program from breakpoint to
breakpoint until the debugger reaches the line discountRate = 1/0;, at which
point the debugger returns the same error that you see in the console when
running the program.
4. When you are finished debugging, click the Terminate button at the top of the
Debug view to stop the debugger or allow the program to finish running.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging
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.
For details on Rich UI, see Rich UI debugging. Otherwise, the EGL debugger selects
the build descriptor in accordance with the following rules:
v If you specified a debug build descriptor for your program or JSF Handler, the
EGL debugger uses that build descriptor. For details on how to establish the
debug build descriptor, see Setting the default build descriptors.
v If you did not specify a debug build descriptor, the EGL debugger prompts you
to select from a list of your build descriptors.
v If the build descriptor you specified lacks any required database-connection
information, the EGL debugger gets the connection information by reviewing
your preferences. For details on how to set those preferences, see “Setting
preferences for SQL database connections” on page 219.
If you are debugging a program that you intend for use in a text or batch
application in a Java environment, and if that program issues a transfer statement
that switches control to a program that you also intend for use in a different run
unit in a Java environment, the EGL debugger uses a build descriptor that is
assigned to the receiving program. The choice of build descriptor is based on the
rules described earlier.
If you are debugging a program that is called by another program, the EGL
debugger uses the build descriptor that is assigned to the called program. The
choice of build descriptor is based on the rules that are described earlier, except
that if you do not specify a build descriptor, the debugger does not prompt you for
a build descriptor when the called program is invoked; instead, the build
descriptor for the calling program remains in use.
Note: You must use a different build descriptor for the caller and the called
program if one of those programs (but not both) uses VisualAge Generator
compatibility. The generation-time status of VisualAge compatibility is
determined by the value of the vagCompatibility build descriptor option.
A build descriptor or resource association part that you use for debugging code
might be different from the one that you use for generating code. For example, if
you intend to access a VSAM file from a program that is written for a COBOL
environment, you are likely to reference a resource association part in the build
descriptor. The resource association part must refer to the runtime target system
(for example, zOS) and must refer to a file type (for example, vsamrs) that is
appropriate for the target system. The debug situation differs from the generation
situation as follows:
v At generation time, the resource association part indicates the system name of
the file that is used in the target environment.
v At debug time, the system name must reflect another naming convention, as
appropriate when you access a remote VSAM file from an EGL-generated Java
program on Windows 2000, NT, or XP; for details on that naming convention,
see your VSAM support documents.
In addition to the system build descriptor option, a value for system type can be
set in sysVar.systemType. Also, a second value is available in
vgLib.getVAGSysType if you requested development-time compatibility with
VisualAge Generator).
The value in sysVar.systemType is the same as the value of the system build
descriptor option, except that the value is DEBUG in either of two cases:
v You select the preference Set systemType to DEBUG, as mentioned in “Setting
preferences for the EGL debugger” on page 604; or
v You specified NONE as the build descriptor to use during the debugging
session, regardless of the value of that preference.
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.
To add or remove a single breakpoint in an EGL source file you can do either of
the following:
v Position the cursor at the breakpoint line in the left margin of the Source view
and double-click.
To disable or enable a single breakpoint in an EGL source file, follow these steps:
1. In the Breakpoint view, right-click on the breakpoint. A menu opens.
2. Click either Enable or Disable.
To remove all breakpoints from an EGL source file, follow these steps:
1. Right-click any breakpoint that is displayed in the Breakpoints view. A menu
opens.
2. Click Remove All.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging
Related tasks
“Creating a launch configuration in the EGL debugger” on page 588
“Starting a non-JEE application in the EGL debugger” on page 590
“Stepping through an application in the EGL debugger” on page 575
This topic offers guidance on the basic steps of debugging a program in the
EGL debugger.
“Viewing variables in the EGL debugger”
This topic shows you how to view variables in your program while your are
debugging your programs.
Prerequisites
v An EGL project
v An EGL program or other logic part that needs debugging
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.
If hotswapping is enabled and you change a function that is on the function stack,
the debugging session continues at the first line of the changed function.
Compatibility
Table 57. Compatibility considerations for hot swapping
Platform Issue
Rich UI Hot swapping is not supported. Similarly, the EGL debugger
does not respond to changes made to variable values in the
Variables view.
Related concepts
“Starting the EGL debugger for EGL projects” on page 588
Start the debugging process by creating a launch configuration.
“EGL debugger commands” on page 580
Rich UI debugging
Related tasks
To start the debugging process outside of Rich UI you need a launch configuration.
You can create a launch configuration yourself, but the EGL debugger creates one
automatically if you do not create one.
To start the EGL debugger and have it create a launch configuration for you, see
“Starting a non-JEE application in the EGL debugger” on page 590. To create a
launch configuration yourself, see “Creating a launch configuration in the EGL
debugger.” If you are debugging an EGL application that is called from an
EGL-generated Java application or Java wrapper, you must create a special kind of
launch configuration called an EGL Listener launch configuration. To create one,
see “Creating an EGL Listener launch configuration” on page 589.
Related concepts
Rich UI debugging
Related tasks
“Starting a non-JEE application in the EGL debugger” on page 590
“Creating a launch configuration in the EGL debugger”
“Creating an EGL Listener launch configuration” on page 589
To start a program using a launch configuration that you create yourself, follow
these steps:
1. Click Run → Debug. The Debug window opens.
2. In the left pane of the Debug window, click EGL Program.
3. Click the New launch configuration at the top of that same pane. A new
launch configuration is displayed below the EGL Program heading. The
Launch tab is initially displayed.
4. In the Name field, type a name for the launch configuration. By default, the
launch configuration has the same name as the program, unless a
configuration already exists for this program.
5. In the Project field of the Load tab, type the name of your project.
6. In the EGL program source file field, select the program that you want to
debug.
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.
Note: You can also display the Debug dialog by clicking Run → Debug.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging
Different rules apply when the called program to be debugged does not run in JEE.
When this is the case, the caller of the program might be running anywhere,
including on a remote system. Follow these steps:
1. Start a listener program. Start a listener by using an EGL Listener launch
configuration that has only one configurable setting, a port number. The default
port number is 8346.
2. If multiple EGL Listeners are running at the same time, you must specify a
different port for each EGL Listener. You might also need to specify a different
port if port 8346 is being used by another application or if a firewall prevents
use of that port. To specify a different port number, see “Creating an EGL
Listener launch configuration” on page 589.
Related tasks
Before you can debug an EGL Web application, you must configure the server for
debugging. This needs to be done only once; see Configuring a server for EGL
debugging. This process will restart the server in Debug mode. To begin debugging,
see Starting an EGL Web debugging session.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging
Related tasks
“Configuring a server for EGL Web debugging”
“Starting an EGL Web debugging session” on page 594
EGL Debug is the default debugging mode. If you want to debug generated Java
code rather than the EGL JSF handler, see ″Debugging Java code″ later in this
topic.
For IBM WebSphere Application Server, version 6.1, the process is more
complicated. Right-click the server name in the Server view and choose Run
administrative console. In the left menu pane of the Integrated Solutions Console,
expand Servers, and click Application servers. The console displays a list of
servers; click yours. On the Configuration tab of the next page, the last group of
options is headed Additional Properties. Under this heading, click Debugging
Service. On the Debugging Service page, add the following (with a space
afterwards) to the beginning of the string in JVM debug arguments:
-Degl.jsfhandler.debug=false
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.
myAddingMachine additionService
function main()
sumint int;
sumint = myAddingMachine.addInts(5, 12);
SysLib.writeStdOut("result = " + sumint);
end
end
6. Set a breakpoint at the service call. See “Using breakpoints in the EGL
debugger” on page 584.
7. Set breakpoints in the service, as you would in any logic part.
8. Debug your new EGL source program. At the breakpoint before the service call,
step into the service code. The debugger pauses at the breakpoints in the
service just as in any other logic part.
Related concepts
“Debugging EGL applications” on page 573
Rich UI debugging
Related tasks
“Calling a local service” on page 483
You can call an EGL or native service that is local to your application without
exposing that service as a Web service.
“Using breakpoints in the EGL debugger” on page 584
This topic shows you how to use breakpoints in debugging your programs. You
can manage breakpoints inside or outside of an EGL debugging session.
“Stepping through an application in the EGL debugger” on page 575
This topic offers guidance on the basic steps of debugging a program in the
EGL debugger.
Debugging SQL and DL/I programs is available for IMS only. The debugger makes
database calls to the host, but otherwise interprets the code on the local client
system. For information on starting the debug server, see “Starting the DLI Debug
Server on the z/OS host” on page 601.
Prerequisites
The following applications are required on the host for debugging:
v TCPIP
v DB2 v.7 or higher
v IMS v.7 or higher
– Open Database Access (ODBA)
v Resource Recovery Services (RRS)
v Workload Manager (WLM)
The IMS debugger uses ODBA to talk to the database capabilities in IMS.
RRS/MVS (Resource Recovery Services) is required; OS/390® Release 3 is the
minimum level that can support the ODBA interface.
The source files in this section are available as part of the Rational COBOL
Runtime for zSeries package.
The value comes from the JCL that you use to start
IMS. The IMS JCL parameter should look like this:
IMSID XXXX IMS SUBSYSTEM IDENTIFIER
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
Syntax
You start a debug server by using z/OS JCL commands. The syntax for the
parameters line is as follows:
'
-n n -q q -t
where
-p Specifies the port number (portno) to which the server listens to communicate
with the clients.
-V Specifies the verbosity level of the server. You may specify this parameter up
to three times (maximum verbosity).
-a Specifies authentication mode:
0 Server state: A or U (unauthorized). If U, APF-authorized build
programs will fail. If you specify a TSO user ID and password, the
server ignores them and the build transaction is performed under the
access and authority of the user ID assigned to the build server job.
-n Specifies the number of concurrent builds. The default is 1. Set n equal to the
number of concurrent builds you want to allow. Once there are n number of
concurrent builds running, the build server queues any additional requests and
submits them on a first come first served basis as builds are completed.
-q Specifies the size of the queue (q) for clients. The default is 10. Each queued
client uses a TCP/IP socket. Therefore setting this too high may require more
sockets than are available, causing unpredictable results. If the queue is full,
subsequent clients are rejected by the server. However, the build client retries
the build in that case.
-t Starts tracing of this server job and writes output to STDOUT. This parameter
is normally used only for debugging.
Procedure
Modify the proxy job JCL to match your system configuration.
The JCL to start a proxy on the host is contained in the file named
EZEDBGPX.JCL. You must modify the STEPLIB portion of the JCL to match your
system configuration.
//jobcard
//*------------------------------------------------------
//RUNPGM EXEC PGM=EZEDBPXY,DYNAMNBR=30,TIME=NOLIMIT,
// PARM='&PARM;'
//* Avoid changing the PARM statement. The &PARM; keyword will
//* be replaced by parameters.
//STEPLIB DD DSN=ELA.V6R0M1.SELALMD,DISP=SHR
// DD DSN=ELA.V6R0M1.SELADBGL,DISP=SHR
// DD DSN=IMS.SDFSRESL
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=*
Note: In this case, the build script can also specify non-APF authorized programs.
However, in a multistep JCL script, an authorized program cannot be
executed after an unauthorized program.
If the server is not started from an APF-authorized library, the build script can
specify only non-APF authorized programs as executables.
Language Code
Brazilian Portugese ptb
Chinese, simplified chs
Chinese, traditional cht
English, USA enu
French fra
German deu
Also, the components that invoke the build server may need to issue messages if
communication with the build server fails. To return those messages in a language
other than English, change the setting of the environment variable
CCU_CATALOG on the client machine. The value of CCU_CATALOG is a string
like the following (on a single line):
shared_resources\eclipse\plugins
\com.ibm.etools.egl.distributedbuild_version\executables\ccu.cat.xxx
shared_resources
The shared resources directory for your product, such as C:\Program
Files\IBM\SDP70Shared on a Windows system or /opt/IBM/SDP70Shared on a
Linux system. If you installed and kept a previous version of an IBM product
containing EGL before installing your current product, you may need to
specify the shared resources directory that was set up in the earlier install.
version
The installed version of the plugin, including three numbers separated by
periods, a string separator, and the date and time that the plugin was built; for
example, 7.0.0.RFB_20070120_1300. If more than one is present, use the one
with the most recent version number, unless you have a reason to use an older
version.
xxx
The code for the language of interest; one of the codes listed in the previous
table
Related tasks
“Debugging IMS and DL/I applications” on page 596
Debugging applications that run remote IMS programs or that access data from
a DL/I database requires configuration of both the host and the local
workspace.
The EGL debugger supports two different types of character encoding: the default
encoding on your local system and Extended Binary Coded Decimal Interchange
Code (EBCDIC). The default character encoding for the EGL debugger is the same
as your local system’s default encoding.
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
There are two pages of preferences for the EGL debugger. The first contains
general preferences, and the second contains a list of programs or services that you
want to debug in the generated code (Java or COBOL), as described in Debug
behavior mapping in this topic.
The only preferences used for debugging Rich UI applications are as follows:
v Stop at first line of a program
v Set systemType to DEBUG
v In the Default behavior mapping dialog box, the settings in the Service
Reference tab
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.
If a value other than 8345 is specified as the EGL debugger port and if an EGL
program will be debugged on the J2EE server, you must edit the server
configuration:
1. Go to the Environment tab, System Properties section.
2. Click Add.
3. In the Name field, type com.ibm.debug.egl.port.
4. In the Value field, type the port number.
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.
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
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.
All statements regarding IBM’s future direction or intent are subject to change or
withdrawal without notice, and represent goals and objectives only.
This information contains examples of data and reports used in daily business
operations. To illustrate them as completely as possible, the examples include the
names of individuals, companies, brands, and products. All of these names are
fictitious and any similarity to the names and addresses used by an actual business
enterprise is entirely coincidental.
COPYRIGHT LICENSE:
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.
However, this information may also contain diagnosis, modification, and tuning
information. Diagnosis, modification and tuning information is provided to help
you debug your application software.
Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the
United States, other countries, or both.
UNIX is a registered trademark of The Open Group in the United States and other
countries.
Index 615
logic parts (continued)
EGL overview 105
O preferences (continued)
Rich UI appearance 347
EGL version 7.0 28 onConstructionFunction EGL services 498
Interface function 411 source styles 179
creating from service or external onPostRenderFunction EGL function 411 SQL database connections 219
type 116 onPreRenderFunction EGL function 411 SQL retrieve 220
remote services 115 OSLINK parameter format 257 text
JSF Handler overloaded functions 107 EGL overview 180
EGL preferences 465 Text UI
Library editor 510
sharing functions 110 P editor bidirectional text 511
service packages editor palette 512
service oriented architecture 113 creating 89 primitive types
Service import statements 124 C data types compared 145
creating from called program 114 overview 87 mapping EGL to C 132
creating WSDL from 119 Page Designer primitives
bindings 389 EGL data parts 97
support 389 EGL data types 98
M page lifecyles print forms
displaying records in EGL 507
manual changes EGL functions 411
pages procedures
EGL version 7.0 54
commands when pages load 411 calling in EGL 212
menus
parts Program Communication Block (PCB)
creating popups in EGL 507
EGL in DL/I (EGL) 221
enabling capabilities in EGL 11
ExternalType 117 program EGL logic part
message input descriptor (MID)
Record parts 100 description 105
estimating size 318
searches 168 program parts
format (EGL) 289
version 7.0 28 Interface 115
message output descriptor (MOD)
version 7.1 14 service 113
estimating size 318
generatable in EGL Program Specification Block (PSB)
format (EGL) 289
description 96 in DL/I (EGL) 221
message queues
introduction 95 scheduling (EGL) 301
print files as (EGL) 322
properties program-to-program message switches
serial files as (EGL) 320
introduction 122 in IMS/VS (EGL) 275
message switches
references 171 in IMSADF II (EGL) 293
in IMS/VS (EGL) 275
renaming in EGL 120 programming tasks
in IMSADF II (EGL) 293
searching for 168 completing in EGL 127
migrating
viewing lists in EGL 170 programs
EGL previous version 38
Parts List view EGL debugger 575
migrating EGL code
EGL 168 starting in the EGL debugger 590
version 6.0 iFix 001 56
Parts Reference view Project Explorer view
version 7.0 43
EGL EGL 168
manual changes after
generatable logic parts 171 Project Interchange
migration 54
searches 168 project sharing 81
migration
passwords projects
preferences
encryption in EGL 146 adding BIRT reports support 553
EGL-to-EGL 42
pop functions adding Jasper reports support 549
migration tool
C 141 converting to EGL plug-in 74
EGL version 7.0 44
popup forms creating
migration tool changes
creating in EGL 506 EGL plug-in 74
EGL version 6.0 iFix001 57
popup menus EGL Web 73
move statements
creating in EGL 507 overview 71
EGL version 7.0 migration 44
preferences debugging in EGL 588
moving parts
build descriptors 174 EGL application artifacts 67
EGL 121
EGL EGL database options 189
MPP (message processing program)
debugger 604 facets 76
generating programs for (EGL) 307
setting 173 features 76
Web applications 465 features and facets 76
EGL editor linking in the EGL build path 84
N folding 176 new EGL projects 173
navigation rules formatter 177 overview 70
EGL Web pages 408 import organization 178 renaming 75
null overview 175 sharing in EGL
testing for in SQL (EGL) 196 fonts 176 overview 79
numeric types generation 180 repositories 82
EGL primitives 98 overview 172
Rich UI 345
Index 617
spaSize (EGL) 276 templates (continued) user interface
spaStatusBytePosition (EGL) 276 removing in EGL 163 EGL version 7 updates 37
SQL restoring defaults in EGL 163 EGL version 7.1 updates 17
connection preferences 219 text user interface (UI) parts
database connections localizing 426 editing 500
changing 205 preferences JSF Handler
creating 197 setting in EGL 180 EGL preferences 465
runtime connections 203 Text Form editor user interfaces
EGL supported database filtering EGL console 516
managers 200 Text UI 509 user sessions
explicit 211 overview 500 data storage for EGL Web pages 424
explicit statements (EGL) 195 Text UI
implicit statements bidirectional text preferences 511
description (EGL) 194
null (EGL) 196
display options 510
palette preferences 512
V
validation
Record parts (EGL) 193 preferences 510
changes in EGL version 7.0 24, 26
retrieve feature 205 text forms
validation changes
retrieve preferences 220 displaying records in EGL 507
EGL version 7.0 24, 26
SELECT statements text strings
variable fields
validating 217 constant fields in EGL
creating with EGL parts
statements Text UI 502
Text UI 503
working with 211 Text UI
variables
stored procedures in EGL 212 editor
binding JSF controls to EGL
working with data in EGL 190 bidirectional text preferences 511
elements 394
SQLRecord parts display options 510
binding JSF controls to EGL
in prepare statements 215 palette preferences 512
variables 401
stereotypes preferences 510
binding to services 491
EGL Record 100 Text UI programs
EGL
storage in IMS (EGL) 307
arrays 103
data processing tasks 183 time types
binding to Web page controls 397
STRING arrays EGL primitives 98
viewing in the EGL debugger 585
binding JSF controls to EGL trademarks 611
VGWebTransactions EGL part
variables 401 transferring control
forwarding control 569
style classes CICS environment
VisualAge Generator
changing from EGL JSF using call (EGL) 254
compatibility preferences 173
Handlers 459 using transfer statement
VisualAge Generator Web transactions
styles (EGL) 261
forwarding control in EGL 569
changing JSF controls with EGL IMS BMP environment
code 458 using transfer statement
subreports (EGL) 270
creating 547 IMS BMP environments W
substrings using call (EGL) 267 Web applications
creating 146 IMS/VS environments debugging in EGL 588
Swing mode using call (EGL) 267 EGL debugger 592
overview 529 using transfer statement EGL elements 389
system functions (EGL) 275 EGL preferences 465
EGL version 7.0 32 in IMS/VS (EGL) 291 EGL tasks 391
EGL version 7.0 migration 44 in z/OS batch (EGL) 267 Page Designer 389
system libraries iSeries environment (EGL) 299, 300 security 452
EGL version 7.0 32 Java programs (EGL) 300 Web diagrams
system messages overview 251 EGL Web projects 389
EGL runtime customization 152 z/OS batch environment Web page controls
system variables using transfer statement binding to EGL variables 397
EGL version 7.0 32 (EGL) 270 Web pages
EGL version 7.0 migration 44 type-ahead AJAX requests 432
Web applications 413 external requests 442
refresh requests 436
T submit requests 439
templates U creating in EGL 392
EGL commands when pages
creating in EGL 160 UNIX screen options
load 411
disabling in EGL 159 EGL Console UI 529
forwarding data 410
editing in EGL 161 UNIX users
navigation rules in EGL 408
EGL naming considerations 158 EGL Console UI screen options 529
previewing EGL pages 448
EGL overview 158 update function
session data storage with EGL 424
enabling in EGL 159 replace EGL keyword 184
Web projects
exporting from EGL 162 use statements
EGL elements 389
importing in EGL 162 description 124
X
XML report design document
creating 534
Index 619
620 EGL Programmer’s Guide
Printed in USA