IBM ToolBox For Java JTOpen
IBM ToolBox For Java JTOpen
IBM i
Programming
IBM Toolbox for Java
7.1
IBM
IBM i
Programming
IBM Toolbox for Java
7.1
Note
Before using this information and the product it supports, read the information in “Notices,” on
page 761.
This edition applies to IBM i 7.1 (product number 5770-SS1) and to all subsequent releases and modifications until
otherwise indicated in new editions. This version does not run on all reduced instruction set computer (RISC)
models nor does it run on CISC models.
© Copyright IBM Corporation 1999, 2010.
US Government Users Restricted Rights – Use, duplication or disclosure restricted by GSA ADP Schedule Contract
with IBM Corp.
Contents
IBM Toolbox for Java . . . . . . . . . 1 Record Format Markup Language . . . . . 408
What's new for IBM i 7.1 . . . . . . . . . . 1 XML parser and XSLT processor . . . . . . 417
PDF file for IBM Toolbox for Java . . . . . . . 2 Extensible Program Call Markup Language . . 418
Installing and managing IBM Toolbox for Java . . . 2 Frequently asked questions (FAQ) . . . . . . 445
Managing your IBM Toolbox for Java installation 3 Tips for programming . . . . . . . . . . 445
Installing IBM Toolbox for Java . . . . . . . 3 Shutting down your Java program . . . . . 445
System properties . . . . . . . . . . . 12 Integrated file system path names for server
IBM Toolbox for Java classes. . . . . . . . . 21 objects. . . . . . . . . . . . . . . 445
Access classes . . . . . . . . . . . . 21 Managing connections in Java programs . . . 447
Commtrace classes . . . . . . . . . . 182 IBM i Java virtual machine . . . . . . . . 453
HTML Classes . . . . . . . . . . . . 190 Independent auxiliary storage pool (ASP) . . . 457
ReportWriter classes . . . . . . . . . . 223 Exceptions . . . . . . . . . . . . . 458
Resource classes . . . . . . . . . . . 224 Error events . . . . . . . . . . . . . 459
Security classes . . . . . . . . . . . . 227 Trace class . . . . . . . . . . . . . 460
Servlet classes . . . . . . . . . . . . 231 IBM i optimization . . . . . . . . . . 462
Utility classes . . . . . . . . . . . . 238 Performance improvements. . . . . . . . 464
Vaccess classes . . . . . . . . . . . . 248 Client installation and update classes . . . . 465
Graphical Toolbox and PDML . . . . . . . . 289 AS400ToolboxJarMaker . . . . . . . . . 466
Setting up the Graphical Toolbox . . . . . . 295 Java national language support . . . . . . 467
Creating your user interface . . . . . . . 297 Service and support for the IBM Toolbox for
Displaying your panels at runtime . . . . . 300 Java . . . . . . . . . . . . . . . 467
Editing help documents generated by GUI Code examples . . . . . . . . . . . . . 468
Builder . . . . . . . . . . . . . . 304 Examples: Access classes . . . . . . . . 469
Using the Graphical Toolbox in a browser . . . 307 Examples: JavaBeans . . . . . . . . . . 555
GUI Builder Panel Builder toolbar . . . . . 311 Examples: Commtrace classes . . . . . . . 562
IBM Toolbox for Java beans . . . . . . . . 313 Graphical Toolbox examples . . . . . . . 562
JDBC . . . . . . . . . . . . . . . . 314 Examples from the HTML classes . . . . . 596
| Enhancements to IBM Toolbox for Java JDBC Examples: Program Call Markup Language
| support for IBM i 7.1 . . . . . . . . . . 314 (PCML) . . . . . . . . . . . . . . 619
Enhancements to IBM Toolbox for Java JDBC Examples: ReportWriter classes . . . . . . 628
support for IBM i 6.1 . . . . . . . . . . 318 Examples: Resource classes . . . . . . . . 645
Enhancements to IBM Toolbox for Java JDBC Examples: RFML . . . . . . . . . . . 649
support for IBM i 5.4 . . . . . . . . . . 321 Example: Using a profile token credential to
IBM Toolbox for Java JDBC properties . . . . 326 swap the IBM i thread identity . . . . . . 650
JDBC SQL Types . . . . . . . . . . . 343 Examples from the servlet classes . . . . . 651
Proxy Support . . . . . . . . . . . . . 344 Simple programming examples . . . . . . 678
Secure Sockets Layer and Java Secure Socket Examples: Tips for programming . . . . . . 695
Extension. . . . . . . . . . . . . . . 349 Examples: ToolboxME . . . . . . . . . 696
IBM Toolbox for Java 2 Micro Edition . . . . . 349 Examples: Utility classes. . . . . . . . . 716
ToolboxME requirements . . . . . . . . 349 Examples: Vaccess classes . . . . . . . . 717
Downloading and setting up ToolboxME . . . 350 Examples: XPCML . . . . . . . . . . 747
Concepts important for using ToolboxME . . . 350 Related information for IBM Toolbox for Java . . 757
ToolboxME classes. . . . . . . . . . . 351
Creating and running a ToolboxME program 362 Appendix. Notices . . . . . . . . . 761
ToolboxME working examples. . . . . . . 376 Programming interface information . . . . . . 763
Extensible Markup Language components . . . . 377 Trademarks . . . . . . . . . . . . . . 763
Program Call Markup Language . . . . . . 377 Terms and conditions. . . . . . . . . . . 763
Graphical Toolbox and PDML . . . . . . . 402
IBM Toolbox for Java uses the IBM i Host Servers as access points to the system. Because IBM Toolbox
for Java uses communication functions built into Java, you do not need to use IBM i Access for Windows
to use IBM Toolbox for Java. Each server runs in a separate job on the server, and each server job sends
and receives data streams on a socket connection.
Note: By using the code examples, you agree to the terms of the “Code license and disclaimer
information” on page 760.
| The following changes have been made to IBM Toolbox for Java in IBM i 7.1:
| v The licensed program product JC1 (IBM Toolbox for Java) no longer exists in IBM i 7.1. The product
| software has been integrated into SS1 (product ID 5770-SS1) Option 3 . The same Java JAR files
| continue to be made available in the same integrated file system directories as in the past, but now
| they are all installed as part of 5770-SS1.
| v The following classes have been added since the previous release of IBM i. All classes listed here are in
| package "com.ibm.as400.access," unless otherwise noted.
| – AS400JDBCArray class
| – AS400JDBCArrayResultSet class
| – ErrorCodeParameter class
| – ObjectLockListEntry class
| – UserObjectsOwnedList class
| – UserObjectsOwnedListEntry class
| – com.ibm.as400.security.auth.ProfileTokenProvider interface
| – com.ibm.as400.security.auth.DefaultProfileTokenProvider class
| v Significant enhancements were made to the following classes. All classes listed here are in package
| "com.ibm.as400.access," unless otherwise noted.
| – Many of the JDBC classes
| – CommandCall and ProgramCall - new default thread-safety behavior, new methods
| – IFSFile and IFSJavaFile - new methods
| – AS400 - new system properties, new methods
| – AS400ConnectionPool
| – Trace
| – DataArea
| – SpooledFile
To help you see where technical changes have been made, the information center uses:
v The image to mark where new or changed information begins.
v The image to mark where new or changed information ends.
In PDF files, you might see revision bars (|) in the left margin of new and changed information.
To find other information about what's new or changed this release, see the Memo to users.
To view or download the PDF version of this document, select IBM Toolbox for Java (about 3100 KB).
Other information
You can also download a zipped package of the IBM Toolbox for Java topic that includes the Javadocs at
the IBM Toolbox for Java and JTOpen Web site .
Note: The information in the zipped package has links to documents that are not included in the zipped
package, so these links do not work.
You need Adobe Reader installed on your system to view or print these PDFs. You can download a free
copy from the Adobe Web site (www.adobe.com/products/acrobat/readstep.html) .
You can use any of the following methods (alone or in combination) to install and manage IBM Toolbox
for Java:
v Individual management to install and individually manage IBM Toolbox for Java on each client
v Network management of a single installation by using your network to install and manage a single,
shared installation of IBM Toolbox for Java on a server
The following sections briefly explain how each method affects both performance and manageability.
How you choose to develop your Java applications and manage your resources determines which of the
methods (or which combination of methods) you use.
Individual management
You can choose to individually manage your IBM Toolbox for Java installations on individual clients. The
main advantage of installing IBM Toolbox for Java on individual clients is that it reduces the time that a
client takes to start an application that uses IBM Toolbox for Java classes.
The main disadvantage is managing those installations individually. Either a user or an application that
you create must track and manage which version of IBM Toolbox for Java is installed on each
workstation.
You can also use your network to install and manage a single copy of IBM Toolbox for Java on a server
that all your clients can access. This kind of network installation provides the following advantages:
v All clients use the same version of IBM Toolbox for Java
v Updating the single installation of IBM Toolbox for Java benefits all clients
v Individual clients have no maintenance issues, other than setting the same initial CLASSPATH
This kind of installation also has the disadvantage of increasing the time that a client takes to start a IBM
Toolbox for Java application. You must also enable your client CLASSPATH to point to your server. You
can use NetServer, which is integrated into IBM i, or a different method that enables you to access files
on the system, such as IBM i Access for Windows.
Note: Before you use IBM Toolbox for Java, make sure to address the workstation requirements that
pertain to your environment.
To run IBM Toolbox for Java in a client/server environment, you must enable the QUSER user profile,
start the host servers, and have TCP/IP running.
From a command line, start the required IBM i options by completing the following steps:
1. Ensure that the QUSER profile is enabled.
2. To start the IBM i host servers, use the CL Start Host Server command. Type STRHOSTSVR *ALL
and press ENTER.
3. To start the TCP/IP distributed data management (DDM) server, use the CL Start TCP/IP Server
command. Type STRTCPSVR SERVER(*DDM) and press ENTER.
To see if IBM Toolbox for Java is already installed on your IBM i server, complete the steps in this topic.
1. In System i Navigator, select and sign on to the system that you want to use.
2. In the Function Tree (the left pane), expand the system, then expand Configuration and Service.
3. Expand Software, then expand Installed Products.
| 4. In the Details pane (the right pane), see if product 5770-SS1 option 3 is installed. If you see this
| product and option combination, the IBM Toolbox for Java is installed on the selected server.
Note: You can also find out if IBM Toolbox for Java is installed by using the CL Go to Menu
command (GO MENU(LICPGM)), Option 11.
| If IBM Toolbox for Java is not installed, you can install the IBM Toolbox for Java by installing option 3 of
| product 5770-SS1.
The IBM i Host Servers start under the QUSER user profile, so you first need to ensure that the QUSER
profile is enabled in order to run IBM Toolbox for Java in a client/server environment.
To use the command line to check the QUSER profile, complete the following steps:
1. On a command line, type DSPUSRPRF USRPRF(QUSER) and press Enter.
2. Make sure that the Status is *ENABLED. If the profile status is not *ENABLED, change the QUSER
profile.
If the QUSER profile is not *ENABLED, you must enable it to start the IBM i Host Servers. Also, the
QUSER profile password cannot be *NONE. If this is true, you must reset it.
To use the command line to enable the QUSER profile, complete the following steps:
1. Type CHGUSRPRF USRPRF(QUSER) and press ENTER.
2. Change the Status field to *ENABLED and press ENTER.
The QUSER user profile is now ready to start the IBM i Host Servers.
Depending on how you want to use IBM Toolbox for Java, you may need to install other licensed
programs.
When you want to use the spooled file viewer functions (SpooledFileViewer class) of IBM Toolbox for
Java, ensure that you have installed host option 8 (AFP Compatibility Fonts) on your server.
When you want to use Secure Sockets Layer (SSL), ensure that you have installed the following:
v IBM HTTP Server for i licensed program, 5770-DG1
v IBM i Option 34 (Digital Certificate Manager)
For more information about SSL, see “Secure Sockets Layer and Java Secure Socket Extension” on page
349.
If you want to use applets, servlets, or SSL on the IBM i server, you must set up an HTTP server and
install the class files on the system. For more information about the IBM HTTP Server for i, see the HTTP
Server Web site.
For information about the Digital Certificate Manager and how to create and work with digital
certificates using the IBM HTTP Server, see Digital Certificate Management.
Because you can use IBM Toolbox for Java both on your server and your client, the compatibility issues
affect both running on a server and connecting from a client back to a server.
Using IBM Toolbox for Java to connect from a client back to the server
You can use different versions of IBM Toolbox for Java on a client and on the server to which you are
connecting. To use IBM Toolbox for Java to access data and resources on an IBM i server, the server to
which you are connecting must be running one of the following:
| v IBM i 7.1
v IBM i 6.1
v IBM i 5.4
The following table shows the compatibility requirements for connecting back to different versions of
IBM i.
Note: IBM Toolbox for Java does not support forward compatibility. You cannot install IBM Toolbox for
Java on or use it to connect to a server that runs a more recent version of IBM i. For example, if
you are using the version of IBM Toolbox for Java that ships with IBM i 5.2, you cannot connect to
a server that runs IBM i 5.4.
Native optimizations are a set of functions that make the IBM Toolbox for Java classes work the way a
user would expect them to work when running on IBM i. The optimizations affect operation of IBM
Toolbox for Java only when running on the IBM i JVM.
The IBM Toolbox for Java optimizations when running on IBM i are:
v Signon: When no userid or password is specified in the AS400 object, the userid and password of the
current job are used
v Directly calling IBM i APIs instead of making socket calls to host servers:
– Record-level database access, data queues and user space when security requirements are met.
– Program call and command call when security requirements and thread safety requirements are met.
Note: For best performance, set your JDBC driver property to use the native driver when the Java
program and database file are on the same server.
No change to the Java application is needed to get the optimizations. IBM Toolbox for Java automatically
enables the optimizations when appropriate.
In order to gain the performance improvements, you need to make sure to use the JAR file that includes
IBM i native optimizations. For more information, see Note 1 in JAR files.
When you do not use the JAR file that includes IBM i native optimizations, IBM Toolbox for Java works
as if it is running on a client.
ToolboxME requirements:
Your workstation, wireless device, and server must meet certain requirements (listed below) for
developing and running IBM Toolbox for Java 2 Micro Edition applications.
Although Toolbox ME is considered a part of IBM Toolbox for Java, it is not included in the licensed
product. ToolboxME (jt400Micro.jar) is included in the open source version of Toolbox for Java, called
JTOpen. You must separately download and set up ToolboxME, which is contained in JTOpen.
Requirements
To use ToolboxME, your workstation, Tier0 wireless device, and server must meet the following
requirements.
Workstation requirements
The only requirement for running ToolboxME applications on your Tier0 device is using a Java virtual
machine for wireless devices.
Server requirements
Note: Before you use IBM Toolbox for Java, make sure to address the IBM i requirements that pertain to
your environment.
To develop and run IBM Toolbox for Java applications, ensure that your workstation meets the following
requirements.
v We recommend using a supported Java 2 Standard Edition (J2SE) Java virtual machine. Many new IBM
Toolbox for Java functions require using version 1.4 or higher of the JVM.
v Using the vaccess classes or the Graphical Toolbox requires Swing, which comes with J2SE. You can
also download Swing 1.1 from the Sun Java Foundation Classes Web site. The following
environments have been tested:
– Windows 2000
– Windows XP
– AIX® Version 4.3.3.1
– Sun Solaris Version 5.7
– IBM i 5.4 or later
– Linux (Red Hat 7.0)
v TCP/IP installed and configured
To develop and run IBM Toolbox for Java applications, ensure that your workstation meets the following
requirements.
v A browser that has a compatible Java virtual machine (JVM).
Note: IBM Toolbox for Java no longer supports running in the default JVM in Netscape Navigator or
Microsoft Internet Explorer. For your applet that uses IBM Toolbox for Java classes to run in a
browser, you should install a plug-in such as the Sun Java 2 Runtime Environment (JRE) plug-in
.
v TCP/IP installed and configured
| v The workstation must connect to a server that is running IBM i 5.4 or newer release.
ToolboxME requirements:
Your workstation, wireless device, and server must meet certain requirements (listed below) for
developing and running IBM Toolbox for Java 2 Micro Edition applications.
Requirements
To use ToolboxME, your workstation, Tier0 wireless device, and server must meet the following
requirements.
Workstation requirements
The only requirement for running ToolboxME applications on your Tier0 device is using a Java virtual
machine for wireless devices.
Server requirements
IBM Toolbox for Java switched to support Swing 1.1 in V4R5, and this release continues that support.
Switching to Swing required programming changes in the IBM Toolbox for Java classes. So, if your
programs use the Graphical Toolbox or the vaccess classes from releases before V4R5, you will need to
change your programs as well.
In addition to a programming change, the Swing classes must be in the CLASSPATH when the program
is run. The Swing classes are part of the Java 2 Platform. If you don't have the Java 2 Platform, you can
download the Swing 1.1 classes from Sun Microsystems, Inc.
Before installing IBM Toolbox for Java, you need to ensure that your version of IBM i meets the
requirements for running IBM Toolbox for Java. You may want to determine whether the IBM Toolbox for
Java is already installed on your server.
| You can install the IBM Toolbox for Java by installing 5770-SS1 option 3. You can use either System i
| Navigator or the command line.
To install IBM Toolbox for Java using System i Navigator, complete the following steps:
Note: For more information, click Help in the Restore Licensed Program (RSTLICPGM) dialog,
You can use System i Navigator to view the status of the resulting Management Central Command task
by completing the following steps:
1. Expand Management Central.
2. Expand Task Activity.
3. Under Task Activity, select Commands.
4. In the Detail pane, click on the appropriate Run Command task.
To install IBM Toolbox for Java from a command line, complete the following steps:
1. On a command line, use the CL Go to Menu command. Type GO MENU(LICPGM) and press
ENTER.
2. Select 11. Install licensed program.
| 3. Select 5770-SS1 3 Extended Base Directory Support.
For more information about installing licensed programs, see Managing software and licensed programs.
How you install IBM Toolbox for Java on your workstation depends on how you want to manage your
installation:
v To install IBM Toolbox for Java on individual clients, copy the JAR files to your workstation and
configure your workstation CLASSPATH.
v To use IBM Toolbox for Java that is installed on a server, you only have to configure your workstation
CLASSPATH to point to the server installation. To point your workstation CLASSPATH to the server,
your server must have IBM i NetServer installed.
This documentation explains how to copy the class files to your workstation. For more information about
setting the CLASSPATH on your workstation, refer to the operating system documentation for your
workstation or information available at the Sun Java Web site .
Note: Using the IBM Toolbox for Java classes in your application also requires that your system meets
the requirements for IBM i.
The IBM Toolbox for Java class files are packaged in several JAR files, consequently you need to copy one
or more of these JAR files to your workstation. For more information about which JAR files are required
for specific IBM Toolbox for Java functions, see JAR files.
The following example assumes you want to copy jt400.jar, which contains the core IBM Toolbox for Java
classes.
You also have the option of using the open source version of IBM Toolbox for Java, called JTOpen. For
more information about JTOpen, see the IBM Toolbox for Java and JTOpen Web site .
JAR files:
The IBM Toolbox for Java is shipped as a set of JAR files. Each JAR file contains Java packages that
provide specific functions. You can reduce the amount of required storage space by using only the JAR
files required to enable the specific functions that you want.
To use a JAR file, make sure that you include an entry for it in your CLASSPATH.
The following chart indicates which JAR files you must add to your CLASSPATH to use the associated
function or package.
IBM Toolbox for Java package or function JAR files required to be in your CLASSPATH
Note 1
Access classes jt400.jar (client) or jt400Native.jar (server) , or
jt400Proxy.jar in a proxy environment
Note 1
“CommandHelpRetriever class” on page 245 jt400.jar (client) or jt400Native.jar (server) and an
XML parser and XSLT processor Note 3
CommandPrompter Note 3 jt400.jar, jui400.jar, util400.jar Note 4
, and an XML parser Note
Note 1
Commtrace classes jt400.jar (client) or jt400Native.jar (server)
HTML classes jt400.jar Note 1 plus jt400Servlet.jar (client), or
jt400Native.jar (server) Note 1
HTMLDocument class The same JAR files required for HTML classes, plus an
XML parser and XSLT processor Note 3
Note 1
JCA classes jt400.jar (client) or jt400Native.jar (server)
JDBC Data Source GUI jt400.jar (client) Note 1 and jui400.jarNote 5
NLS system and error messages jt400Mri_lang_cntry.jar Note 6
Note 7 Note 1 Note 8
PCML (development and run-time, parsed) jt400.jar (client) or jt400Native.jar (server) , , and
an XML parser Note 3
Note 1 Note 8
PCML (run-time, serialized) jt400.jar (client) or jt400Native.jar (server) ,
PDML (development) Note 3 uitools.jar, jui400.jar, util400.jar Note 4
, and an XML parser
Note 3
Note 1: Do not put both jt400.jar and jt400Native.jar in your CLASSPATH. Choose the JAR file most
appropriate for your environment and use only that JAR in your CLASSPATH.
Note 2: Some of the IBM Toolbox for Java classes are in more than one JAR file:
v jt400.jar - Access, commtrace, JCA, JDBC support, MEServer, PCML, resource, RFML, security, utilities,
vaccess, and XPCML.
v jt400.zip - Use jt400.jar instead of jt400.zip. jt400.zip is shipped to retain compatibility with previous
releases of IBM Toolbox for Java.
v jt400Access.zip - The same classes that are in jt400.jar minus the vaccess classes. jtAccess400.zip is
shipped to retain compatibility with previous releases of IBM Toolbox for Java. Use jt400.jar or
jt400Native.jar instead of jt400Access.zip.
v jt400Native.jar - Access, HTML, MEServer, PCML, resource, RFML, security, XPCML, and native
optimizations. Native optimizations is a set of classes (fewer than 20) that take advantage of IBM i
function when running on the IBM i JVM. Because jt400Native.jar contains the native optimizations,
when running on theIBM i JVM, use jt400Native.jar instead of jt400.jar. jt400Native.jar ships with IBM i
and resides in directory /QIBM/ProdData/OS400/jt400/lib.
v jt400Native11x.jar - Use jt400Native.jar instead of jt400Native11x.jar. jt400Native11x.jar is shipped to
retain compatibility with previous releases of IBM Toolbox for Java.
Note 3: When you must use an XML parser or XSLT processor, make sure that they are JAXP-compliant.
For more information, see the following page:
Note 4: Using CommandPrompter, PDML, or the System i Debugger also requires one additional JAR file
that is not part of IBM Toolbox for Java: jhall.jar. For more information about downloading jhall.jar, see
the Sun JavaHelp Web site .
Note 6: jui400.jar contains the classes necessary to use the JDBC DataSource GUI interface. jt400.jar ( Note
1) contains the classes necessary for all other JDBC functions.
You can add support for other languages by adding more than one of these JAR files to the classpath.
Java loads the correct string based on the current locale.
Note 8: Serializing your PCML file during development has two benefits:
1. You need to parse the PCML file only during development and not during run-time
2. Users need fewer JAR files in their CLASSPATH to run the application
To parse the PCML file during development, you need both the PCML run-time in data.jar or jt400.jar
and the PCML parser in x4j400.jar. To run the serialized application , users need only jt400.jar. For more
information, see “Building IBM i program calls with PCML” on page 378.
Note 9: Use jt400.jar and jt400Native.jar instead of data400.jar. data400.jar contains the PCML runtime
classes, which are now also in jt400.jar and jt400Native.jar (Note 1). data400.jar is shipped to retain
compatibility with previous releases of IBM Toolbox for Java.
Note 10: Copies of the ReportWriter classes are in more than one JAR file:
v composer.jar
v outputwriter.jar
v reportwriters.jar
If your application streams PCL data to an IBM i spooled file, you must make the access classes available
by using the appropriate JAR file ( Note 1). Creating a spooled file to hold PCL data requires the AS400,
OutputQueue, PrintParameterList, and SpooledFileOutputStream classes. For more information, see the
ReportWriter classes.
Note 11: jt400Micro.jar does not contain the classes needed to run MEServer, which reside in both jt400.jar
and jt400Native.jar (Note 1). jt400Micro.jar is available only from the IBM Toolbox for Java and JTOpen
Web site .
System properties
You can specify system properties to configure various aspects of the IBM Toolbox for Java.
For example, you can use system properties to define a proxy server or a level of tracing. System
properties are useful for convenient runtime configuration without needing to recompile code. System
properties work like environment variables in that when you change a system property during runtime,
the change is generally not reflected until the next time you run the application.
If an IBM Toolbox for Java system property is set using more than one of the mechanisms described
above, then the precedence is as follows (in order of decreasing precedence):
1. The system property set programmatically using java.lang.System.setProperties()
2. The system property set using the -D option of the java command
3. The system property set using a Properties class
4. The system property set using a jt400.properties file
Trace properties
Trace property Description
com.ibm.as400.access.Trace.category Specifies which trace categories to enable. This is a
comma-delimited list containing any combination of
trace categories. The complete list of trace categories is
defined in the Trace class.
com.ibm.as400.access.Trace.file Specifies the file to which trace output is written. The
default is to write trace output to System.out.
com.ibm.as400.access.ServerTrace.JDBC Specifies which trace categories to start on the JDBC
server job. For information about supported values, see
the JDBC server trace property.
CommandCall/ProgramCall properties
CommandCall/ProgramCall property Description
com.ibm.as400.access.CommandCall.threadSafe Specifies whether CommandCalls might be assumed to
be thread-safe. If true, all CommandCalls are assumed to
be thread-safe. If false, all CommandCalls are assumed
to be non-thread-safe. This property is ignored for a
given CommandCall object if either
CommandCall.setThreadSafe() or
AS400.setMustUseSockets(true) has been performed on
the object.
FTP properties
FTP property Description
com.ibm.as400.access.FTP.reuseSocket Specifies whether the socket is reused for multiple file
transfers (through a single FTP instance), when in
"active" mode. If true, the socket is reused. If false, a
new socket is created for each file transfer. This property
is ignored for a given FTP object if FTP.setReuseSocket()
has been performed on the object.
Connection properties
Connection property Description
| com.ibm.as400.access.AS400.guiAvailable Indicates whether the current environment has GUI
| capability. If true, prompting may occur during signon
| to display error conditions, to prompt for additional
| information, or to prompt for change password. If false,
| error conditions or missing information will result in
| exceptions. Applications that are running as IBM i
| applications or want to control the signon user interface
| may want to run with prompting mode set to false. The
| default is true.
| com.ibm.as400.access.AS400.mustAddLanguageLibrary Indicates whether AS400 objects should attempt to add
| the appropriate secondary language library to the library
| list when running on the system. Setting the language
| library will ensure that any system error messages that
| are returned, will be returned in the appropriate national
| language for the client locale. If true, AS400 objects will
| attempt to add the secondary language library to the
| library list when running on the system. If false, no
| attempt is made by AS400 objects to add the secondary
| language library to the library list. The default is false.
| com.ibm.as400.access.AS400.mustUseNetSockets Specifies whether AS400 objects should use Internet
| domain sockets only. When your Java program runs on
| the system, some IBM Toolbox for Java classes create
| UNIX domain socket connections. If true, only Internet
| domain sockets will be used by AS400 objects. If false,
| AS400 objects may use UNIX domain socket connections
| in addition to Internet domain sockets. The default is
| false.
#---------------------------------------------------------#
# Proxy server system properties #
#---------------------------------------------------------#
#---------------------------------------------------------#
# Trace system properties #
#---------------------------------------------------------#
#---------------------------------------------------------#
# Command Call system properties #
#---------------------------------------------------------#
#---------------------------------------------------------#
# Program Call system properties #
#---------------------------------------------------------#
#---------------------------------------------------------#
# FTP system properties #
#---------------------------------------------------------#
#---------------------------------------------------------#
# Connection system properties #
#---------------------------------------------------------#
/*---------------------------------------------------------*/
/* Trace system properties */
/*---------------------------------------------------------*/
/*---------------------------------------------------------*/
/* Command Call system properties */
/*---------------------------------------------------------*/
/*---------------------------------------------------------*/
/* FTP system properties */
/*---------------------------------------------------------*/
/*---------------------------------------------------------*/
/* Connection system properties */
/*---------------------------------------------------------*/
For convenience, this documentation usually refers to each package with a short name. For example, the
com.ibm.as400.access package is called the access package.
In addition to the packages listed below, you can also read more about the micro package, which enables
you to create Java programs that give your wireless devices direct access to IBM i data and services, in
the “IBM Toolbox for Java 2 Micro Edition” on page 349 topic.
Access classes
The IBM Toolbox for Java access classes represent IBM i data and resources.
Note: IBM Toolbox for Java provides a second set of classes, called the resource classes, for working with
IBM i objects and lists. The resource classes present a generic framework and consistent
programming interface for working with various IBM i objects and lists.
Related information:
EventLog classes Javadoc
Provides a way to log exceptions and messages independent of the device used to display them.
Access package summary
Resource package summary
The access classes use the existing systems as the access points. Each server runs in a separate job on the
system and sends and receives data streams on a socket connection.
IBM Toolbox for Java 21
Figure 1: Server access points
AS400 class
The IBM Toolbox for Java AS400 class manages a set of socket connections to the server jobs on server
and sign-on behavior for the server, including prompting the user for sign-on information, password
caching, and default user management.
The Java program must provide an AS400 object when the Java program uses an instance of a class that
accesses the IBM i system. For example, the CommandCall object requires an AS400 object before it can
send commands to the system.
The AS400 object handles connections, user IDs, and passwords differently when it is running in the IBM
i Java virtual machine. For more information, see “IBM i Java virtual machine” on page 453.
AS400 objects now support Kerberos authentication, using the Java Generic Security Service Application
Programming Interface (JGSS API) to authenticate to the server, instead of using a user ID and password.
Note: Using Kerberos tickets requires that you install J2SDK, v1.4 and configure the Java Generic Security
Services (JGSS) Application Programming Interface. For more information about JGSS, see the
J2SDK, v1.4 Security Documentation .
For information about using an AS400 object when sending or receiving encrypted data, see the
SecureAS400 class.
Related information:
AS400ConnectionPool Javadoc
AS400 Javadoc
To minimize the number of times a user has to sign on, use a default user ID. The Java program uses the
default user ID when a the program does not provide a user ID. The default user ID can be set either by
the Java program or through the user interface. If the default user ID has not been established, the
Sign-On dialog allows the user to set the default user ID.
Once the default user ID is established for a given server, the Sign-On dialog does not allow the default
user ID to be changed. When an AS400 object is constructed, the Java program can supply the user ID
and password. When a program supplies the user ID to the AS400 object, the default user ID is not
affected. The program must explicitly set the default user ID setUseDefaultUser() if the program wants to
set or change the default user ID. See Prompting, default user ID, and password caching summary for
more information.
The AS400 object has methods to get, set, and remove the default user ID. The Java program can also
disable default user ID processing through the setUseDefaultUser() method. If default user ID processing
is disabled and the Java application does not supply a user ID, the AS400 object prompts for user ID
every time a connection is made to the server.
All AS400 objects that represent the same IBM i system within a Java virtual machine use the same
default user ID.
In the following example, two connections to the server are created by using two AS400 objects. If the
user checked the Default User ID box when signing on, the user is not prompted for a user ID when the
second connection is made.
// Create two AS400 objects to the same system.
AS400 sys1 = new AS400("mySystem.myCompany.com");
AS400 sys2 = new AS400("mySystem.myCompany.com");
The default user ID information is discarded when the last AS400 object for the server is garbage
collected.
The password cache allows the IBM Toolbox for Java to save password and user ID information so that it
does not prompt the user for that information every time a connection is made.
The password cache applies to all AS400 objects that represent an IBM i system within a Java virtual
machine. Java does not allow sharing information between virtual machines, so a cached password in one
Java virtual machine is not visible to another virtual machine. The cache is discarded when the last AS400
object is garbage collected. The Sign-on dialog has a checkbox that gives the user the option to cache the
password. When an AS400 object is constructed, the Java program has the option to supply the user ID
and password. Passwords supplied on constructors are not cached.
The AS400 object provides methods to clear the password cache and disable the password cache . See
Prompting, default user ID, and password caching summary for more information.
When you are using the AS400 class, prompting for user ID and password may occur when connecting to
the server. Prompting can be turned off by your Java program.
Java programs can turn off user ID and password prompting and message windows displayed by the
AS400 object. An example of when this may be needed is when an application is running on a gateway
on behalf of many clients. If prompts and messages are displayed on the gateway machine, the user has
no way of interacting with the prompts. These types of applications can turn off all prompting by using
the setGuiAvailable() method on the AS400 object.
See Prompting, default user ID, and password caching summary for more information.
Java programs can control when prompting for user ID and password caching occurs. The information
from the Sign-On dialog can be used to set the default user ID and cache the password. The following
table summarizes when prompting takes place, what information is retrieved, and what information is
set.
This table assumes that the Java program allows default user ID processing and password caching, and
that you checked the Default User ID box and the Save Password box on the Sign-On dialog.
Use this table for client connections, not for running Java on your server.
SecureAS400 class
The SecureAS400 class enables you to use an AS400 object when sending or receiving encrypted data.
When an AS400 object communicates with the server, user data (except the user password) is sent
unencrypted to the server. So, IBM Toolbox for Java objects associated with an AS400 object exchange
data with the server over a normal connection.
When you want to use IBM Toolbox for Java to exchange sensitive data with the server, you can encrypt
data by using Secure Sockets Layer (SSL). Use the SecureAS400 object to designate which data you want
to encrypt. IBM Toolbox for Java objects associated with a SecureAS400 object exchange data with the
server over a secure connection.
For more information, see Secure Sockets Layer and Java Secure Socket Extension.
You can set up a secure server connection by creating an instance of a SecureAS400 object in the
following ways:
v SecureAS400(String systemName, String userID) prompts you for sign-on information
v SecureAS400(String systemName, String userID, String password) does not prompt you for sign-on
information
AS400JPing class
The IBM Toolbox for Java AS400JPing class allows your Java program to query the host servers to see
which services are running and which ports are in service.
To query the servers from a command line, use the JPing class.
The following example shows how you can use AS400JPing within a Java program to ping the Remote
Command Service:
AS400JPing pingObj = new AS400JPing("myAS400", AS400.COMMAND, false);
if (pingObj.ping())
System.out.println("SUCCESS");
else
System.out.println("FAILED");
Related information:
AS400JPing class
BidiTransform class
The IBM Toolbox for Java BidiTransform class provides layout transformations that enable you to convert
bidirectional text in IBM i format (after first converting it to Unicode) to bidirectional text in Java format,
or from Java format to IBM i format.
AS400BidiTransform class
The following example shows how you can use the AS400BidiTransform class to transform bidirectional
text:
// Java data to system layout:
AS400BidiTransform abt;
abt = new AS400BidiTransform(424);
String dst = abt.toAS400Layout("some bidirectional string");
Note: Read the Code example disclaimer for important legal information.
BidiConversionProperties class
The BidiConversionProperties class provides a set of properties that can be used to control the conversion
of character set data.
Related information:
BidiConversionProperties Javadoc
CallStackEntry class
The CallStackEntry class represents an entry in the call stack of a specific thread of a server job.
ClusteredHashTable classes
The IBM Toolbox for Java ClusteredHashTable classes enable your Java programs to use highly available
clustered hash tables to share and replicate data to nonpersistent storage among the nodes in a cluster.
To use the ClusteredHashTable classes, ensure that you can use nonpersistent storage for the data.
Replicated data is not encrypted.
Note: The following information assumes that you understand the concepts and terminology common to
IBM i cluster technology. See IBM i cluster technology for details.
Using the ClusteredHashTable class requires that you have defined and activated a cluster on the
systems. You must also start a clustered has table server. For more information, see Configure clusters
and Clustered Hash Table APIs.
Required parameters are the name of the clustered hash table server and the AS400 object, which
represents the system that contains the clustered hash table server.
In order to store data in a clustered hash table server, you need a connection handle and a key:
v When you open a connection, the clustered hash table server assigns the connection handle that you
must specify on subsequent requests to the clustered hash table server. This connection handle is good
only for the instantiated AS400 object, so you must open another connection if you use a different
AS400 object.
v You must specify the key to access and change data in the clustered hash table. Duplicate keys are not
supported.
The ClusteredHashTable class provides methods that enable you to perform the following actions:
v Open a connection to the clustered hash table server job
v Generate a unique key to store data into the clustered hash table
v Close the active connection to the clustered hash table server job
The following example operates on clustered hash table server named CHTSVR01. It assumes a cluster
and a clustered hash table server is already active. It opens a connection, generates a key, puts an entry
using the new key in the clustered hash table, gets an entry from the clustered hash table, and closes the
connection.
ClusteredHashTableEntry myEntry = null;
// Open a connection.
cht.open();
// Prepare some data that you want to store into the hash table.
// ENTRY_AUTHORITY_ANY_USER means that any user can access the
// entry in the clustered hash table.
// DUPLICATE_KEY_FAIL means that if the specified key already exists,
// the ClusteredHashTable.put() request will not succeed.
int timeToLive = 500;
myEntry = new ClusteredHashTableEntry(key,myData.getBytes(),timeToLive,
ClusteredHashTableEntry.ENTRY_AUTHORITY_ANY_USER,
ClusteredHashTableEntry.DUPLICATE_KEY_FAIL);
Using the ClusteredHashTable class causes the AS400 object to connect to the server. For more
information, see Managing connections.
CommandCall class
The CommandCall class allows a Java program to call a non-interactive IBM i command.
Using the CommandCall class causes the AS400 object to connect to the system. See managing
connections for information about managing connections.
When the Java program and the IBM i command are on the same server, the default IBM Toolbox for
Java behavior is to look up the thread safety for the command on the system. If threadsafe, the command
is run on-thread. You can suppress the run-time lookup by explicitly specifying thread-safety for the
command by using the setThreadSafe() method.
Examples
The following examples show ways you can use the CommandCall class to run different kinds of
commands.
Note: Read the Code example disclaimer for important legal information.
The following example shows how to use the CommandCall class to run a command on the system:
// Create an AS400 object.
AS400 sys = new AS400("mySystem.myCompany.com");
“Example: Using CommandCall” on page 472 shows how to run a command that is specified by the user.
Related information:
CommandCall Javadoc
AS400Message Javadoc
AS400 Javadoc
Connection pooling
Use connection pools to share connections and manage sets (pools) of connections to an IBM i system.
For example, an application can retrieve a connection from a pool, use it, then return it to the pool for
reuse.
The AS400ConnectionPool class manages a pool of AS400 objects. The AS400JDBCConnectionPool class
represents a pool of AS400JDBCConnections that are available for use by a Java program as part of IBM
A connection pool of either type keeps track of the number of connections it creates. Using methods
inherited from ConnectionPool, you can set several connection pool properties, including:
v the maximum number of connections that can be given out by a pool
v the maximum lifetime of a connection
v the maximum inactivity time of a connection
In terms of performance, connecting to the server is an expensive operation. Using connection pools can
improve performance by avoiding repeated connection times. For example, create connections when you
create the connection pool by filling the pool with active (preconnected) connections using the
AS400ConnectionPool class. Instead of creating new connections, you can use a connection pool to easily
retrieve, use, return, and reuse the connection objects.
Retrieve a connection using an AS400ConnectionPool by specifying the system name, user id, the
password, and (optionally) the service. To specify the service to which you want to connect, use constants
from the AS400 class (FILE, PRINT, COMMAND, and so on).
After retrieving and using the connection, applications return connections to the pool. It is the
responsibility of each application to return connections to the pool for reuse. When connections are not
returned to the pool, the connection pool continues to grow in size and connections are not reused.
See managing connections for more information about managing when a connection to the system is
opened when using the AS400ConnectionPool classes.
“Example: Using AS400ConnectionPool” on page 473 shows how to reuse AS400 objects.
Related information:
AS400ConnectionPool Javadoc
AS400 Javadoc
Data area
The IBM Toolbox for Java DataArea class is an abstract base class that represents an IBM i data area
object.
This base class has four subclasses that support the following: character data, decimal data, logical data,
and local data areas that contain character data.
Using the DataArea class causes the AS400 object to connect to the server. See managing connections for
information about managing connections.
The CharacterDataArea class represents a data area on the server that contains character data. Character
data areas do not have a facility for tagging the data with the proper CCSID; therefore, the data area
object assumes that the data is in the user's CCSID. When writing, the data area object converts from a
string (Unicode) to the user's CCSID before writing the data to the server. When reading, the data area
object assumes that the data is the CCSID of the user and converts from that CCSID to Unicode before
returning the string to the program. When reading data from the data area, the amount of data read is by
number of characters, not by the number of bytes.
DecimalDataArea
The DecimalDataArea class represents a data area on the server that contains decimal data.
Example: Using DecimalDataArea The following example shows how to create and to write to a decimal
data area:
Note: Read the Code example disclaimer for important legal information.
// Establish a connection to the server "MyServer".
AS400 system = new AS400("MyServer");
// Create a DecimalDataArea object.
QSYSObjectPathName path = new QSYSObjectPathName("MYLIB", "MYDATA", "DTAARA");
DecimalDataArea dataArea = new DecimalDataArea(system, path.getPath());
// Create the decimal data area on the server using default values.
dataArea.create();
// Clear the data area.
dataArea.clear();
// Write to the data area.
dataArea.write(new BigDecimal("1.2"));
LocalDataArea
The LocalDataArea class represents a local data area on the server. A local data area exists as a character
data area on the server, but the local data area does have some restrictions of which you should be
aware.
The local data area is associated with a server job and cannot be accessed from another job. Therefore,
you cannot create or delete the local data area. When the server job ends, the local data area associated
with that server job is automatically deleted, and the LocalDataArea object that is referring to the job is
no longer valid. You should also note that local data areas are a fixed size of 1024 characters on the
server.
LogicalDataArea
The LogicalDataArea class represents a data area on the server that contains logical data.
DataAreaEvent
You can use the DataAreaEvent class with any of the DataArea classes. Using the DataAreaEvent class,
you can do the following:
v Get the identifier for the event
DataAreaListener
The DataAreaListener class provides an interface for receiving data area events.
You can use the the DataAreaListener class with any of the DataArea classes. You can invoke the
DataAreaListener class when any of the following are performed:
v Clear
The data description classes build on the data conversion classes to convert all fields in a record with a
single method call. The RecordFormat class allows the program to describe data that makes up a
DataQueueEntry, ProgramCall parameter, a record in a database file accessed through record-level access
classes, or any buffer of system data. The Record class allows the program to convert the contents of the
record and access the data by field name or index.
The converter classes provide fast and efficient conversion between Java and your system.
BinaryConverter converts between Java byte arrays and Java simple types. CharConverter converts
between Java String objects and IBM i code pages. For more information, see the Converters topic.
Data types
The AS400DataType is an interface that defines the methods required for data conversion. A Java
program uses data types when individual pieces of data need to be converted. Conversion classes exist
for the following types of data:
v Numeric
v Text (character)
v Composite (numeric and text)
The following example illustrates using AS400DataType classes with ProgramCall to supply data for
program parameters and to interpret the data returned in program parameters.
The IBM Toolbox for Java provides classes for building on the data types classes to handle converting
data one record at a time instead of one field at a time. For example, suppose a Java program reads data
off a data queue. The data queue object returns a byte array of IBM i data to the Java program. This array
can potentially contain many types of IBM i data. The application can convert one field at a time out of
the byte array by using the data types classes, or the program can create a record format that describes
the fields in the byte array. That record then does the conversion.
The following examples illustrate using the record format conversion classes with data queues:
Conversion classes for numeric data convert numeric data from the format used on the IBM i (called
system format in the following table) to the Java format.
Examples
The following examples show data conversions that use a numeric type in the system format and a Java
int:
// Convert from system type to Java object. The number starts at the
// beginning of the buffer.
Integer intObject = (Integer) bin4Converter.toObject(data,0);
// Find out how many bytes of the buffer were filled with the
// system value.
int length = bin4Converter.getByteLength();
Text conversion:
Character data is converted through the IBM Toolbox for Java AS400Text class. This class converts
character data between an EBCDIC code page and character set (CCSID), and Unicode.
When the AS400Text object is constructed, the Java program specifies the length of the string to be
converted and the server CCSID or encoding. The CCSID of the Java program is assumed to be 13488
Unicode. The toBytes() method converts from Java form to byte array inIBM i format. The toObject()
method converts from a byte array in IBM i format to Java format.
The AS400BidiTransform class provides layout transformations that allow the conversion of bidirectional
text in IBM i format (after its conversion to Unicode) to bidirectional text in Java format, or from Java
format to IBM i format. The default conversion is based on the CCSID of the job. To alter the direction
and shaping of the text, specify a BidiStringType. Note that where IBM Toolbox for Java objects perform
the conversion internally, as in the DataArea class, the objects have a method to override the string type.
For example, the DataArea class has addVetoableChangeListener() method that you can specify to listen
for a veto changes to certain properties, including string type.
The following example assumes that a DataQueueEntry object returns text in EBCDIC. The example
converts the EBCDIC data to Unicode, so that the Java program can use data:
// Assume the data queue work has already been done to
// retrieve the text from the system and the data has been
// put in the following buffer.
int textLength = 100;
byte[] data = new byte[textLength];
// Note: You can also create a converter with just the AS400 object.
// This converter assumes the IBM i code page matches
// the CCSID returned by the AS400 object.
AS400Text textConverter = new AS400Text(textLength, system);
This topic describes IBM Toolbox for Java conversion classes for composite types.
v AS400Array - Allows the Java program to work with an array of data types.
v AS400Structure - Allows the Java program to work with a structure whose elements are data types.
The following example shows conversion from a Java structure to a byte array and back again. The
example assumes that the same data format is used for both sending and receiving data.
// Create a structure of data types that corresponds to a structure
// that contains: - a four-byte number
// - four bytes of pad
// - an eight-byte number
// - 40 characters
AS400DataType[] myStruct =
{
new AS400Bin4(),
new AS400ByteArray(4),
new AS400Float8(),
new AS400Text(40)
};
// Create the Java object that holds the data to send to the server.
Object[] myData =
{
new Integer(88), // the four-byte number
new byte[0], // the pad (let the conversion object 0 pad)
new Double(23.45), // the eight-byte floating point number
"This is my structure" // the character string
};
// ... send the byte array to the server. Get data back from the
// server. The returned data will also be a byte array.
// Pull the third object out of the structure. This is the double.
Double doubleObject = (Double) myRoundTripData[2];
FieldDescription classes:
The field description classes allow the Java program to describe the contents of a field or parameter with
a data type and a string containing the name of the field. If the program is working with data from
record-level access, it can also specify any IBM i data definition specification (DDS) keywords that further
describe the field.
The following example assumes that the entries on a data queue have the same format. Each entry has a
message number (AS400Bin4), a time stamp (8 characters), and message text (50 characters) that you can
describe with field descriptions:
// Create a field description for the numeric data. Note it uses the
// AS400Bin4 data type. It also names the field so it can be accessed by
// name in the record class.
BinaryFieldDescription bfd = new BinaryFieldDescription(new AS400Bin4(), "msgNumber");
// Create a field description for the character data. Note it uses the
// AS400Text data type. It also names the field so it can be accessed by
// name by the record class.
// Create a field description for the character data. Note it uses the
// AS400Text data type. It also names the field so it can be accessed by
// name by the record class.
CharacterFieldDescription cfd2 = new CharacterFieldDescription(new AS400Text(50), "msgText");
You can now group the field descriptions in an instance of the RecordFormat class. To see how to add the
field descriptions to a RecordFormat object, see the example on the following page:
“RecordFormat class”
RecordFormat class:
The IBM Toolbox for Java RecordFormat class allows the Java program to describe a group of fields or
parameters. A record object contains data described by a RecordFormat object. If the program is using
record-level access classes, the RecordFormat class also allows the program to specify descriptions for key
fields.
A RecordFormat object contains a set of field descriptions. The field description can be accessed by index
or by name. Methods exist on the RecordFormat class to do the following:
v Add field descriptions to the record format.
v Add key field descriptions to the record format.
v Retrieve field descriptions from the record format by index or by name.
v Retrieve key field descriptions from the record format by index or by name.
v Retrieve the names of the fields that make up the record format.
v Retrieve the names of the key fields that make up the record format.
v Retrieve the number of fields in the record format.
v Retrieve the number of key fields in the record format.
v Create a Record object based on this record format.
The following example adds the field descriptions created in the field description example to a record
format:
// Create a record format object, then fill it with field descriptions.
RecordFormat rf = new RecordFormat();
rf.addFieldDescription(bfd);
rf.addFieldDescription(cfd1);
rf.addFieldDescription(cfd2);
To see how to create a record from the record format, see the example on the following page:
“Record class”
RecordFormat Javadoc
Record class:
The IBM Toolbox for Java record class allows the Java program to process data described by the record
format class.
Data is converted between byte arrays containing the server data and Java objects. Methods are provided
in the record class to do the following:
v Retrieve the contents of a field, by index or by name, as a Java object.
v Retrieve the number of fields in the record.
IBM Toolbox for Java 39
v Set the contents of a field, by index or by name, with a Java object.
v Retrieve the contents of the record as server data into a byte array or output stream.
v Set the contents of the record from a byte array or an input stream.
v Convert the contents of the record to a String.
The following example uses the record format created in the record format example:
// Assume data queue setup work has already been done. Now read a
// record from the data queue.
DataQueueEntry dqe = dq.read();
// The data from the data queue is now in a data queue entry. Get
// the data out of the data queue entry and put it in the record.
// We obtain a default record from the record format object and
// initialize it with the data from the data queue entry.
Record dqRecord = rf.getNewRecord(dqe.getData());
// Now that the data is in the record, pull the data out one
// field at a time, converting the data as it is removed. The result
// is data in a Java object that the program can now process.
Integer msgNumber = (Integer) dqRecord.getField("msgNumber");
String msgTime = (String) dqRecord.getField("msgTime");
String msgText = (String) dqRecord.getField("msgText");
Related information:
Record Javadoc
Retrieve the contents of a Record object by having your Java program either get one field at a time or get
all the fields at once.
Use the getField() method of the Record class to retrieve a single field by name or by index. Use the
getFields() method to retrieve all of the fields as an Object[].
The Java program must cast the Object (or element of the Object[]) returned to the appropriate Java object
for the retrieved field. The following table shows the appropriate Java object to cast based on the field
type.
Related information:
Record Javadoc
Set the contents of a Record object by using the setField() method in your Java program.
The Java program must specify the appropriate Java object for the field being set. The following table
shows the appropriate Java object for each possible field type.
Related information:
Record Javadoc
LineDataRecordWriter class:
The LineDataRecordWriter class writes the record data, in line data format, to an OutputStream. The class
translates the data into bytes by using the specified CCSID. The record format associated with the record
determines the format of the data.
LineDataRecordWriter
Using LineDataRecordWriter requires that the following record format attributes be set:
v Record format ID
v Record format type
In conjunction with the Record or the RecordFormat classes, the LineDataRecordWriter takes a record as
input to the writeRecord() method. (Record takes a RecordFormat as input when you instantiate it.)
Note: Read the Code example disclaimer for important legal information.
The following example shows one way to use the LineDataRecordWriter class to write a record:
// Example using the LineDataRecordWriter class.
try
{
// create a ccsid
ccsid_ = system_.getCcsid();
SpooledFileOutputStream os = null;
try {
// create the output spooled file to hold the record data
os = new SpooledFileOutputStream(system_, parms, null, outQ);
}
catch (Exception e) {
System.out.println("Error occurred creating spooled file");
e.printStackTrace();
}
catch(Exception e)
{
failed(e, "Exception occurred.");
}
LineDataRecordWriter Javadoc
Record Javadoc
RecordFormat Javadoc
Data queues
The DataQueue classes allow the Java program to interact with server data queues.
The data queue classes provide a complete set of interfaces for accessing server data queues from your
Java program. It is an excellent way to communicate between Java programs and programs on the server
that are written in any programming language.
A required parameter of each data queue object is the AS400 object that represents the server that has the
data queue or where the data queue is to be created.
Using the data queue classes causes the AS400 object to connect to the server. See managing connections
for information about managing connections.
Each data queue object requires the integrated file system path name of the data queue. The type for the
data queue is DTAQ. See integrated file system path names for more information.
The data queue classes support sequential and keyed data queues.:
Methods common to both types of queues are in the BaseDataQueue class. The DataQueue class extends
the BaseDataQueue class in order to complete the implementation of sequential data queues. The
BaseDataQueue class is extended by the KeyedDataQueue class to complete the implementation of keyed
data queues.
When data is read from a data queue, the data is placed in a DataQueueEntry object. This object holds
the data for both keyed and sequential data queues. Additional data available when reading from a
keyed data queue is placed in a KeyedDataQueueEntry object that extends the DataQueueEntry class.
The data queue classes do not alter data that is written to or is read from the server data queue. The Java
program must correctly format the data. The data conversion classes provide methods for converting
data.
The following example creates a DataQueue object, reads data from the DataQueueEntry object, and then
disconnects from the system.
Note: Read the Code example disclaimer for important legal information.
// Create an AS400 object
AS400 sys = new AS400("mySystem.myCompany.com");
Entries on a sequential data queue on the server are removed in first-in first-out (FIFO) or last-in first-out
(LIFO) sequence.
The BaseDataQueue and DataQueue classes provide the following methods for working with sequential
data queues:
v Create a data queue on the server. The Java program must specify the maximum size of an entry on
the data queue. The Java program can optionally specify additional data queue parameters (FIFO vs
LIFO, save sender information, specify authority information, force to disk, and provide a queue
description) when the queue is created.
v Peek at an entry on the data queue without removing it from the queue. The Java program can wait or
return immediately if no entry is currently on the queue.
v Read an entry off the queue. The Java program can wait or return immediately if no entry is available
on the queue.
v Write an entry to the queue.
v Clear all entries from the queue.
v Delete the queue.
The BaseDataQueue class provides additional methods for retrieving the attributes of the data queue.
The following sequential data queue examples illustrate how a producer puts items on a data queue and
how a consumer takes the items off the queue and processes them:
“Example: Using DataQueue classes to read entries off a data queue” on page 490
BaseDataQueue Javadoc
DataQueue Javadoc
The BaseDataQueue and KeyedDataQueue classes provide methods for working with keyed data queues.
The BaseDataQueue and KeyedDataQueue classes also provide additional methods for retrieving the
attributes of the data queue.
The following keyed data queue examples illustrate how a producer puts items on a data queue, and
how a consumer takes the items off the queue and processes them:
“Example: Using KeyedDataQueue classes to read entries off a data queue” on page 498
BaseDataQueue Javadoc
KeyedDataQueue Javadoc
Digital certificates
Digital certificates are digitally-signed statements used for secured transactions over the internet.
To make a secure connection using the Secure Sockets Layer (SSL), a digital certificate is required.
As an administrator of a secured server, you can add a certification authority's "trusted root key" to the
server. This means that your server will trust anyone who is certified through that particular certification
authority.
Digital certificates also offer encryption, ensuring a secure transfer of data through a private encryption
key.
You can create digital certificates through the javakey tool. (For more information about javakey and Java
security, see the Sun Microsystems, Inc., Java Security page .) The IBM Toolbox for Java has classes
that administer digital certificates on the system.
The AS400Certificate classes provide methods to manage X.509 ASN.1 encoded certificates. Classes are
provided to do the following:
v Get and set certificate data.
Using a certificate class causes the AS400 object to connect to the server. See managing connections for
information about managing connections.
The AS400Certificate class provides methods to read and write certificate data. Data is accessed as an
array of bytes. The Java.Security package in Java virtual machine 1.2 provides classes that can be used to
get and set individual fields of the certificate.
Listing certificates
The following example lists certificates in a validation list. It lists only those certificates belonging to a
certain person.
Note: Read the Code example disclaimer for important legal information.
// Create an AS400 object. The certificates are on this system.
AS400 sys = new AS400("mySystem.myCompany.com");
// Retrieve the list that matches the criteria. User space "myspace"
// in library "mylib" will be used for storage of the certificates.
EnvironmentVariable class
The IBM Toolbox for Java EnvironmentVariable class and the EnvironmentVariableList class enable you to
access and set IBM i system-level environment variables.
Each variable has unique identifiers: the system name and the environment variable name. Each
environment variable is associated with a CCSID, which is by default the CCSID of the current job, which
describes where the contents of the variable are stored.
Note: Environment variables are different than system values, although they are often used for the same
purpose. See SystemValues for more information on how to access system values.
The following example creates two EnvironmentVariables and sets and gets their values.
Note: Read the Code example disclaimer for important legal information.
// Create the system object.
AS400 system = new AS400("mySystem");
// Create the background color environment variable and get its value.
EnvironmentVariable bg = new EnvironmentVariable(system, "BACKGROUND");
String background = bg.getValue();
EnvironmentVariable Javadoc
EnvironmentVariableList Javadoc
Exceptions
The IBM Toolbox for Java access classes throw exceptions when device errors, physical limitations,
programming errors, or user input errors occur. The exception classes are based upon the type of error
that occurs instead of the location where the error originates.
The following example shows how to catch a thrown exception, retrieve the return code, and display the
exception text:
Note: Read the Code example disclaimer for important legal information.
// All the setup work to delete a file on the server through the
// IFSFile class is done. Now try deleting the file.
try
{
aFile.delete();
// Get the return code out of the exception and display additional
// information based on the return code.
int rc = e.getReturnCode()
switch (rc)
{
case ExtendedIOException.FILE_IN_USE:
System.out.println("Delete failed, file is in use "):
break;
case ExtendedIOException.PATH_NOT_FOUND:
System.out.println("Delete failed, path not found ");
break;
default:
System.out.println("Delete failed, rc = ");
System.out.println(rc);
}
}
FileAttributes class
The IBM Toolbox for Java FileAttributes class represents the set of file attributes that can be retrieved and
set through the Get Attributes (Qp0lGetAttr) and Set Attributes (Qp0lSetAttr) APIs.
To obtain the attributes of an object, the object must exist and the caller must have authority to it. Only
attributes supported by the specific file system, object type, and system operating release can be retrieved
or set.
You can find a complete list of the available attributes in the FileAttributes Javadoc.
Related information:
FileAttributes Javadoc
Get Attributes (Qp0lGetAttr) API
FTP class
The IBM Toolbox for Java FTP class provides a programmable interface to FTP functions.
You are no longer required to use java.runtime.exec() or tell your users to run FTP commands in a
separate application. That is, you can program FTP functions directly into your application. So, from
within your program, you can do the following:
v Connect to an FTP server
v Send commands to the server
v List the files in a directory
v Get files from the server and put files to the server
Note: Read the Code example disclaimer for important legal information.
For example, with the FTP class, you can copy a set of files from a directory on a server:
FTP client = new FTP("myServer", "myUID", "myPWD");
client.cd("/myDir");
client.setDataTransferType(FTP.BINARY);
String [] entries = client.ls();
client.disconnect();
FTP is a generic interface that works with many different FTP servers. Therefore, it is up to the
programmer to match the semantics of the server.
AS400FTP subclass
While the FTP class is a generic FTP interface, the AS400FTP subclass is written specifically for the FTP
server on the server. That is, it understands the semantics of the FTP server on the IBM i. For example,
this class understands the various steps needed to transfer a save file to the server and performs these
steps automatically. AS400FTP also ties into the security facilities of the IBM Toolbox for Java. As with
other IBM Toolbox for Java classes, AS400FTP depends on the AS400 object for system name, user ID, and
password.
Note: Read the Code example disclaimer for important legal information.
The following example puts a save file to the server. Note the application does not set data transfer type
to binary or use CommandCall to create the save file. Since the extension is .savf, AS400FTP class detects
the file to put is a save file so it does these steps automatically.
The function that is provided by the IFSFile classes is a superset of the function provided by the file IO
classes in the java.io package. All methods in java.io FileInputStream, FileOutputStream, and
RandomAccessFile are in the integrated file system classes.
Through the integrated file system classes, the Java program can directly access stream files on the
system. The Java program can still use the java.io package, but the client operating system must then
provide a method of redirection. For example, if the Java program is running on a Windows 95 or
Windows NT operating system, the Network Drives function of IBM i Access for Windows is required to
redirect java.io calls to the system. With the integrated file system classes, you do not need IBM i Access
for Windows.
A required parameter of the integrated file system classes is the AS400 object that represents the system
that contains the file. Using the integrated file system classes causes the AS400 object to connect to the
system. See managing connections for information about managing connections.
The integrated file system classes require the hierarchical name of the object in the integrated file system.
Use the forward slash as the path separator character. The following example shows how to access FILE1
in directory path DIR1/DIR2:
/DIR1/DIR2/FILE1
“Example: Using IFS classes to copy a file from one directory to another” on page 506 shows how to use
the integrated file system classes to copy a file from one directory to another on the system.
“Example: Using the IFS classes to list the contents of a directory” on page 508 shows how to use the
integrated file system classes to list the contents of a directory on the system.
IFSFile class:
The IBM Toolbox for Java IFSFile class represents an object in the IBM i integrated file system.
You can get the list of files in a directory by using either the list() method or the listFiles() method:
v The listFiles() method caches information for each file on the initial call. After calling listFiles(), using
other methods to query file details results in better performance because the information is retrieved
from the cache. For example, calling isDirectory() on an IFSFile object returned from listFiles() does not
require a call to the server.
v The list() method retrieves information about each file in a separate request to the server, making it
slower and more demanding of server resources.
Note: Using listFiles() means that the information in the cache may eventually become stale, so you may
need to refresh the data by calling listFiles() again.
Examples
IFSJavaFile class:
This IBM Toolbox for Java class represents a file in the IBM i integrated file system and extends the
java.io.File class. IFSJavaFile allows you to write files for the java.io.File interface that access integrated
file systems.
IFSJavaFile makes portable interfaces that are compatible with java.io.File and uses only the errors and
exceptions that java.io.File uses. IFSJavaFile uses the security manager features from java.io.File, but
unlike java.io.File, IFSJavaFile uses security features continuously.
You use IFSJavaFile with IFSFileInputStream and IFSFileOutputStream. It does not support
java.io.FileInputStream and java.io.FileOutputStream.
You can get the list of files in a directory by using either the list() method or the listFiles() method:
v The listFiles() method performs better because it retrieves and caches information for each file on the
initial call. After that, information about each file is retrieved from the cache.
v The list() method retrieves information about each file in a separate request, making it slower and
more demanding of server resources.
Note: Using listFiles() means that the information in the cache eventually become stale, so you may need
to refresh the data.
Note: Read the Code example disclaimer for important legal information.
try
{
IFSFileOutputStream os =
new IFSFileOutputStream(file.getSystem(), file, IFSFileOutputStream.SHARE_ALL, false);
byte[] data = new byte[256];
int i = 0;
for (; i < data.length; i++)
{
data[i] = (byte) i;
os.write(data[i]);
}
os.close();
}
catch (Exception e)
{
System.err.println ("Exception: " + e.getMessage());
}
Related information:
IFSJavaFile Javadoc
The IBM Toolbox for Java IFSFileInputStream class represents an input stream for reading data from a file
on the server.
As in the IFSFile class, methods exist in IFSFileInputStream that duplicate the methods in FileInputStream
from the java.io package. In addition to these methods, IFSFileInputStream has additional methods
specific to the IBM i platform. The IFSFileInputStream class allows a Java program to do the following:
v Open a file for reading. The file must exist since this class does not create files on the server. You can
use a constructor that allows you to specify the file sharing mode.
v Determine the number of bytes in the stream.
v Read bytes from the stream.
v Skip bytes in the stream.
v Lock or unlock bytes in the stream.
v Close the file.
As in FileInputStream in java.io, this class allows a Java program to read a stream of bytes from the file.
The Java program reads the bytes sequentially with only the additional option of skipping bytes in the
stream.
In addition to the methods in FileInputStream, IFSFileInputStream gives the Java program the following
options:
v Locking and unlocking bytes in the stream. See IFSKey for more information.
v Specifying a sharing mode when the file is opened. See sharing modes for more information.
IFSTextFileInputStream class:
The IFSTextFileInputStream class represents a stream of character data read from a file. The data read
from the IFSTextFileInputStream object is supplied to the Java program in a Java String object, so it is
IBM Toolbox for Java 53
always Unicode. When the file is opened, the IFSTextFileInputStream object determines the CCSID of the
data in the file. If the data is stored in an encoding other than Unicode, the IFSTextFileInputStream object
converts the data from the file's encoding to Unicode before giving the data to the Java program. If the
data cannot be converted, an UnsupportedEncodingException is thrown.
IFSFileReader:
Use this class for reading character files in the integrated file system.
IFSFileOutputStream class:
The IFSFileOutputStream class represents an output stream for writing data to a file on the server.
As in the IFSFile class, methods exist in IFSFileOutputStream that duplicate the methods in
FileOutputStream from the java.io package. IFSFileOutputStream also has additional methods specific to
the server. The IFSFileOutputStream class allows a Java program to do the following:
As in FileOutputStream in java.io, this class allows a Java program to sequentially write a stream of bytes
to the file.
In addition to the methods in FileOutputStream, IFSFileOutputStream gives the Java program the
following options:
v Locking and unlocking bytes in the stream. See IFSKey for more information.
v Specifying a sharing mode when the file is opened. See sharing modes for more information.
IFSTextFileOutputStream class:
The IFSTextFileOutputStream class represents a stream of character data being written to a file. The data
supplied to the IFSTextFileOutputStream object is in a Java String object so the input is always Unicode.
The IFSTextFileOutputStream object can convert the data to another CCSID as it is written to the file,
however. The default behavior is to write Unicode characters to the file, but the Java program can set the
target CCSID before the file is opened. In this case, the IFSTextFileOutputStream object converts the
characters from Unicode to the specified CCSID before writing them to the file. If the data cannot be
converted, an UnsupportedEncodingException is thrown.
IFSFileWriter:
Use IFSFileWriter for writing character files in the integrated file system. IFSFileWriter is meant for
writing streams of characters.
IFSRandomAccessFile:
The IBM Toolbox for Java IFSRandomAccessFile class represents a file on the server for reading and
writing data.
The Java program can read and write data sequentially or randomly. As in IFSFile, methods exist in
IFSRandomAccessFile that duplicate the methods in RandomAccessFile from the java.io package. In
addition to these methods, IFSRandomAccessFile has additional methods specific to IBM i. Through
IFSRandomAccessFile, a Java program can do the following:
v Open a file for read, write, or read/write access. The Java program can optionally specify the file
sharing mode and the existence option.
v Read data at the current offset from the file.
v Write data at the current offset to the file.
v Get or set the current offset of the file.
v Close the file.
In addition to the methods in java.io RandomAccessFile, IFSRandomAccessFile gives the Java program
the following options:
v Committing to disk bytes written.
v Locking or unlocking bytes in the file.
The following example shows how to use the IFSRandomAccessFile class to write four bytes at 1K
intervals to a file.
// Create an AS400 object.
AS400 sys = new AS400("mySystem.myCompany.com");
IFSFileDialog:
The IBM Toolbox for Java IFSFileDialog class allows you to traverse the file system and select a file.
This class uses the IFSFile class to traverse the list of directories and files in the IBM i integrated file
system. Methods on the class allow a Java program to set the text on the push buttons of the dialog and
to set filters. Note that an IFSFileDialog class based on Swing 1.1 is also available.
You can set filters through the FileFilter class. If the user selects a file in the dialog, the getFileName()
method can be used to get the name of the file that was selected. The getAbsolutePath() method can be
used to get the path and name of the file that was selected.
The following example shows how to set up a dialog with two filters and to set the text on the push
buttons of the dialog.
// Create a list of filters then set the filters in the dialog. The
// first filter will be used when the dialog is first displayed.
FileFilter[] filterList = {new FileFilter("All files (*.*)", "*.*"),
new FileFilter("HTML files (*.HTML", "*.HTM")};
dialog.setFileFilter(filterList, 0);
IFSKey class:
If the Java program allows other programs access to a file at the same time, the Java program can lock
bytes in the file for a period of time. During that time, the program has exclusive use of that section of
the file. When a lock is successful, the integrated file system classes return an IFSKey object.
This object is supplied to the unlock() method to indicate which bytes to unlock. When the file is closed,
the system unlocks all locks that are still on the file (the system does an unlock for every lock that the
program did not unlock).
The Java program can specify a sharing mode when a file is opened. The program either allows other
programs to open the file at the same time or has exclusive access to the file.
IFSSystemView:
IFSSystemView provides a gateway to the IBM i integrated file system, for use when constructing
javax.swing.JFileChooser objects.
JFileChooser is a standard Java way to build dialogs for navigating and choosing files.
ISeriesNetServer class
The ISeriesNetServer class represents the NetServer service on a server. This class allows the user to
query and modify the state and configuration of the NetServer.
JavaApplicationCall class
The JavaApplicationCall class provides you with the ability to have your client use the server JVM to run
a Java program that resides on the server.
After establishing a connection to the server from the client, the JavaApplicationCall class lets you
configure the following:
1. Set the CLASSPATH environment variable on the server with the setClassPath() method
2. Define your program's parameters with the setParameters() method
3. Run the program with run()
4. Send input from the client to the Java program. The Java program reads the input via standard input
which is set with the sendStandardInString() method. You can redirect standard output and standard
error from the Java program to the client via the getStandardOutString() and getStandardErrorString().
JavaApplicationCall is a class you call from your Java program. However, the IBM Toolbox for Java also
provides utilities to call Java programs that reside on the server. These utilities are complete Java
programs you can run from your workstation. See RunJavaApplication class for more information.
Example
The example in the JavaApplicationCall Javadoc reference documentation shows how to run a program
on the server (that outputs "Hello World!") from the client:
JavaApplicationCall
Related information:
JavaApplicationCall Javadoc
JDBC classes
JDBC is an application programming interface (API) included in the Java platform that enables Java
programs to connect to a wide range of databases.
Supported interfaces
The following table lists the supported JDBC interfaces and the API required to use them:
Related reference:
“JDBC” on page 314
JDBC is an application programming interface (API) included in the Java platform that enables Java
programs to connect to a wide range of databases.
“Example: Using JDBCPopulate to create and populate a table” on page 511
This program uses the IBM Toolbox for Java JDBC driver to create and populate a table.
“Example: Using JDBCQuery to query a table” on page 522
This program uses the IBM Toolbox for Java JDBC driver to query a table and output its contents.
Related information:
JTOpen: The Open Source version of the IBM Toolbox for Java
AS400JDBCConnectionPoolDataSource Javadoc
AS400JDBCPooledConnection Javadoc
RowID
You can use a AS400JDBCBlob object to access binary large objects (BLOBs), such as sound byte (.wav)
files or image (.gif) files.
The key difference between the AS400JDBCBlob class and the AS400JDBCBlobLocator class is where the
blob is stored. With the AS400JDBCBlob class, the blob is stored in the database, which inflates the size of
the database file. The AS400JDBCBlobLocator class stores a locator (think of it as a pointer) in the
database file that points to where the blob is located.
With the AS400JDBCBlob class, the lob threshold property can be used. This property specifies the
maximum large object (LOB) size (in kilobytes) that can be retrieved as part of a result set. LOBs that are
larger than this threshold are retrieved in pieces using extra communication to the server. Larger LOB
thresholds reduce the frequency of communication to the server, but they download more LOB data, even
if it is not used. Smaller lob thresholds may increase frequency of communication to the server, but they
only download LOB data as it is needed. See JDBC properties for information about additional properties
that are available.
Examples
The following examples show how to use the AS400JDBCBlob class to read from a blob and update a
blob:
//Update the blob in the result set, changing the blob starting
// at the seventh byte of the blob (1-based) and truncating the
// blob at the end of the updated bytes (the blob now has 9 bytes).
rs.updateBlob(1, blob);
// Update the database with the change. This will change the blob
// in the database starting at the seventh byte of the blob, and
// truncating at the end of the updated bytes.
rs.updateRow();
rs.close();
CallableStatement interface:
Use a CallableStatement object to run SQL stored procedures. The stored procedure being called must
already be stored in the database. CallableStatement does not contain the stored procedure, it only calls
the stored procedure.
A stored procedure can return one or more ResultSet objects and can use IN parameters, OUT
parameters, and INOUT parameters. Use Connection.prepareCall() to create new CallableStatement
objects.
The CallableStatement object allows you to submit multiple SQL commands as a single group to a
database through the use of batch support. You may get better performance by using batch support
because processing a group of operations is usually faster than processing them one at a time. For more
information about using batch support, see Enhancements to JDBC support.
CallableStatement allows you to get and set parameters and columns by name, although using the
column index results in better performance.
AS400JDBCClob class:
You can use a AS400JDBCClob object to access character large objects (CLOBs), such as large documents.
The key difference between the AS400JDBCClob class and the AS400JDBCClobLocator class is where the
blob is stored. With the AS400JDBCClob class, the clob is stored in the database, which inflates the size of
the database file. The AS400JDBCClobLocator class stores a locator (think of it as a pointer) in the
database file that points to where the clob is located.
With the AS400JDBCClob class, the lob threshold property can be used. This property specifies the
maximum large object (LOB) size (in kilobytes) that can be retrieved as part of a result set. LOBs that are
larger than this threshold are retrieved in pieces using extra communication to the server. Larger LOB
thresholds reduce the frequency of communication to the server, but they download more LOB data, even
if it is not used. Smaller lob thresholds may increase frequency of communication to the server, but they
only download LOB data as it is needed. See “IBM Toolbox for Java JDBC properties” on page 326 for
information about additional properties that are available.
Examples
The following examples show how to use the AS400JDBCClob class to read from a clob and update a
clob:
AS400JDBCClobLocator class
You can use a AS400JDBCClobLocator object to access character large objects (CLOBs).
AS400JDBCConnection class:
The AS400JDBCConnection class provides a JDBC connection to a specific DB2® for IBM i database.
There are many optional properties that can be specified when the connection is created. Properties can
be specified either as part of the URL or in a java.util.Properties object. See “IBM Toolbox for Java JDBC
properties” on page 326 for a complete list of properties supported by the AS400JDBCDriver.
AS400JDBCConnection includes support for savepoints and statement-level holdability, and limited
support for returning auto-generated keys. For more information about these and other enhancements,
see “Enhancements to JDBC support for Version 5 Release 3” on page 323.
To use Kerberos tickets, set only the system name (and not the password) on your JDBC URL object. The
user identity is retrieved through the Java Generic Security Services (JGSS) framework, so you also do not
need to specify a user on your JDBC URL. You can set only one means of authentication in an
AS400JDBCConnection object at a time. Setting the password clears any Kerberos ticket or profile token.
For more information, see the “AS400 class” on page 22 and J2SDK, v1.4 Security Documentation .
If you use JDBC 3.0 and connect to a server running IBM i 5.2 or later, you can use
AS400JDBCConnection to perform the following actions:
v Create a statement with a specific result set holdability (Statement, PreparedStatement, or
CallableStatement object)
v Create a prepared statement that returns any auto-generated keys (when getGeneratedKeys() is called
on the Statement object)
v Use savepoints, which offer more granular control over transactions:
– Set savepoints
– Rollback savepoints
– Release savepoints
AS400JDBCConnection Javadoc
AS400JDBCConnectionPool:
The AS400JDBCConnectionPool class represents a pool of AS400JDBCConnection objects that are available
for use by a Java program as part of IBM Toolbox for Java support for the JDBC 2.0 Optional Package
API.
You can use an AS400JDBCConnectionPoolDataSource to specify properties for the connections that are
created in the pool, as in the following example.
You cannot change the connection pool data source after you have requested a connection and the pool is
in use. To reset the connection pool data source, first call close() on the pool.
Note: When connections are not returned to the pool, the connection pool continues to grow in size and
connections are not reused.
Set properties on the pool by using methods inherited from ConnectionPool. Some of the properties that
you can set include:
v maximum number of connections to allow in the pool
v maximum lifetime of a connection
v maximum inactivity time of a connection.
You can also register AS400JDBCConnectionPoolDataSource objects by using a Java Naming and
Directory Interface (JNDI) service provider. For more information about JNDI service providers, see IBM
Toolbox for Java reference links.
The following example gets a connection pool data source from JNDI and uses it to create a connection
pool with 10 connections:
// Obtain an AS400JDBCConnectionPoolDataSource object from JNDI
// (assumes JNDI environment is set).
Context context = new InitialContext(environment);
// ... Application works with some more connections from the pool.
AS400JDBCManagedConnectionPoolDataSource class:
The JDBC connection pool is a managed connection pool that allows you to reuse connections.
These properties allow you to configure the attributes of the connection pool:
v InitialPoolSize
v MinPoolSize
v MaxPoolSize
v MaxLifetime
v MaxIdleTime
v PropertyCycle
v ReuseConnections
For more information, see the Javadocs on setX() methods where X is the property.
Example 1
This brief example shows the basic use of the AS400JDBCManagedConnectionPoolDataSource class.
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import com.ibm.as400.access.AS400JDBCManagedConnectionPoolDataSource;
import com.ibm.as400.access.AS400JDBCManagedDataSource;
// Set general datasource properties. Note that both connection pool datasource (CPDS) and managed
// datasource (MDS) have these properties, and they might have different values.
cpds0.setServerName(host);
cpds0.setDatabaseName(host);//iasp can be here
cpds0.setUser(userid);
cpds0.setPassword(password);
cpds0.setSavePasswordWhenSerialized(true);
Connection c = dataSource_.getConnection();
This example shows more details about how to use the AS400JDBCManagedConnectionPoolDataSource
class.
import java.awt.TextArea;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Vector;
import java.util.Properties;
import java.sql.Connection;
import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.naming.*;
import java.util.Date;
import java.util.ArrayList;
import java.util.Random;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400JDBCManagedConnectionPoolDataSource;
import com.ibm.as400.access.AS400JDBCManagedDataSource;
import com.ibm.as400.access.Trace;
// If you turn this flag on, be sure to also turn on the following flag:
// AS400JDBCConnection.TESTING_THREAD_SAFETY.
private static final boolean TESTING_THREAD_SAFETY = false;
// Note: For consistency, all time values are stored units of milliseconds.
private int initialPoolSize_; // initial # of connections in pool
private int minPoolSize_; // max # of connections in pool
private int maxPoolSize_; // max # of connections in pool
private long maxLifetime_; // max lifetime (msecs) of connections in pool
private long maxIdleTime_; // max idle time (msecs) of available connections in pool
private long propertyCycle_; // pool maintenance frequency (msecs)
private boolean keepDaemonsAlive_ = true; // When this is false, the daemons shut down.
static
{
try {
Class.forName("com.ibm.as400.access.AS400JDBCDriver");
}
catch(Exception e){
System.out.println("Unable to register JDBC driver.");
System.exit(0);
}
}
cptest.setup();
cptest.runTest();
}
if (TESTING_THREAD_SAFETY)
{
// Adjust values for performing thread-intensive stress testing.
// NOTE: This assumes that the AS400JDBCConnection class has also been modified to
// not make actual connections to an actual server.
// To do this, edit AS400JDBCConnection.java, changing its TESTING_THREAD_SAFETY
// flag to ’false’, and recompile.
minPoolSize_ = 100;
maxPoolSize_ = 190;
initialPoolSize_ = 150; // this should get reset to maxPoolSize_
numDaemons_ = 75;
if (timeToRunDaemons_ == 0) {
timeToRunDaemons_ = 180*1000; // 180 seconds == 3 minutes
}
}
else
{ // Set more conservative values, as we’ll be making actual connections to an
// actual server, and we don’t want to monopolize the server.
minPoolSize_ = 5;
maxPoolSize_ = 15;
initialPoolSize_ = 9;
numDaemons_ = 4;
if (timeToRunDaemons_ == 0) {
timeToRunDaemons_ = 15*1000; // 15 seconds
}
}
maxLifetime_ = (int)timeToRunDaemons_ / 3;
maxIdleTime_ = (int)timeToRunDaemons_ / 4;
propertyCycle_ = timeToRunDaemons_ / 4;
poolHealthCheckCycle_ = Math.min(timeToRunDaemons_ / 4, 20*60*1000);
// at least once every 20 minutes (more frequently if shorter run-time)
daemonMaxSleepTime_ = Math.min(timeToRunDaemons_ / 3, 10*1000);
// at most 10 seconds (less if shorter run-time)
daemonMinSleepTime_ = 20; // milliseconds
if (DEBUG)
System.out.println("setup: Constructing "
+ "AS400JDBCManagedConnectionPoolDataSource (cpds0)");
AS400JDBCManagedConnectionPoolDataSource cpds0 =
new AS400JDBCManagedConnectionPoolDataSource();
// Set datasource properties. Note that both CPDS and MDS have these
// properties, and they might have different values.
cpds0.setServerName(host);
cpds0.setDatabaseName(host);//iasp can be here
cpds0.setUser(userid);
cpds0.setPassword(password);
cpds0.setSavePasswordWhenSerialized(true);
ctx.rebind("mydatasource", cpds0);
// We can now do lookups on cpds, by the name"mydatasource".
if (DEBUG)
System.out.println("setup: lookup(\"mydatasource\"" + ")");
// AS400JDBCManagedConnectionPoolDataSource cpds1 =
// (AS400JDBCManagedConnectionPoolDataSource)ctx.lookup("mydatasource");
// if (DEBUG) System.out.println("setup: cpds1.getUser() == |" + cpds1.getUser() + "|");
if (DEBUG)
System.out.println("setup: Constructing AS400JDBCManagedDataSource (mds0)");
AS400JDBCManagedDataSource mds0 = new AS400JDBCManagedDataSource();
mds0.setDescription("DataSource supporting connection pooling");
mds0.setDataSourceName("mydatasource");
ctx.rebind("ConnectionPoolingDataSource", mds0);
if (DEBUG)
System.out.println("setup: lookup(\"ConnectionPoolingDataSource\"" + ")");
dataSource_ = (DataSource)ctx.lookup("ConnectionPoolingDataSource");
//dataSource_.setLogWriter(output_);
if (DEBUG)
System.out.println("setup: dataSource_.getUser() == |" +
((AS400JDBCManagedDataSource)dataSource_).getUser() + "|");
mds_ = (AS400JDBCManagedDataSource)dataSource_;
}
catch (Exception e)
{
e.printStackTrace();
System.out.println("Setup error during Trace file creation.");
}
}
/**
* Gets and returns connections from and to a connection pool for a while.
**/
public void runTest()
{
boolean ok = true;
try
{
System.out.println("Started test run at " + new Date());
if (DEBUG)
System.out.println("Checking health just after datasource creation "
+ "(we expect that the pool does not exist yet) ...");
if (mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool exists prior to first getConnection().");
}
mds_.setAccess("read only");
oldBool = mds_.isKeepAlive();
newBool = (oldBool ? false : true);
mds_.setKeepAlive(newBool);
if (mds_.isKeepAlive() != newBool) {
ok = false;
System.out.println("\nERROR: isKeepAlive() returned unexpected value: "
+ "|"+mds_.isKeepAlive()+"|");
}
mds_.setKeepAlive(oldBool);
oldInt = mds_.getReceiveBufferSize();
newInt = (oldInt == 256 ? 512 : 256);
mds_.setReceiveBufferSize(newInt);
if (mds_.getReceiveBufferSize() != newInt) {
ok = false;
System.out.println("\nERROR: getReceiveBufferSize() returned unexpected value: "
+ "|"+mds_.getReceiveBufferSize()+"|");
}
mds_.setReceiveBufferSize(oldInt);
System.out.println("CONNECTION 1");
Object o = dataSource_.getConnection();
System.out.println(o.getClass());
System.out.println("******LOOK ABOVE*******");
Connection c1 = dataSource_.getConnection();
if (DEBUG)
displayConnectionType(c1, true);
if (DEBUG)
System.out.println("Checking health after first getConnection() ...");
if (!mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool is not healthy after first getConnection().");
}
if (!TESTING_THREAD_SAFETY)
{
try
{
c1.setAutoCommit(false);
if (DEBUG)
System.out.println("SELECT * FROM QIWS.QCUSTCDT");
Statement s = c1.createStatement();
ResultSet rs = s.executeQuery("SELECT * FROM QIWS.QCUSTCDT");
while(rs.next()){
if (DEBUG)
System.out.println(rs.getString(2));
}
rs.close();
System.out.println("CONNECTION 2");
Connection c2 = dataSource_.getConnection(userid, password);
if (DEBUG)
displayConnectionType(c2, false);
System.out.println("CONNECTION 3");
Connection c3 = dataSource_.getConnection();
if (DEBUG)
displayConnectionType(c3, true);
c1.close();
if (DEBUG)
System.out.println("Checking health after first close() ...");
if (!mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool is not healthy after first close().");
}
System.out.println("CONNECTION 4");
Connection c4 = dataSource_.getConnection();
if (DEBUG) displayConnectionType(c4, true);
// Run the test daemons for a while; check pool health periodically.
if (DEBUG)
System.out.println("Checking health after connectionGetter daemons have run...");
if (!mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool is not healthy after test daemons stopped.");
}
if (DEBUG)
System.out.println("Checking health after pool closed ...");
Trace.setTraceJDBCOn(true); // make sure the final stats get printed out
Trace.setTraceOn(true);
if (!mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool is not healthy after pool closed.");
}
System.out.println();
if(ok==true)
System.out.println("test ran ok");
else
System.out.println("test failed");
}
catch (Exception e)
{
System.out.println(e);
e.printStackTrace();
}
finally {
System.out.println("Ended test at " + new Date());
}
}
void startThreads()
{
// Create a bunch of threads that call getConnection().
Thread[] threads = new Thread[numDaemons_];
for (int i=0; i<numDaemons_; i++)
{
ConnectionGetter getter;
// Flip a coin to see if this daemon will specify the default uid, or unique uid.
if (random_.nextBoolean())
{
getter = new ConnectionGetter(userid,password);
if (TESTING_THREAD_SAFETY) { // we can use fictional userid
getter = new ConnectionGetter("Thread"+i, "Pwd"+i);
}
else { // must use a real userid
getter = new ConnectionGetter(userid,password);
}
}
else
getter = new ConnectionGetter(null, null);
void stopThreads()
{
// ConnectionGetter --------------------------------------------------------------------
/**
Helper class. This daemon wakes up at random intervals and either
gets another connection from the connection pool or returns a
previously-gotten connection to the pool.
**/
private final class ConnectionGetter implements Runnable
{
private String uid_;
private String pwd_;
private boolean useDefaultUid_;
private long maxSleepTime_;
private String threadName_;
private boolean firstConnection_ = true;
ArrayList connections_ = new ArrayList();
// list of connections that this getter currently ’owns’.
try
{
while (keepDaemonsAlive_)
{
try
{
// Pick a random sleep-time, between min and max values.
long sleepTime = Math.max((long)(maxSleepTime_ * random_.nextFloat()),
daemonMinSleepTime_);
// Note: Must never call wait(0), because that waits forever.
synchronized (daemonSleepLock_) {
try {
daemonSleepLock_.wait(sleepTime);
System.out.print(".");
}
catch (InterruptedException ie) {}
}
if (!keepDaemonsAlive_) break;
if (conn == null) {
System.out.println("ConnectionGetter("+threadName_+") ERROR: "
+ "getConnection() returned null");
}
else
{
// Occasionally "forget" that we own a connection, and neglect to
// close it.
// Orphaned connections should eventually exceed their maximum
// lifetime and get "reaped" by the connection manager.
float val = random_.nextFloat();
if (firstConnection_ || val < 0.1) {
// ’orphan’ a few gotten connections
firstConnection_ = false;
}
else {
connections_.add(conn);
}
if (DEBUG) displayConnectionType(conn, useDefaultUid_);
if (conn instanceof com.ibm.as400.access.AS400JDBCConnectionHandle)
{ // We got a pooled connection. Try speeding up our cycle time.
if (maxSleepTime_ > 100)
maxSleepTime_--;
else
maxSleepTime_ = 100;
}
else
{ // We didn’t get a pooled connection. That means that the pool
// must be at capacity. Slow down our cycle time a bit.
maxSleepTime_ = maxSleepTime_ + 50;
}
}
}
else { // Close a connection that we currently own.
if (connections_.size() != 0) {
conn = (Connection)connections_.remove(0);
conn.close();
}
}
} // inner try
catch (Exception e)
{
e.printStackTrace();
}
} // outer while
} // outer try
finally
{
if (DEBUG)
System.out.println("ConnectionGetter("+threadName_+") Stopping");
// Return all the connections that I still have in my list.
for (int i=0; i<connections_.size(); i++) {
Connection conn = (Connection)connections_.remove(0);
try { conn.close(); } catch (Exception e) { e.printStackTrace(); }
}
}
}
DatabaseMetaData interface:
You can use a DatabaseMetaData object to obtain information about the database as a whole as well as
catalog information.
The following example shows how to return a list of tables, which is a catalog function:
// Connect to the server.
Connection c = DriverManager.getConnection("jdbc:as400://mySystem");
AS400JDBCDataSource class:
The AS400JDBCDataSource class represents a factory for IBM i database connections. The
AS400JDBCConnectionPoolDataSource class represents a factory for AS400JDBCPooledConnection objects.
You can register either kind of data source object by using a Java Naming and Directory Interface (JNDI)
service provider. For more information about JNDI service providers, see “Related information for IBM
Toolbox for Java” on page 757.
Examples
The following examples demonstrate ways to create and use AS400JDBCDataSource objects. The last two
examples show how to register an AS400JDBCDataSource object with JNDI and then use the object
returned from JNDI to obtain a database connection. Notice that even when using different JNDI service
providers, the code is very similar.
The following example shows you how to create an AS400JDBCDataSource object and connect it to a
database:
// Create a data source for making the connection.
AS400JDBCDataSource datasource = new AS400JDBCDataSource("myAS400");
datasource.setUser("myUser");
datasource.setPassword("MYPWD");
The following example shows how you can use an AS400JDBCConnectionPoolDataSource to cache JDBC
connections.
// Create a data source for making the connection.
AS400JDBCConnectionPoolDataSource dataSource =
new AS400JDBCConnectionPoolDataSource("myAS400");
datasource.setUser("myUser");
datasource.setPassword("MYPWD");
// Register the datasource with the Java Naming and Directory Interface (JNDI).
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
Context context = new InitialContext(env);
context.bind("jdbc/customer", dataSource);
Example: Using AS400JDBCDataSource objects and IBM SecureWay Directory classes with a
Lightweight Directory Access Protocol (LDAP) directory server
The following examples shows how you can use IBM SecureWay Directory classes to store an object to a
Lightweight Directory Access Protocol (LDAP) directory server:
// Create a data source to the IBM i database.
AS400JDBCDataSource dataSource = new AS400JDBCDataSource();
dataSource.setServerName("myAS400");
dataSource.setDatabaseName("myAS400 Database");
// Register the datasource with the Java Naming and Directory Interface (JNDI).
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.jndi.LDAPCtxFactory");
Context context = new InitialContext(env);
context.bind("cn=myDatasource, cn=myUsers, ou=myLocation,o=myCompany,c=myCountryRegion",
dataSource);
Before using JDBC to access data in a server database file, you need to register the IBM Toolbox for Java
JDBC driver with the DriverManager.
You can register the driver either by using a Java system property or by having the Java program register
the driver:
v Register by using a system property
Each virtual machine has its own method of setting system properties. For example, the Java command
from the JDK uses the -D option to set system properties. To set the driver using system properties,
specify the following:
"-Djdbc.drivers=com.ibm.as400.access.AS400JDBCDriver"
v Register by using the Java program
To load the IBM Toolbox for Java JDBC driver, add the following to the Java program before the first
JDBC call:
Class.forName("com.ibm.as400.access.AS400JDBCDriver");
The IBM Toolbox for Java JDBC driver does not require an AS400 object as an input parameter like the
other IBM Toolbox for Java classes that get data from a server. An AS400 object is used internally,
however, to manage default user and password caching. When a connection is first made to the server,
the user may be prompted for user ID and password. The user has the option to save the user ID as the
default user ID and add the password to the password cache. As in the other IBM Toolbox for Java
functions, if the user ID and password are supplied by the Java program, the default user is not set and
the password is not cached. See “Managing connections in Java programs” on page 447 for information
about managing connections.
You can use the DriverManager.getConnection() method to connect to the server database.
DriverManager.getConnection() takes a uniform resource locator (URL) string as an argument. The JDBC
driver manager attempts to locate a driver that can connect to the database that is represented by the
URL. When using the IBM Toolbox for Java driver, use the following syntax for the URL:
"jdbc:as400://systemName/defaultSchema;listOfProperties"
To use Kerberos tickets, set only the system name (and not the password) on your JDBC URL object. The
user identity is retrieved through the Java Generic Security Services (JGSS) framework, so you also do not
need to specify a user on your JDBC URL. You can set only one means of authentication in an
AS400JDBCConnection object at a time. Setting the password clears any Kerberos ticket or profile token.
For more information, see “AS400 class” on page 22 and J2SDK, v1.4 Security Documentation .
This example results in the user being prompted to type in the name of the system to which he or she
wants to connect.
// Connect to unnamed system.
// User receives prompt to type system name.
Connection c = DriverManager.getConnection("jdbc:as400:");
Example: Connecting to the server database; no default SQL schema or properties specified
// Connect to system ’mySystem’. No
// default SQL schema or properties are specified.
Connection c = DriverManager.getConnection("jdbc:as400://mySystem");
Example: Connecting to the server database and using java.util.Properties to specify properties
The Java program can specify a set of JDBC properties either by using the java.util.Properties interface or
by specifying the properties as part of the URL. See “IBM Toolbox for Java JDBC properties” on page 326
for a list of supported properties.
For example, to specify properties using the Properties interface, use the following code as an example:
// Create a properties object.
Properties p = new Properties();
Example: Connecting to the server database and using a uniform resource locator (URL) to specify
properties
// Connect using properties. The
// properties are set on the URL
// instead of through a properties object.
Connection c = DriverManager.getConnection(
"jdbc:as400://mySystem;naming=sql;errors=full");
Example: Connecting to the server database and specifying user ID and password
// Connect using properties on the
// URL and specifying a user ID and password
Connection c = DriverManager.getConnection(
"jdbc:as400://mySystem;naming=sql;errors=full",
"auser",
"apassword");
To disconnect from the server, use the close() method on the Connecting object. Use the following
statement to close the connection created in the previous example:
c.close();
AS400JDBCDriver Javadoc
AS400JDBCParameterMetaData class:
The AS400JDBCParameterMetaData class enables your programs to retrieve information about the
properties of parameters in PreparedStatement and CallableStatement objects.
AS400JDBCParameterMetaData provides methods that allow you to perform the following actions:
v Get the class name of the parameter
v Get the number of parameters in the PreparedStatement
v Get the SQL type of the parameter
v Get the database-specific type name for the parameter
v Get the precision or the scale of the parameter
The following example shows one way to use AS400JDBCParameterMetaData to retrieve parameters from
a dynamically generated PreparedStatement object:
// Get a connection from the driver.
Class.forName("com.ibm.as400.access.AS400JDBCDriver");
Connection connection =
DriverManager.getConnection("jdbc:as400://myAS400", "myUserId", "myPassword");
PreparedStatement interface:
You can use a PreparedStatement object when an SQL statement is going to be run many times. A
prepared statement is an SQL statement that has been precompiled.
This approach is more efficient than running the same statement multiple times using a Statement object,
which compiles the statement each time it is run. In addition, the SQL statement contained in a
PreparedStatement object may have one or more IN parameters. Use Connection.prepareStatement() to
create PreparedStatement objects.
The PreparedStatement object allows you to submit multiple SQL commands as a single group to a
database through the use of batch support. You may improve performance by using batch support
because processing a group of operations is typically faster than processing them one at a time. For more
information about using batch support, see Enhancements to JDBC support.
ResultSet class:
You can use a ResultSet object to access a table of data that was generated by running a query. The table
rows are retrieved in sequence. Within a row, column values can be accessed in any order.
The data stored in ResultSet is retrieved by using the various get methods, depending on the type of data
being retrieved. The next() method is used to move to the next row.
ResultSet allows you to get and update columns by name, although using the column index results
improves performance.
Cursor movement
A cursor, which is an internal pointer, is used by a result set to point the row in the result set that is
being accessed by the Java program.
The performance of the getRow() method has been improved. Before V5R2, using ResultSet.last(),
ResultSet.afterLast(), and ResultSet.absolute() with a negative value made the current row number not
available. The previous restrictions are lifted, which makes the getRow() method fully functional.
JDBC 2.0 and later JDBC specifications provide additional methods for accessing specific positions within
a database:
Scrolling capabilities
If a result set is created by executing a statement, you can move (scroll) backward (last-to-first) or
forward (first-to-last) through the rows in a table.
A result set that supports this movement is called a scrollable result set. Scrollable result sets also support
absolute positioning. Absolute positioning allows you to move directly to a row by specifying its position
in the result set.
With JDBC 2.0 and later JDBC specifications, you have two additional scrolling capabilities available to
use when working with the ResultSet class: scroll-insensitive and scroll-sensitive result sets.
Note: IBM i only allows read-only access for scrollable insensitive cursors. IBM Toolbox for Java supports
a scroll-insensitive cursor if the result set concurrency is read-only. If the result set type is specified
as insensitive and the concurrency is specified as updateable, the result set type changes to
sensitive and issues a warning to you.
In your application, you can use result sets that use either read-only concurrency (no updates can be
made to the data) or updateable concurrency (allows updates to the data and uses database write locks to
control access to the same data item by different transactions). In an updateable result set, rows can be
updated, inserted, and deleted. Numerous update methods are available for you to use in your program,
for example:
v Update ASCII stream
v Update Big Decimal
v Update binary stream
See Method Summary in the AS400JDBCResultSet Javadoc for a complete listing of the update methods
available through the ResultSet interface.
The following example shows how to use a result set that allows updates to the data (update
concurrency) and allows changes to be made to the result set while it is open (scroll sensitive).
// Connect to the server.
Connection c = DriverManager.getConnection("jdbc:as400://mySystem");
ResultSetMetaData
The ResultSetMetaData interface determines the types and properties of the columns in a ResultSet.
When connecting to a server running IBM i 5.2 or later, using the extended metadata property enables
you to increase the accuracy of the following ResultSetMetaData methods:
v getColumnLabel(int)
v isReadOnly(int)
v isSearchable(int)
v isWriteable(int)
Additionally, setting this property to true enables support for the ResultSetMetaData.getSchemaName(int)
method. Be aware that using the extended metadata property may degrade performance because it
requires retrieving more information from the server.
AS400JDBCResultSet Javadoc
AS400ResultSetMetaData Javadoc
AS400JDBCRowSet class:
The AS400JDBCRowSet class represents a connected rowset that encapsulates a JDBC result set. The
methods on AS400JDBCRowSet are very similar to those of the AS400JDBCResultSet. The database
connection is maintained while in use.
Examples
The following examples show how you can use the AS400JDBCRowSet class.
Example: Creating and populating an AS400JDBCRowSet object, while getting the data source from
JNDI
AS400JDBCSavepoint class:
The IBM Toolbox for Java AS400JDBCSavepoint class represents a logical breaking point in a transaction.
Using savepoints gives you more granular control over which changes are affected when you roll back a
transaction.
For example, Figure 1 shows a transaction that includes two savepoints, A and B. Rolling back the
transaction to either savepoint undoes (or reverses) only those changes from the point a rollback is called
to the savepoint. This prevents having to undo all the changes in the entire transaction. Note that once
you rollback to savepoint A, you cannot later rollback to savepoint B. You cannot access savepoint B after
work is rolled back past it.
In this scenario, assume that your application updates student records. At the end of updating a certain
field in every student record, you perform a commit. Your code detects a particular error associated with
updating this field and rolls back the work done when this error occurs. You know that this particular
error affects only the work performed on the current record.
The following example code helps illustrate how you can use savepoints. The example assumes that the
student ID for John is 123456 and the student ID for Jane is 987654.
// Get a connection from the driver
Class.forName("com.ibm.as400.access.AS400JDBCDriver");
// An error is detected, so we need to roll back Jane’s record, but not John’s.
// Rollback the transaction to savepoint 1. The change to Jane’s record is
// removed while the change to John’s record remains.
connection.rollback(savepoint1);
// Commit the transaction; only John’s ’B’ grade is committed to the database.
connection.commit();
Using savepoints requires that you be aware of the following considerations and restrictions:
Considerations
IBM Toolbox for Java follows database rules regarding how rollbacks affect cursors and retained locks.
For example, when you set the connection option to keep cursors open after a traditional rollback, cursors
also remain open after a rollback to a savepoint. In other words, when a rollback request happens
involving savepoints, IBM Toolbox for Java does not move or close the cursor when the underlying
database does not support this.
Using a savepoint to roll back a transaction undoes only the actions performed from the point where you
start the roll back to the savepoint. Actions performed before that savepoint remain. As in the previous
example, be aware that you can commit a transaction that includes work performed before a particular
savepoint but does not include work performed after the savepoint.
All savepoints are released and become invalid when the transaction is committed or when the entire
transaction is rolled back. You can also release savepoints by calling Connection.releaseSavepoint().
Restrictions
Use a Statement object to run an SQL statement and optionally obtain the ResultSet produced by it.
PreparedStatement inherits from Statement, and CallableStatement inherits from PreparedStatement. Use
the following Statement objects to run different SQL statements:
v “Statement interface”: Runs a simple SQL statement that has no parameters.
v “PreparedStatement interface” on page 81 - Runs a precompiled SQL statement that may or may not
have IN parameters.
v “CallableStatement interface” on page 63 - Runs a call to a database stored procedure. A
CallableStatement may or may not have IN, OUT, and INOUT parameters.
The Statement object allows you to submit multiple SQL commands as a single group to a database
through the use of batch support. You may improve performance by using batch support because
processing a group of operations is typically faster than processing them one at a time. For more
information about using batch support, see Enhancements to JDBC support.
When using batch updates, typically you turn off auto-commit. Turning off auto-commit allows your
program to determine whether to commit the transaction if an error occurs and not all of the commands
have executed. In JDBC 2.0 and later JDBC specifications, a Statement object can keep track of a list of
commands that can be successfully submitted and executed together in a group. When this list of batch
commands is executed by the executeBatch() method, the commands are executed in the order in which
they were added to the list.
AS400JDBCStatement provides methods that enable you to perform many actions, including the
following:
v Execute different kinds of statements
v Retrieve the values for different parameters of the Statement object, including:
– The connection
– Any auto-generated keys created as a result of executing the Statement
– The fetch size and fetch direction
– The maximum field size and maximum row limit
– The current result set, the next result set, the type of result set, the result set concurrency, and the
result set cursor holdability
v Add an SQL statement to the current batch
v Run the current batch of SQL statements
Statement interface
The JDBC XA distributed transaction management classes enable you to use the IBM Toolbox for Java
JDBC driver within a distributed transaction. Using the XA classes to enable the IBM Toolbox for Java
JDBC driver allows it to participate in transactions that span multiple data sources.
Typically, XA distributed transaction management classes are used and controlled directly by a
transaction manager, which is separate from the JDBC driver. The distributed transaction management
interfaces are defined as part of the JDBC 2.0 Optional Package and the Java Transaction API (JTA). Both
are available from Sun as JAR files. The distributed transaction management interfaces are also supported
in the JDBC 3.0 API, which is bundled with the Java 2 Platform, Standard Edition, version 1.4.
For more information, see the Sun Web sites for JDBC and the JTA .
Use the following objects to enable the IBM Toolbox for Java JDBC driver to participate in XA distributed
transactions:
v AS400JDBCXADataSource - A factory for AS400JDBCXAConnection objects. This is a subclass of
AS400JDBCDataSource.
v AS400JDBCXACConnection - A pooled connection object that provides hooks for connection pool
management and XA resource management.
v AS400JDBCXAResource - A resource manager for use in XA transaction management.
Note: Prior to V5R3, the database host server used XA APIs for Job Scoped Locks (XA model). In V5R3
and subsequent releases, the database host server uses XA APIs for Transaction Scoped Locks (NTS
model) for all MTS functions. For more information about how these APIs differ, see XA APIs.
The following example shows simple usage of the XA classes. Keep in mind that the details would be
filled in with work using other data sources. This type of code usually appears within a transaction
manager.
// Create an XA data source for making the XA connection.
AS400JDBCXADataSource xaDataSource = new AS400JDBCXADataSource("myAS400");
xaDataSource.setUser("myUser");
xaDataSource.setPassword("myPasswd");
Jobs classes
The IBM Toolbox for Java Jobs classes, which are in the access package, allow a Java program to retrieve
and change job information.
Use the Jobs classes to work with the following type of job information:
v Date and Time Information
v Job Queue
v Language Identifiers
v Message Logging
v Output Queue
v Printer Information
Examples
The following examples show some of the ways you can use the Job, JobList, and JobLog classes. The
first example shows one way to use a cache with the Job class. Links to other examples immediately
follow the sample code.
Note: Read the Code example disclaimer for important legal information.
The following examples show how to list the jobs belonging to a specific user, list jobs with the job status
information, and display the messages in a job log:
“Example: Using JobLog to display messages in the job log” on page 530
Access package Javadoc
Job class:
The Job class (in the access package) allows a Java program to retrieve and change server job information.
The following type of job information can be retrieved and changed with the Job class:
v Job queues
v Output queues
v Message logging
v Printer device
v Country or region identifier
v Date format
The job class also allows the ability to change a single value at a time, or cache several changes using the
setCacheChanges(true) method and committing the changes using the commitChanges() method. If
caching is not turned on, you do not need to do a commit.
Example
For a code example, see the Javadoc reference documentation for the Job class. The example shows how
to set and get values to and from the cache in order to set the run priority with the setRunPriority()
method and set the date format with the setDateFormat() method.
Job Javadoc
JobList class:
You can use the JobList class (in the access package) to list IBM i jobs.
System.out.println(j.getName() + "." +
j.getUser() + "." +
j.getNumber());
}
Job Javadoc
JobLog class:
TheJobLog class (in the access package) retrieves messages in the job log of a server job by calling
getMessages().
The following example prints all messages in the job log for the specified user:
// ... Setup work to create an AS400
// object and a jobList object has
// already been done
if (j.getUser().trim().equalsIgnoreCase(userID))
{
// A job matching the current user
// was found. Create a job log
// object for this job.
JobLog jlog = new JobLog(system, j.getName(), j.getUser(), j.getNumber());
while (messageList.hasMoreElements())
{
AS400Message message = (AS400Message) messageList.nextElement();
}
}
Job Javadoc
Message classes
The IBM Toolbox for Java AS400Message class and its associated classes represent a message returned
from a server.
AS400Message
The AS400Message object allows the Java program to retrieve an IBM i message that is generated from a
previous operation (for example, from a command call). From a message object, the Java program can
retrieve the following:
v The IBM i library and message file that contain the message
v The message ID
v The message type
v The message severity
v The message text
v The message help text
Note: Read the Code example disclaimer for important legal information.
// Create a command call object.
CommandCall cmd = new CommandCall(sys, "myCommand");
The following examples show how you can use message lists with CommandCall and ProgramCall.
v “Example: Using CommandCall” on page 472
v “Example: Using ProgramCall” on page 542
QueuedMessage
The QueuedMessage class accesses information about a message on an IBM i message queue. With this
class, a Java program can retrieve:
v Information about where a message originated, such as program, job number, and user.
v The message queue
The following example prints all messages in the message queue of the current (signed-on) user:
Note: Read the Code example disclaimer for important legal information.
// The message queue is on this system.
AS400 sys = new AS400(mySystem.myCompany.com);
MessageFile
The MessageFile class allows you to receive a message from an IBM i message file. The MessageFile class
returns an AS400Message object that contains the message. Using the MessageFile class, you can do the
following:
v Return a message object that contains the message
v Return a message object that contains substitution text in the message
Note: Read the Code example disclaimer for important legal information.
AS400 system = new AS400("mysystem.mycompany.com");
MessageFile messageFile = new MessageFile(system);
messageFile.setPath("/QSYS.LIB/QCPFMSG.MSGF");
AS400Message message = messageFile.getMessage("CPD0170");
System.out.println(message.getText());
MessageQueue
The MessageQueue class allows a Java program to interact with an IBM i message queue.
The MessageQueue class acts as a container for the QueuedMessage class. The getMessages() method, in
particular, returns a list of QueuedMessage objects. The MessageQueue class can do the following:
v Set message queue attributes
v Get information about a message queue
v Receive messages from a message queue
v Send messages to a message queue
v Reply to messages
The following example lists messages in the message queue for the current user:
Note: Read the Code example disclaimer for important legal information.
NetServer class
The NetServer class has been deprecated and replaced by the ISeriesNetServer class.
The NetServer class represents the NetServer service on the server. NetServer objects allow you to query
and modify the state and configuration of the NetServer service.
Note: In order to use the NetServer class, you need a server user profile that has *IOSYSCFG authority.
Pending attributes
Many of the NetServer attributes are pending (for example, NAME_PENDING). Pending attributes
represent NetServer values that take effect the next time you start (or restart) the NetServer on the server.
When you have a pair of related attributes and one attribute is pending while the other is nonpending:
v The pending attribute is read/write, so you can change it
94 IBM i: Programming IBM Toolbox for Java
v The nonpending attribute is read-only, so you can query it but you cannot change it
Related NetServer classes allow you to get and set detailed information about specific connections,
sessions, file shares, and print shares:
v NetServerConnection: Represents a NetServer connection
v NetServerFileShare: Represents a NetServer file server share
v NetServerPrintShare: Represents a NetServer print server share
v NetServerSession: Represents a NetServer session
v NetServerShare: Represents a NetServer share
Note: Read the Code example disclaimer for important legal information.
// Create a system object to represent the server.
AS400 system = new AS400("MYSYSTEM", "MYUSERID", "MYPASSWD");
// The NetServer name will get set to NEWNAME the next time the NetServer
// is ended and started.
ObjectReferences class
The IBM Toolbox for Java ObjectReferences class represents the set of information about integrated file
system references on an object that can be retrieved through the Retrieve Object References (QP0LROR)
API.
A reference is an individual type of access or lock obtained on the object when using integrated file
system interfaces. An object may have multiple references concurrently held, provided that the reference
types do not conflict with one another. This class will not return information about byte range locks that
may currently be held on an object.
The user must have execute (*X) data authority to each directory preceding the object whose references
are to be obtained. The user must have read (*R) data authority to the object whose references are to be
obtained.
Permission classes
The IBM Toolbox for Java permission classes allow you to get and set object authority information. Object
authority information is also known as permission. The Permission class represents a collection of many
users' authority to a specific object. The UserPermission class represents a single user's authority to a
specific object.
The Permission class allows you to retrieve and change object authority information. It includes a
collection of many users who are authorized to the object. The Permission object allows the Java program
to cache authority changes until the commit() method is called. Once the commit() method is called, all
changes made up to that point are sent to the server. Some of the functions provided by the Permission
class include:
v addAuthorizedUser(): Adds an authorized user.
v commit(): Commits the permission changes to the server.
v getAuthorizationList(): Returns the authorization list of the object.
v getAuthorizedUsers(): Returns an enumeration of authorized users.
v getOwner(): Returns the name of the object owner.
v getSensitivityLevel(): Returns the sensitivity level of the object.
v getType(): Returns the object authority type (QDLO, QSYS, or Root).
v getUserPermission(): Returns the permission of a specific user to the object.
v getUserPermissions(): Returns an enumeration of permissions of the users to the object.
v setAuthorizationList(): Sets the authorization list of the object.
v setSensitivityLevel(): Sets the sensitivity level of the object.
Note: Read the Code example disclaimer for important legal information.
The following example shows you how to create a permission and add an authorized user to an object.
UserPermission class
The UserPermission class represents the authority of a single, specific user. UserPermission has three
subclasses that handle the authority based on the object type:
v DLOPermission
v QSYSPermission
v RootPermission
Note: Read the Code example disclaimer for important legal information.
// Retrieve the various users/groups that have permissions set on that object.
Enumeration enum = objectInQSYS.getUserPermissions();
while (enum.hasMoreElements())
{
// Print out the user/group profile names one at a time.
UserPermission userPerm = (UserPermission)enum.nextElement();
System.out.println(userPerm.getUserID());
}
Permission Javadoc
UserPermission Javadoc
DLOPermission class:
The DLOPermission class is a subclass of UserPermission. DLOPermission allows you to display and set
the authorities a user has (called permissions) to a document library object (DLO). DLOs are stored in
QDLS.
You must use one of the following methods to change or determine the user's authority:
v Use getDataAuthority() to display the authority value of the user
v Use setDataAuthority() to set the authority value of the user
After setting permissions, it is important that you use the commit() method from the Permissions class to
send the changes to the server.
For more information about permissions and authorities, see the Security reference topic.
The following example shows how to retrieve and print the DLO permissions, including the user profiles
for each permission.
// Create a system object.
QSYSPermission:
QSYSPermission is a subclass of the UserPermission class. QSYSPermission allows you to display and set
the permission a user has for an object in the traditional IBM i library structure stored in QSYS.LIB. You
can set authority for an object stored in QSYS.LIB by setting a system-defined authority value or by
setting the individual object and data authorities.
The following table lists and describes the valid system-defined authority values:
Each system-defined authority value actually represents a combination of the individual object authorities
and data authorities. The following table illustrates the relationships of system-defined authorities to the
individual object and data authorities:
Table 1. Y refers to those authorities that can be assigned. n refers to those authorities that cannot be assigned.
System-
Object authority Data authority
defined
authority Opr Mgt Exist Alter Ref Read Add Upd Dlt Exe
All Y Y Y Y Y Y Y Y Y Y
Change Y n n n n Y Y Y Y Y
Exclude n n n n n n n n n n
Use Y n n n n Y n n n Y
Autl Only valid with user (*PUBLIC) and a specified authorization list that determines the individual object
and data authorities.
Use the getObjectAuthority() method to display the current system-defined authority. Use the
setObjectAuthority() method to set the current system-defined authority using a single value.
Use the appropriate set method to set individual object authority values on or off:
v setAlter()
v setExistence()
v setManagement()
v setOperational()
v setReference()
Use the appropriate set method to set individual data authority values on or off:
v setAdd()
v setDelete()
v setExecute()
v setRead()
v setUpdate()
For more information about the different authorities, see the Security reference topic. For information
about using CL commands to grant and edit object authorities, see the CL commands Grant Object
Authority (GRTOBJAUT) and Edit Object Authority (EDTOBJAUT).
Example
This example shows you how to retrieve and print the permissions for a QSYS object.
// Create a system object.
AS400 sys = new AS400("MYAS400", "USERID", "PASSWORD");
RootPermission:
The RootPermission class represents a user's authority to objects contained in the root directory structure.
RootPermissions objects are those objects not contained in QSYS.LIB or QDLS.
RootPermission is a subclass of the UserPermission class. The RootPermission class allows you to display
and set the permissions for the user of an object contained in the root directory structure.
The following table lists and describes the valid data authority values:
The object authority can be set to one or more of the following values: alter, existence, management, or
reference. You can use the setAlter(), setExistence(), setManagement(), or setReference() methods to set the
values on or off.
After setting either the data authority or the object authority of an object, it is important that you use the
commit() method from the Permissions class to send the changes to the server.
For more information about the different authorities, see the Security reference topic.
Example
This example shows you how to retrieve and print the permissions for a root object.
// Create a system object.
AS400 sys = new AS400("MYAS400", "USERID", "PASSWORD");
Print classes
Print objects include spooled files, output queues, printers, printer files, writer jobs, and Advanced
Function Printing (AFP) resources, which include fonts, form definitions, overlays, page definitions, and
page segments.
Examples
v Example: Creating spooled files shows how to create a spooled file on a server from an input stream
v Example: Creating SCS spooled files shows how to generate a SCS data stream using the
SCS3812Writer class, and how to write the stream to a spooled file on the server
v Example: Reading spooled files shows how to use PrintObjectInputStream to read an existing server
spooled file
v Example: Reading and transforming spooled files shows how to use PrintObjectPageInputStream and
PrintObjectTransformedInputStream to obtain different transformations when reading spooled file data
v Example: Copying a spooled file shows how to copy a spooled file to the same queue that contains
the file you want to copy.
v Example: Listing spooled files asynchronously (using listeners) shows how to asynchronously list all
spooled files on a system and how to use the PrintObjectListListener interface to get feedback as the
list is being built
v Example: Listing spooled files asynchronously (without using listeners) shows how to asynchronously
list all spooled files on a system without using the PrintObjectListListener interface
v Example: Listing spooled files synchronously shows how to synchronously list all spooled files on a
system
Related information:
PrintObject Javadoc
You can use the IBM Toolbox for Java PrintObjectList class and its subclasses to work with lists of print
objects. Print objects include spooled files, output queues, printers, Advanced Function Printing (AFP)
resources, printer files, and writer jobs.
Each subclass has methods that allow filtering of the list based on what makes sense for that particular
type of print object. For example, SpooledFileList allows you to filter a list of spooled files based on the
user who created the spooled files, the output queue that the spooled files are on, the form type, or user
data of the spooled files. Only those spooled files that match the filter criteria are listed. If no filters are
set, a default for each of the filters are used.
To actually retrieve the list of print objects from the server, the openSynchronously() or
openAsynchronously() methods are used. The openSynchronously() method does not return until all
objects in the list have been retrieved from the server. The openAsynchronously() method returns
immediately, and the caller can do other things in the foreground while waiting for the list to build. The
asynchronously opened list also allows the caller to start displaying the objects to the user as the objects
come back. Because the user can see the objects as they come back, the response time may seem faster to
the user. In fact, the response time may actually take longer overall due to the extra processing being
done on each object in the list.
If the list is opened asynchronously, the caller may get feedback on the building of the list. Methods, such
as isCompleted() and size(), indicate whether the list has finished being built or return the current size of
the list. Other methods, waitForListToComplete() and waitForItem(), allow the caller to wait for the list to
complete or for a particular item. In addition to calling these PrintObjectList methods, the caller may
register with the list as a listener. In this situation, the caller is notified of events that happen to the list.
To register or unregister for the events, the caller uses PrintObjectListListener(), and then calls
addPrintObjectListListener() to register removePrintObjectListListener()or to unregister. The following
table shows the events that are delivered from a PrintObjectList.
IBM Toolbox for Java 101
PrintObjectList event When event is delivered
listClosed When the list is closed.
listCompleted When the list completes.
listErrorOccurred If any exception is thrown while the list is being retrieved.
listOpened When the list is opened.
listObjectAdded When an object is added to the list.
After the list has been opened and the objects in the list processed, close the list using the close() method.
This frees up any resources allocated to the garbage collector during the open. After a list has been
closed, its filters can be modified, and the list can be opened again.
When print objects are listed, attributes about each print object listed are sent from the server and stored
with the print object. These attributes can be updated using the update() method in the PrintObject class.
Which attributes are sent back from the server depends on the type of print object being listed. A default
list of attributes for each type of print object that can be overridden by using the setAttributesToRetrieve()
method in PrintObjectList exists. See the Retrieving PrintObject attributes section for a list of the
attributes each type of print object supports.
Examples
“Example: Listing spooled files asynchronously (using listeners)” on page 536 shows how to
asynchronously list all spooled files on a system and how to use the PrintObjectListListener
interface to get feedback as the list is being built
“Example: Listing spooled files asynchronously (without using listeners)” on page 539 shows how to
asynchronously list all spooled files on a system without using the PrintObjectListListener interface
“Example: Listing spooled files synchronously” on page 541 shows how to synchronously list all
spooled files on a system
PrintObjectList Javadoc
SpooledFileList Javadoc
AFPResource Javadoc
PrintObject is an abstract class. An abstract class does not allow you to create an instance of the class.
Instead, you must create an instance of one of its subclasses to work with print objects.
Use the base class, PrintObject , and its subclasses to work with server print objects:
v OutputQueue
v Printer
You can retrieve print object attributes by using the attribute ID and one of several methods from the
base PrintObject class.
The attributeID parameter is an integer that identifies which attribute to retrieve. All of the IDs are
defined as public constants in the base PrintObject class. The PrintAttributes file contains an entry of each
attribute ID. The entry includes a description of the attribute and its type (integer, floating point, or
string). For a list of which attributes may be retrieved using these methods, select the following links:
v AFPResourceAttrs for AFP Resources
v OutputQueueAttrs for output queues
v PrinterAttrs for printers
v PrinterFileAttrs for printer files
v SpooledFileAttrs for spooled files
v WriterJobAttrs for writer jobs
To achieve acceptable performance, these attributes are copied to the client. These attributes are copied
either when the objects are listed, or the first time they are needed if the object was created implicitly.
This keeps the object from going to the host every time the application needs to retrieve an attribute. This
also makes it possible for the Java print object instance to contain out-of-date information about the object
on the server. The user of the object can refresh all of the attributes by calling the update() method on the
object. In addition, if the application calls any methods on the object that would cause the object's
attributes to change, the attributes are automatically updated. For example, if an output queue has a
status attribute of RELEASED (getStringAttribute(ATTR_OUTQSTS); returns a string of "RELEASED"),
and the hold() method is called on the output queue, getting the status attribute after that returns HELD.
setAttributes method
You can use the SpooledFile setAttributes method to change the attributes of spooled files and printer file
objects. Select the following links for a list or which attributes may be set:
v PrinterFileAttrs file for printer files
v SpooledFileAttrs for spooled files
The setAttributes method takes a PrintParameterList parameter, which is a class that is used to hold a
collection of attributes IDs and their values. The list starts out empty, and the caller can add attributes to
PrintParameterList class
You can use the PrintParameterList class to pass a group of attributes to a method that takes any of a
number of attributes as parameters. For example, you can send a spooled file using TCP (LPR) by using
the SpooledFile method, sendTCP(). The PrintParameterList object contains the required parameters for
the send command, such as the remote system and queue, plus any optional parameters desired, such as
whether to delete the spooled file after it is sent. In these cases, the method documentation gives a list of
required and optional attributes. The PrintParameterList setParameter() method does not check which
attributes you are setting and the values that you set them to. The PrintParameterList setParameter()
method simply contains the values to pass along to the method. In general, extra attributes in the
PrintParameterList are ignored, and illegal values on the attributes that are used are diagnosed on the
server.
PrintObject Javadoc
SpooledFile Javadoc
PrintParameterList Javadoc
This topic lists the attributes that can be retrieved and set for an AFP resource.
Retrieve Attributes
The following attributes may be retrieved for an AFP resource using the appropriate getIntegerAttribute(),
getStringAttribute(), or getFloatAttribute() method:
v ATTR_AFP_RESOURCE - AFP resource Integrated File System Path
v ATTR_OBJEXTATTR - Object Extended Attribute
v ATTR_DESCRIPTION - Text Description
v ATTR_DATE - Date File Opened
v ATTR_TIME - Time File Opened
v ATTR_NUMBYTES - Number of bytes to read/write
Set Attributes
Retrieve attributes
The following attributes may be retrieved for an output queue using the appropriate
getIntegerAttribute(), getStringAttribute(), or getFloatAttribute() method:
v ATTR_AUTHCHCK - Authority to Check
v ATTR_DATA_QUEUE - Data Queue Integrated File System Name
v ATTR_DISPLAYANY - Display any File
v ATTR_JOBSEPRATR - Job Separators
v ATTR_NUMFILES - Number of Files
v ATTR_NUMWRITERS - Number of Writers Started to Queue
v ATTR_OPCNTRL - Operator Controlled
Set attributes
Printer Attributes:
The following attributes may be retrieved for a printer using the appropriate getIntegerAttribute(),
getStringAttribute(), or getFloatAttribute() method:
Retrieve Attributes
v ATTR_AFP - Advanced Function Printing
v ATTR_ALIGNFORMS - Align Forms
v ATTR_ALWDRTPRT - Allow Direct Print
v ATTR_BTWNCPYSTS - Between copies status
v ATTR_BTWNFILESTS - Between files status
v ATTR_CODEPAGE - Code Page
v ATTR_CHANGES - Changes
v ATTR_DEVCLASS - Device Class
v ATTR_DEVMODEL - Device Model
v ATTR_DEVTYPE - Device Type
v ATTR_DEVSTATUS - Device Status
v ATTR_DRWRSEP - Drawer for Separators
v ATTR_ENDPNDSTS - End pending status
v ATTR_FILESEP - File Separators
v ATTR_FONTID - Font Identifier
v ATTR_FORM_DEFINITION - Form Definition Integrated File System Name
v ATTR_FORMTYPE - Form Type
v ATTR_FORMTYPEMSG - Form Type Message
v ATTR_FORMFEED - Form Feed
v ATTR_CHAR_ID - Graphic Character Set
v ATTR_HELDSTS - Held status
v ATTR_HOLDPNDSTS - Hold pending status
Set Attributes
This topic contains a list of printer file attributes for use with IBM Toolbox for Java.
Retrieve attributes
The following attributes may be retrieved for a printer file using the appropriate getIntegerAttribute(),
getStringAttribute(), or getFloatAttribute() method:
v ATTR_ALIGN - Align Page
v ATTR_BKMGN_ACR - Back Margin Offset Across
106 IBM i: Programming IBM Toolbox for Java
v ATTR_BKMGN_DWN - Back Margin Offset Down
v ATTR_BACK_OVERLAY - Back Overlay Integrated File System Name
v ATTR_BKOVL_DWN - Back Overlay Offset Down
v ATTR_BKOVL_ACR - Back Overlay offset across
v ATTR_CPI - Characters per Inch
v ATTR_CODEDFNTLIB - Coded Font Library Name
v ATTR_CODEPAGE - Code Page
v ATTR_CODEDFNT - Code Font Name
v ATTR_CONTROLCHAR - Control Character
v ATTR_CONVERT_LINEDATA - Convert Line Data
v ATTR_COPIES - Copies
v ATTR_CORNER_STAPLE - Corner staple
v ATTR_DBCSDATA - User Specified DBCS Data
v ATTR_DBCSEXTENSN - DBCS Extension Characters
v ATTR_DBCSROTATE - DBCS Character Rotation
v ATTR_DBCSCPI - DBCS Characters per Inch
v ATTR_DBCSSISO - DBCS SO/SI Spacing
v ATTR_DFR_WRITE - Defer Write
v ATTR_PAGRTT - Degree of Page Rotation
v ATTR_EDGESTITCH_NUMSTAPLES - Edge Stitch Number of Staples
v ATTR_EDGESTITCH_REF - Edge Stitch Reference
v ATTR_EDGESTITCH_REFOFF - Edge Stitch Reference
v ATTR_ENDPAGE - Ending Page
v ATTR_FILESEP - File Separators
v ATTR_FOLDREC - Fold Records
v ATTR_FONTID - Font Identifier
v ATTR_FORM_DEFINITION - Form Definition Integrated File System Name
v ATTR_FORMFEED - Form Feed
v ATTR_FORMTYPE - Form Type
v ATTR_FTMGN_ACR - Front Margin Offset Across
v ATTR_FTMGN_DWN - Front Margin Offset Down
v ATTR_FRONT_OVERLAY - Front overlay Integrated File System Name
v ATTR_FTOVL_ACR - Front Overlay Offset Across
v ATTR_FTOVL_DWN - Front Overlay Offset Down
v ATTR_CHAR_ID - Graphic Character Set
v ATTR_JUSTIFY - Hardware Justification
v ATTR_HOLD - Hold Spool File
v ATTR_LPI - Lines Per Inch
v ATTR_MAXRCDS - Maximum Spooled Output Records
v ATTR_OUTPTY - Output Priority
v ATTR_OUTPUT_QUEUE - Output Queue Integrated File System Name
v ATTR_OVERFLOW - Overflow Line Number
v ATTR_PAGE_DEFINITION - Page Definition Integrated File System
v ATTR_PAGELEN - Length of Page
v ATTR_MEASMETHOD - Measurement Method
Set attributes
The following attributes may be set for a printer file using the setAttributes() method:
v ATTR_ALIGN - Align Page
v ATTR_BKMGN_ACR - Back Margin Offset Across
v ATTR_BKMGN_DWN - Back Margin Offset Down
v ATTR_BACK_OVERLAY - Back Overlay Integrated File System Name
v ATTR_BKOVL_DWN - Back Overlay Offset Down
v ATTR_BKOVL_ACR - Back Overlay offset across
v ATTR_CPI - Characters per Inch
v ATTR_CODEDFNTLIB - Coded Font Library Name
v ATTR_CODEPAGE - Code Page
v ATTR_CODEDFNT - Code Font Name
v ATTR_CONTROLCHAR - Control Character
v ATTR_CONVERT_LINEDATA - Convert Line Data
v ATTR_COPIES - Copies
v ATTR_CORNER_STAPLE - Corner staple
v ATTR_DBCSDATA - User Specified DBCS Data
v ATTR_DBCSEXTENSN - DBCS Extension Characters
v ATTR_DBCSROTATE - DBCS Character Rotation
v ATTR_DBCSCPI - DBCS Characters per Inch
This topic lists the attributes that can be retrieved and set for a spooled file.
Retrieve attributes
The following attributes may be retrieved for a spooled file using the appropriate getIntegerAttribute(),
getStringAttribute(), or getFloatAttribute() method:
v ATTR_AFP - Advanced Function Printing
v ATTR_ALIGN - Align Page
v ATTR_BKMGN_ACR - Back Overlay offset across
v ATTR_BKMGN_DWN - Back Overlay Offset Down
v ATTR_BACK_OVERLAY - Back Overlay Integrated File System Name
v ATTR_BKOVL_DWN - Back Overlay Offset Down
v ATTR_BKOVL_ACR - Back Overlay offset across
v ATTR_CPI - Characters per Inch
v ATTR_CODEDFNTLIB - Coded Font Library Name
v ATTR_CODEDFNT - Code Font Name
v ATTR_CODEPAGE - Code Page
v ATTR_CONTROLCHAR - Control Character
v ATTR_COPIES - Copies
v ATTR_COPIESLEFT - Copies left to Produce
v ATTR_CORNER_STAPLE - Corner staple
v ATTR_CURPAGE - Current Page
v ATTR_DATE - Date Object Created
v ATTR_DATE_WTR_BEGAN_FILE - Date Writer Began Processing Spooled File
v ATTR_DATE_WTR_CMPL_FILE - Date Writer Completed Processing Spooled File
v ATTR_DBCSDATA - User Specified DBCS Data
v ATTR_DBCSEXTENSN - DBCS Extension Characters
v ATTR_DBCSROTATE - DBCS Character Rotation
v ATTR_DBCSCPI - DBCS Characters per Inch
v ATTR_DBCSSISO - DBCS SO/SI Spacing
v ATTR_PAGRTT - Degree of Page Rotation
v ATTR_EDGESTITCH_NUMSTAPLES - Edge Stitch Number of Staples
v ATTR_EDGESTITCH_REF - Edge Stitch Reference
v ATTR_EDGESTITCH_REFOFF - Edge Stitch Reference Offset
v ATTR_ENDPAGE - Ending Page
v ATTR_FILESEP - File Separators
Set attributes
The following attributes may be set for a spooled file using the setAttributes() method:
v ATTR_ALIGN - Align Page
v ATTR_BACK_OVERLAY - Back Overlay Integrated File System Name
v ATTR_BKOVL_DWN - Back Overlay Offset Down
v ATTR_BKOVL_ACR - Back Overlay offset across
v ATTR_COPIES - Copies
v ATTR_ENDPAGE - Ending Page
v ATTR_FILESEP - File Separators
v ATTR_FORM_DEFINITION - Form definition Integrated File System Name
v ATTR_FORMFEED - Form Feed
v ATTR_FORMTYPE - Form Type
v ATTR_FRONTSIDE_OVERLAY - Front overlay Integrated File System Name
v ATTR_FTOVL_ACR - Front Overlay Offset Across
v ATTR_FTOVL_DWN - Front Overlay Offset Down
v ATTR_OUTPTY - Output Priority
Retrieve Attributes
The following attributes may be retrieved for a writer job using the appropriate getIntegerAttribute(),
getStringAttribute(), or getFloatAttribute() method:
v ATTR_WTRJOBNAME - Writer Job Name
v ATTR_WTRJOBNUM - Writer Job Number
v ATTR_WTRJOBSTS - Writer Job Status
v ATTR_WTRJOBUSER - Writer Job User Name
Set Attributes
AFP Resource
ID ATTR_AFP_RESOURCE
Type String
Description
The Integrated File System path of the external AFP (Advanced Function Print) resource. The
format of the Integrated File System path is "/QSYS.LIB/library.LIB/resource.type" where library
is the library that contains the resource, resource is the name of the resource and type is the
resource type. Valid values for type include "FNTRSC", "FORMDF", "OVL", "PAGSEG", and
"PAGDFN".
Align Forms
ID ATTR_ALIGNFORMS
Type String
Description
The time at which a forms alignment message will be sent. Valid values are *WTR, *FILE, *FIRST.
Align Page
ID ATTR_ALIGN
Type String
Description
Indicates whether a forms alignment message is sent before printing this spooled file. Valid
values are *YES, *NO.
Authority
ID ATTR_AUT
Type String
Description
Specifies the authority that is given to users who do not have specific authority to the output
queue. Valid values are *USE, *ALL, *CHANGE, *EXCLUDE, *LIBCRTAUT.
Authority to Check
ID ATTR_AUTCHK
Type String
Description
Indicates what type of authorities to the output queue allow the user to control all the files on the
output queue. Valid values are *OWNER, *DTAAUT.
Auxiliary Storage
ID ATTR_AUX_POOL
Type Integer
Description
Specifies the number of the auxiliary storage pool (ASP) that the spooled file is stored on. The
possible values are:
v 1: System ASP
v 2-32: One of the user ASPs
Back Overlay
ID ATTR_BACK_OVERLAY
Type String
Description
The Integrated File System path of the back overlay or a special value. If the value is an
Integrated File System path it will have the format "/QSYS.LIB/library.LIB/overlay.OVL" where
library is the library of the resource and overlay is the name of the overlay. Valid special values
include *FRONTOVL.
Changes
ID ATTR_CHANGES
Type String
Description
The time at which pending changes take effect. Valid values are *NORDYF, *FILEEND, or blank
which implies no changes pending to the writer.
Code Page
ID ATTR_CODEPAGE
Type String
Description
The mapping of graphic characters to code points for this spooled file. If the graphic character set
field contains a special value, this field may contain a zero (0).
Control Character
ID ATTR_CONTROLCHAR
Type String
Description
Whether this file uses the American National Standards printer control character. The possible
values are *NONE for no print control characters are passed in the data that is printed or *FCFC
which means that the first character of every record is an American National Standards printer
control character.
Copies
ID ATTR_COPIES
Type Integer
Corner Staple
ID ATTR_CORNER_STAPLE
Type String
Description
The reference corner to be used for a corner staple. A staple is driven into the media at the
reference corner. Valid values are *NONE, *DEVD, *BOTRIGHT, *TOPRIGHT, *TOPLEFT, and
*BOTLEFT.
Current Page
ID ATTR_CURPAGE
Type Integer
Description
Current page that is being written by the writer job.
Data Format
ID ATTR_DATAFORMAT
Type String
Description
Data format. Valid values are *RCDDATA, *ALLDATA.
Data Queue
ID ATTR_DATA_QUEUE
Type String
Description
Specifies the Integrated File System path of the data queue that is associated with the output
queue or "*NONE" if no data queue is associated with the the output queue. The format of the
Integrated File System path is "/QSYS.LIB/library.LIB/dataqueue.DTAQ" where library is the
library that contains the data queue and dataqueue is the name of the data queue.
Defer Write
ID ATTR_DFR_WRITE
Type String
Description
Whether print data is held in system buffers before
Destination Option
ID ATTR_DESTOPTION
Type String
Destination Type
ID ATTR_DESTINATION
Type String
Description
Destination type. Valid values are *OTHER, *AS400, *PSF2.
Device Class
ID ATTR_DEVCLASS
Type String
Description
The device class.
Device Model
ID ATTR_DEVMODEL
Type String
Description
The model number of the device.
Device Status
ID ATTR_DEVSTATUS
Type Integer
Description
The status of the printer device. Valid values are 0 (varied off), 10 (vary off pending), 20 (vary on
pending), 30 (varied on), 40 (connect pending), 60 (active), 66 (active writer), 70 (held), 75
(powered off), 80 (recovery pending), 90 (recovery canceled), 100 (failed), 106 (failed writer), 110
(being serviced), 111 (damaged), 112 (locked), 113 (unknown).
Device Type
ID ATTR_DEVTYPE
Type String
Description
The device type.
Ending Page
ID ATTR_ENDPAGE
Type Integer
Description
The page number at which to end printing the spooled file. Valid values are 0 or the ending page
number. The value *END is encoded as 0.
Envelope Source
ID ATTR_ENVLP_SOURCE
Type String
Description
The size of the envelope in the envelope source. If this field is not specified or the value is not
valid, the special value of *MFRTYPMDL is used. Valid values are *NONE - there is no envelope
File Separators
ID ATTR_FILESEP
Type Integer
Description
The number of file separator pages that are placed at the beginning of each copy of the spooled
file. Valid values are -1, or the number of separators. The value *FILE is encoded as -1.
Fold Records
ID ATTR_FOLDREC
Type String
Description
Whether records that exceed the printer forms width are folded (wrapped) to the next line. Valid
values are *YES, *NO.
Font Identifier
ID ATTR_FONTID
Type String
Description
The printer font that is used. Valid special values include *CPI and *DEVD.
Form Definition
ID ATTR_FORM_DEFINITION
Type String
Description
The Integrated File System path name of the form definition or a special value. If an Integrated
File System path is specified the format is "/QSYS.LIB/library.LIB/formdef.FORMDF" where
library is the library of the form definition and formdef is the name of the form definition. Valid
special values include *NONE, *INLINE, *INLINED, and *DEVD.
Form Feed
ID ATTR_FORMFEED
Type String
Description
The manner in which forms feed to the printer. Valid values are *CONT, *CUT, *AUTOCUT,
*DEVD.
Form Type
ID ATTR_FORMTYPE
Type String
Description
The type of form to be loaded in the printer to print this spooled file.
Front Overlay
ID ATTR_FRONT_OVERLAY
Type String
Description
The Integrated File System path of the front overlay. The format of the Integrated File System
path is "/QSYS.LIB/library.LIB/overlay.OVL" where library is the library of the resource and
overlay is the name of the overlay. The string "*NONE" is used to indicate that no front overlay is
specified.
Hardware Justification
ID ATTR_JUSTIFY
Type Integer
Description
The percentage that the output is right justified. Valid values are 0, 50, 100.
Held Status
ID ATTR_HELDSTS
Type String
Description
Whether the writer is held. Valid values are *YES, *NO.
Image Configuration
ID ATTR_IMGCFG
Type String
Description
The transform services for a variety of image and print data-stream formats.
Internet Address
ID ATTR_INTERNETADDR
Type String
IPP Attributes-charset
ID ATTR_IPP_ATTR_CHARSET
Type String
Description
Indicates the charset (coded character set and encoding method) of the IPP specified spooled file
attributes.
IPP Job ID
ID ATTR_IPP_JOB_ID
Type Integer
Description
IPP Job ID relative to the IPP printer that created the job.
Job Number
ID ATTR_JOBNUMBER
Type String
Description
The number of the job that created the spooled file.
Job Separators
ID ATTR_JOBSEPRATR
Type Integer
Description
The number of job separators to be placed at the beginning of the output for each job having
spooled files on this output queue. Valid values are -2, 0-9. The value *MSG is encoded as -2. Job
separators are specified when the output queue is created.
Job System
ID ATTR_JOBSYSTEM
Type String
Description
The system job which created spooled file was running.
Job User
ID ATTR_JOBUSER
Type String
Description
The name of the user that created the spooled file.
Length of Page
ID ATTR_PAGELEN
Type Float
Description
The length of a page. Units of measurement are specified in the measurement method attribute.
Line Spacing
ID ATTR_LINESPACING
Type String
Description
How a file's line data records are spaced when printed. The information is returned only for
*LINE and *AFPDSLINE printer device types files. Valid values are *SINGLE, *DOUBLE,
*TRIPLE, or *CTLCHAR.
Measurement Method
ID ATTR_MEASMETHOD
Type String
Description
The measurement method that is used for the length of page and width of page attributes. Valid
values are *ROWCOL, *UOM.
Message ID
ID ATTR_MESSAGEID
Type String
Description
The message ID.
Message Queue
ID ATTR_MESSAGE_QUEUE
Type String
Description
The Integrated File System path of the message queue that the writer uses for operational
messages. The format of the Integrated File System path is "/QSYS.LIB/library.LIB/
messageque.MSGQ" where library is the library that contains the message queue and messageque is
the name of the message queue.
Message Reply
ID ATTR_MSGREPLY
Type String
Description
The message reply. Text string to be provided by the client which answers a message of type
"inquiry". In the case of message retrieved, the attribute value is returned by the server and
contains the default reply which the client can use. The system limits the length to 132 characters.
Must be null-terminated due to variable length.
Message Text
ID ATTR_MSGTEXT
Type String
Description
The message text, that is sometimes known as first-level text, can be returned by a "retrieve
message" request. The system limits the length to 132 characters.
Message Type
ID ATTR_MSGTYPE
Type String
Description
The message type, a 2-digit, EBCDIC encoding. Two types of messages indicate whether one can
"answer" a "retrieved" message: '04' Informational messages convey information without asking
for a reply (may require a corrective action instead), '05' Inquiry messages convey information
and ask for a reply.
Network Identifier
ID ATTR_NETWORK
Type String
Description
The network identifier of the system where the file was created.
Number of Files
ID ATTR_NUMFILES
Type Integer
Description
The number of spooled files that exist on the output queue.
Operator Controlled
ID ATTR_OPCNTRL
Type String
Description
Whether users with job control authority are allowed to manage or control the spooled files on
this queue. Valid values are *YES, *NO.
Output Bin
ID ATTR_OUTPUTBIN
Type Integer
Description
The output bin the printer uses for the printed output. Values range from 1 to 65535. The value
*DEVD is encoded as 0.
Output Queue
ID ATTR_OUTPUT_QUEUE
Type String
Description
The Integrated File System path of the output queue. The format of the Integrated File System
path is "/QSYS.LIB/library.LIB/queue.OUTQ" where library is the library that contains the output
queue and queue is the name of the output queue.
Overall Status
ID ATTR_OVERALLSTS
Type Integer
Description
The overall status of the "logical printer". "Logical printer" refers to printer device, output queue
and writer job. Valid values are 1 (unavailable), 2 (powered off or not yet available), 3 (stopped),
4 (message waiting), 5 (held), 6 (stop pending), 7 (hold pending), 8 (waiting for printer), 9
(waiting to start), 10 (printing), 11 (waiting for output queue), 12 (connect pending), 13 (powered
off), 14 (unusable), 15 (being serviced), 999 (unknown).
Page At A Time
ID ATTR_PAGE_AT_A_TIME
Type String
Description
Specifies whether the spooled file is to be opened in page-at-a-time mode. Valid values are *YES
and *NO.
Page Definition
ID ATTR_PAGE_DEFINITION
Type String
Description
The Integrated File System path name of the page definition or a special value. If an Integrated
File System path is specified the format is "/QSYS.LIB/library.LIB/pagedef.PAGDFN" where
library is the library of the page definition and pagedef is the name of the page definition. Valid
special values include *NONE.
Page Number
ID ATTR_PAGENUMBER
Type Integer
Description
The number of the page to be read from a spooled file opened in page-at-a-time mode.
Paper Source 1
ID ATTR_PAPER_SOURCE_1
Type String
Description
The size of the paper in paper source one. If this field is not specified or the value is not valid,
the special value of *MFRTYPMDL is used. Valid values are *NONE - there is no paper source
one or the paper is manually fed into the printer, *MFRTYPMDL - the paper size suggested by
the manufacturer type and model is used, *LETTER (8.5 x 11.0 inches), *LEGAL (8.5 x 14.0
inches), *EXECUTIVE (7.25 x 10.5 inches), *LEDGER (17.0 x 11.0 inches), *A3 (297mm x 420mm),
*A4 (210mm x 297mm), *A5 (148mm x 210mm), *B4 (257mm x 364mm), *B5 (182mm x 257mm),
*CONT80 (8.0 inches wide with continuous form), *CONT132 (13.2 inches wide with continuous
form).
Paper Source 2
ID ATTR_PAPER_SOURCE_2
Type String
Description
The size of the paper in paper source two. If this field is not specified or the value is not valid,
the special value of *MFRTYPMDL is used. Valid values are *NONE - there is no paper source
two or the paper is manually fed into the printer, *MFRTYPMDL - the paper size suggested by
the manufacturer type and model is used, *LETTER (8.5 x 11.0 inches), *LEGAL (8.5 x 14.0
inches), *EXECUTIVE (7.25 x 10.5 inches), *LEDGER (17.0 x 11.0 inches), *A3 (297mm x 420mm),
Pel Density
ID ATTR_PELDENSITY
Type String
Description
For font resources only, this value is an encoding of the number of pels ("1" represents a pel size
of 240, "2" represents a pel size of 320). Additional values may become meaningful as the server
defines them.
Point Size
ID ATTR_POINTSIZE
Type Float
Description
The point size in which this spooled file's text is printed. The special value *NONE will be
encoded as 0.
Print Fidelity
ID ATTR_FIDELITY
Type String
Description
The kind of error handling that is performed when printing. Valid values are *ABSOLUTE,
*CONTENT.
Print Quality
ID ATTR_PRTQUALITY
Type String
Description
The print quality that is used when printing this spooled file. Valid values are *STD, *DRAFT,
*NLQ, *FASTDRAFT.
Print Sequence
ID ATTR_PRTSEQUENCE
Type String
Description
Print sequence. Valid values are *NEXT.
Printer
ID ATTR_PRINTER
Type String
Description
The name of the printer device.
Printer Assigned
ID ATTR_PRTASSIGNED
Type String
Description
Indicates if the printer is assigned. Valid values are 1 (assigned to a specific printer), 2 (assigned
to multiple printers), 3 (not assigned).
Printer File
ID ATTR_PRINTER_FILE
Type String
Description
The Integrated File System path of the printer file. The format of the Integrated File System path
is "/QSYS.LIB/library.LIB/printerfile.FILE" where library is the library that contains the printer
file and printerfile is the name of the printer file.
Printer Queue
ID ATTR_RMTPRTQ
Type String
Description
The name of the destination printer queue when sending spooled files via SNDTCPSPLF (LPR).
Record Length
ID ATTR_RECLENGTH
Type Integer
Description
Record length.
Reduce Output
ID ATTR_REDUCE
Type String
Description
The manner in which multiple logical pages print on each side of a physical page. Valid values
*TEXT or ????.
Remote System
ID ATTR_RMTSYSTEM
Replacement Character
ID ATTR_RPLCHAR
Type String
Description
The character that replaces any unprintable characters.
Restart Printing
ID ATTR_RESTART
Type Integer
Description
Restart printing. Valid values are -1, -2, -3, or the page number to restart at. The value *STRPAGE
is encoded as -1, the value *ENDPAGE is encoded as -2, and the value *NEXT is encoded as -3.
Seek Offset
ID ATTR_SEEKOFF
Seek Origin
ID ATTR_SEEKORG
Type Integer
Description
Valid values include 1 (beginning or top), 2 (current), and 3 (end or bottom).
Send Priority
ID ATTR_SENDPTY
Type String
Description
Send priority. Valid values are *NORMAL, *HIGH.
Separator page
ID ATTR_SEPPAGE
Type String
Description
Allows a user the option of printing a banner page or not. Valid values are *YES or *NO.
Source Drawer
ID ATTR_SRCDRWR
Type Integer
Description
The drawer to be used when the automatic cut sheet feed option is selected. Valid values are -1,
-2, 1-255. The value *E1 is encoded as -1, and the value *FORMDF is encoded as -2.
Spool SCS
ID ATTR_SPLSCS
Type Long
Description
Determines how SCS data is used during create spool file.
Started By User
ID ATTR_STARTEDBY
Type String
Description
The name of the user who started the writer.
Starting Page
ID ATTR_STARTPAGE
Text Description
ID ATTR_DESCRIPTION
Type String
Description
Text to describe an instance of an AS400 object.
Total Pages
ID ATTR_PAGES
Type Integer
Description
The number of pages that are contained in a spooled file.
Unit of Measure
ID ATTR_UNITOFMEAS
Type String
Description
The unit of measure to use for specifying distances. Valid values are *CM, *INCH.
User Comment
ID ATTR_USERCMT
Type String
Description
The 100 characters of user-specified comment that describe the spooled file.
User Data
ID ATTR_USERDATA
Type String
Description
The 10 characters of user-specified data that describe the spooled file. Valid special values include
*SOURCE.
User ID
ID ATTR_TOUSERID
Type String
Description
User id to whom the spooled file is sent.
Viewing Fidelity
ID ATTR_VIEWING_FIDELITY
Type String
Description
The processing to take place when viewing a page of spooled file data (in page-at-a-time mode).
Valid values are *ABSOLUTE and *CONTENT(default). To process all non-raster data
(commands) prior to the current page, *ABSOLUTE is used. For SCS files, *CONTENT is used to
process only open time commands plus the current page. For AFPDS files, *CONTENT is used to
process the first page of data plus the current page.
VM/MVS Class
ID ATTR_VMMVSCLASS
Type String
Description
VM/MVS class. Valid values are A-Z and 0-9.
Width of Page
ID ATTR_PAGEWIDTH
Type Float
Description
The width of a page. Units of measurement are specified in the measurement method attribute.
Writer Started
ID ATTR_WTRSTRTD
Type String
Description
Indicates whether a writer is started for this printer. Values are 1 - yes a writer is started, 0 - no
writer is started.
Writing Status
ID ATTR_WRTNGSTS
Type String
Description
Indicates whether the print writer is in writing status. Values are *YES - the writer is in writing
status, *NO - the writer is not in writing status, *FILE - the writer is writing the file separators.
NPS CCSID
ID ATTR_NPSCCSID
Type Integer
Description
CCSID that the Network Print Server expects that all strings will be encoded in.
NPS Level
ID ATTR_NPSLEVEL
Description
The version, release, and modification level of the Network Print Server. This attribute is a
character string encoded as VXRYMY (ie. "V3R1M0") where
X is in (0..9)
Y is in (0..9,A..Z)
You can use the copy method of the SpooledFile class to create a copy of the spooled file that the
SpooledFile object represents.
SpooledFile.copy() is a new method available to you only if you download JTOpen 3.2 or later or apply
an IBM i fix. It is recommended that the better solution is to download and use JTOpen. For more
information, see the following:
The copy method uses the Create Spooled File (QSPCRTSP) API within the network print server job to
create an exact replica of the spooled file. You need only a unique creation date and time to preserve the
identity of the newly created copy of the spooled file.
Specifying an output queue as a parameter to the copy method creates the copy of the spooled file to the
first position on the specified output queue. Both the output queue and the original spooled file must
reside on the same system
Note: Read the Code example disclaimer for important legal information.
This example shows how to use SpooledFile.copy() to copy a spooled file to the same queue that contains
the file you want to copy. When you want to route the newly copied spooled file to a specific output
queue, pass the output queue as a parameter to the copy method:
SpooledFile newSplf = new sourceSpooledFile.copy(<outqname>);
You can use the SpooledFileOutputStream class to create new server spooled files. The class derives from
the standard JDK java.io.OutputStream class; after its construction, it can be used anywhere an
OutputStream is used.
When creating a new SpooledFileOutputStream, the caller may specify the following:
v Which printer file to use
v Which output queue to put the spooled file on
v A PrintParameterList object that may contain parameters to override fields in the printer file
These parameters are all optional (the caller may pass null of any or all of them). If a printer file is not
specified, the network print server uses the default network print printer file, QPNPSPRTF. The output
queue parameter is there as a convenience; it also can be specified in the PrintParameterList. If the output
queue parameter is specified in both places, the PrintParameterList field overrides the output queue
parameter. See the documentation of the SpooledFileOutputStream constructor in the Javadoc for a
complete list of which attributes may be set in the PrintParameterList for creating new spooled files.
Use one of the write() methods to write data into the spooled file. The SpooledFileOutputStream object
buffers the data and sends it when either the output stream is closed or the buffer is full. Buffering is
done for two reasons:
v It allows the automatic data typing (see Data stream types in spooled files) to analyze a full-buffer of
data to determine the data type
v It makes the output stream work faster because not every write request is communicated to the server
Use the flush() method to force the data to be written to the server.
When the caller is finished writing data to the new spooled file, the close() method is called to close the
spooled file. Once the spooled file has been closed, no more data can be written to it. By calling the
getSpooledFile() method once the spooled file has been closed, the caller can get a reference to a
SpooledFile object that represents the spooled file.
Use the Printer Data Type attribute of the spooled file to set the type of data to be put into the spooled
file. If the caller does not specify a printer data type, the default is to use automatic data typing. This
method looks at the first few thousand bytes of the spooled file data, determines if it fits either SNA
Character Stream (SCS) or Advanced Function Printing data stream (AFPDS) data stream architectures,
and then sets the attribute appropriately. If the bytes of spooled file data do not match either of these
architectures, the data is tagged as *USERASCII. Automatic data typing works most of the time. The
caller generally uses it unless the caller has a specific case in which automatic data typing does not work.
In those cases, the caller can set the Printer Data Type attribute to a specific value (for example, *SCS). If
the caller wants to use the printer data that is in the printer file, the caller must use the special value
*PRTF. If the caller overrides the default data type when creating a spooled file, caution must be used to
ensure that the data put into the spooled file matches the data type attribute. Putting non-SCS data into a
spooled file that is marked to receive SCS data triggers an error message from the host and the loss of the
spooled file.
To generate spooled files that will print on certain printers attached to the server, an SNA Character
Stream (SCS) data stream must be created. SCS is a text-based, EBCDIC data stream that can be printed
on SCS printers, IPDS printers, or to PC printers. SCS can be printed by converting it using an emulator
or the host print transform on the server.
You can use the SCS writer classes to generate such an SCS data stream. The SCS writer classes convert
Java Unicode characters and formatting options into an SCS data stream. Five SCS writer classes generate
varying levels of SCS data streams. The caller chooses the writer that matches the final printer destination
to which the caller or end user will be printing.
Use the following SCS writer classes to generate an SCS printer data stream:
To construct an SCS writer, the caller needs an output stream and, optionally, an encoding. The data
stream is written to the output stream. To create an SCS spooled file, the caller first constructs a
SpooledFileOutputStream, and then uses that to construct an SCS writer object. The encoding parameter
gives a target EBCDIC coded character set identifier (CCSID) to convert the characters to.
Once the writer is constructed, use the write() methods to output text. Use the carriageReturn(),
lineFeed(), and newLine() methods to position the write cursor on the page. Use the endPage() method to
end the current page and start a new page.
When all of the data has been written, use the close() method to end the data stream and close the output
stream.
“Example: Creating SCS spooled files” on page 532 shows how to generate a SCS data stream using the
SCS3812Writer class, and how to write the stream to a spooled file on the server:
You can use the PrintObjectInputStream class to read the raw contents of a spooled file or Advanced
Function Printing (AFP) resource from the server. The class extends the standard JDK java.io.InputStream
class so that it can be used anywhere an InputStream is used.
Use one of the read() methods for reading from the input stream. These methods all return the number of
bytes actually read, or -1 if no bytes were read and the end of file was reached.
Use the available() method of PrintObjectInputStream to return the total number of bytes in the spooled
file or AFP resource. The PrintObjectInputStream class supports marking the input stream, so
PrintObjectInputStream always returns true from the markSupported() method. The caller can use the
mark() and reset() methods to move the current read position backward in the input stream. Use the
skip() method to move the read position forward in the input stream without reading the data.
Example
The following example shows how to use PrintObjectInputStream to read an existing server spooled file
You can use the PrintObjectPageInputStream class to read the data out of a server AFP and SCS spooled
file one page at a time.
Use one of the read() methods for reading from the input stream. All these methods return the number of
bytes actually read, or -1 if no bytes were read and the end of page was reached.
Use the available() method of PrintObjectPageInputStream to return the total number of bytes in the
current page. The PrintObjectPageInputStream class supports marking the input stream, so
PrintObjectPageInputStream always returns true from the markSupported() method. The caller can use
the mark() and reset() methods to move the current read position backward in the input stream so that
subsequent reads reread the same bytes. The caller can use the skip() method to move the read position
forward in the input stream without reading the data.
However, when transforming an entire spooled file data stream is desired, use the
PrintObjectTransformedInputStream class.
Example
ProductLicense class
The ProductLicense class enables you to request licenses for products installed on the system. To be
compatible with other IBM i license users, the class works through IBM i product license support when
requesting or releasing a license.
The class does not enforce the license policy but returns enough information such that the application can
enforce the policy. When a license is requested the ProductLicense class will return the status of the
request -- license granted or denied. If the request is denied the application must disable the behavior
that required the license because the IBM Toolbox for Java does not know which function to disable.
Use the ProductLicense class with IBM i license support to enforce the license of your application:
v The server side of your application registers your product and license terms with IBM i license
support.
v The client side of your application uses the ProductLicense object to request and release licenses.
For example, suppose your customer bought 15 concurrent use licenses for your product. Concurrent use
means 15 users can use the product at the same time, but it does not need to be 15 specific users. It can
be any 15 users in the organization. This information is registered with IBM i license support. As users
connect your application uses the ProductLicense class to request a license.
v When the number of concurrent users is fewer than 15, the request is successful and your application
runs.
v When the 16th user connects, the ProductLicense request fails. Your application then displays an error
message and terminates.
When a user stops running the application, your application releases the license by way of the
ProductLicense class. The license is now available for someone else to use.
Related information:
ProductLicense Javadoc
ProgramCall class
The IBM Toolbox for Java ProgramCall class allows the Java program to call a IBM i program. You can
use the ProgramParameter class to specify input, output, and input/output parameters. If the program
runs, the output and input/output parameters contain the data that is returned by the IBM i program. If
the IBM i program fails to run successfully, the Java program can retrieve any resulting IBM i messages
as a list of AS400Message objects.
The program name and parameter list can be set on the constructor, through the ProgramCall
setProgram() method, or on the run() method The run() method calls the program.
Using the ProgramCall class causes the AS400 object to connect to the server. See managing connections
for information about managing connections.
The ProgramCall object requires the integrated file system path name of the program.
The default behavior is for IBM i programs to run in a separate server job, even when the Java program
and the IBM i program are on the same server. You can override the default behavior and have the IBM i
program run in the Java job using the ProgramCall setThreadSafe() method.
You can use the ProgramParameter objects to pass parameter data between the Java program and the
IBM i program. Set the input data with the setInputData() method. After the program is run, retrieve the
output data with the getOutputData() method. Each parameter is a byte array. The Java program must
convert the byte array between Java and IBM i formats. The data conversion classes provide methods for
converting data. Parameters are added to the ProgramCall object as a list.
Note: Read the Code example disclaimer for important legal information.
The following example shows how to use the ProgramParameter object to pass parameter data.
// Create an AS400 object
AS400 sys = new AS400("mySystem.myCompany.com");
QSYSObjectPathName class
You can use the QSYSObjectPathName class to represent an object in the integrated file system. Use this
class to build an integrated file system name or to parse an integrated file system name into its
components.
Several of the IBM Toolbox for Java classes require an integrated file system path name in order to be
used. Use a QSYSObjectPathName object to build the name.
Note: Read the Code example disclaimer for important legal information.
Example 1: The ProgramCall object requires the integrated file system name of the server program to call.
A QSYSObjectPathName object is used to build the name. To call program PRINT_IT in library REPORTS
using a QSYSObjectPathName:
// Create an AS400 object.
AS400 sys = new AS400("mySystem.myCompany.com");
Example 2: If the name of the object is used just once, the Java program can use the toPath() method to
build the name. This method is more efficient than creating a QSYSObjectPathName object.
// Create an AS400 object.
AS400 sys = new AS400("mySystem.myCompany.com");
Example 3: In this example, a Java program was given an integrated file system path. The
QSYSObjectPathName class can be used to parse this name into its components.
// Create a path name object from
// the fully qualified integrated
// file system name.
QSYSObjectPathName ifsName = new QSYSObjectPathName(pathName);
Record-level access
The record-level access classes create, read, update, and delete IBM i files and members.
v Create a IBM i physical file specifying one of the following:
– The record length
– An existing data description specifications (DDS) source file
– A RecordFormat object
v Retrieve the record format from a physical or logical file, or the record formats from a IBM i multiple
format logical file.
Note: The record format of the file is not retrieved in its entirety. The record formats retrieved are
meant to be used when setting the record format for an AS400File object. Only enough
information is retrieved to describe the contents of a record of the file. Record format
information, such as column headings and aliases, is not retrieved.
v Access the records in an IBM i file sequentially, by record number, or by key.
Note: The record-level access classes do not support logical join files or null key fields.
The record-level access classes require an AS400 object that represents the system that has the database
files. Using the record-level access classes causes the AS400 object to connect to the IBM i system. See
managing connections for information about managing connections.
The record-level access classes require the integrated file system path name of the data base file. See
integrated file system path names for more information.
Examples
v The sequential access example shows how to access a system file sequentially.
v The read file example shows how to use the record-level access classes to read a system file.
v The keyed file example shows how to use the record-level access classes to read records by key from a
system file.
AS400File:
KeyedFile:
The KeyedFile class gives a Java program keyed access to a file on the server. Keyed access means that
the Java program can access the records of a file by specifying a key. Methods exist to position the cursor,
read, update, and delete records by key.
Methods are also provided for specifying a search criteria when positioning, reading, and updating by
key. Valid search criteria values are as follows:
v Equal - find the first record whose key matches the specified key.
v Less than - find the last record whose key comes before the specified key in the key order of the file.
v Less than or equal - find the first record whose key matches the specified key. If no record matches the
specified key, find the last record whose key comes before the specified key in the key order of the file.
v Greater than - find the first record whose key comes after the specified key in the key order of the file.
v Greater than or equal - find the first record whose key matches the specified key. If no record matches
the specified key, find the first record whose key comes after the specified key in the key order of the
file.
The key for a KeyedFile object is represented by an array of Java Objects whose types and order
correspond to the types and order of the key fields as specified by the RecordFormat object for the file.
The following example shows how to specify the key for the KeyedFile object.
// Specify the key for a file whose key fields, in order,
// are:
// CUSTNAME CHAR(10)
A KeyedFile object accepts partial keys as well as complete keys. However, the key field values that are
specified must be in order.
For example:
// Specify a partial key for a file whose key fields,
// in order, are:
// CUSTNAME CHAR(10)
// CUSTNUM BINARY(9)
// CUSTADDR CHAR(100)VARLEN()
Object[] partialKey = new Object[2];
partialKey[0] = "John Doe";
partialKey[1] = new Integer(445123);
The key field values for a record can be obtained from the Record object for a file through the
getKeyFields() method.
....
SequentialFile:
The SequentialFile class gives a Java program access to a file on the server by record number. Methods
exist to position the cursor, read, update, and delete records by record number.
// ....
AS400FileRecordDescription:
The IBM Toolbox for Java AS400FileRecordDescription class provides the methods for retrieving the
record format of a file on the server.
This class provides methods for creating Java source code for subclasses of RecordFormat and for
returning RecordFormat objects, which describe the record formats of user-specified physical or logical
files on the server. The output of these methods can be used as input to an AS400File object when setting
the record format.
Note: The AS400FileRecordDescription class does not retrieve the entire record format of a file. Only
enough information is retrieved to describe the contents of the records that make up the file.
Information such as column headings, aliases, and reference fields is not retrieved. Therefore, the
record formats retrieved cannot necessarily be used to create a file whose record format is identical
to the file from which the format was retrieved.
Creating Java source code for subclasses of RecordFormat to represent the record format of files on the
server
Note: This method overwrites files with the same names as the Java source files being created.
Example 1: The following example shows how to use the createRecordFormatSource() method:
// Create an AS400 object, the file exists on this
// server.
AS400 sys = new AS400("mySystem.myCompany.com");
// Assuming that the format name for file MYFILE is FILE1, the
// file FILE1Format.java will be created in the current working directory.
// It will overwrite any file by the same name. The name of the class
// will be FILE1Format. The class will extend from RecordFormat.
Example 2: Compile the file you created above, FILE1Format.java, and use it as follows:
// Create an AS400 object, the file exists on this
// server.
AS400 sys = new AS400("mySystem.myCompany.com");
myFile.setRecordFormat(new FILE1Format());
Creating RecordFormat objects to represent the record format of files on the server
Physical files on the server are created by specifying a record length, an existing server data description
specifications (DDS) source file, or a RecordFormat object.
When you create a file and specify a record length, a data file or a source file can be created. The method
sets the record format for the object. Do not call the setRecordFormat() method for the object.
A data file has one field. The field name is the name of the file, the field type is of type character, and the
field length is the length that is specified on the create method.
// ....
Example 2: When creating a file specifying an existing DDS source file, the DDS source file is specified on
the create() method. The record format for the file must be set using the setRecordFormat() method before
the file can be opened. For example:
// Create an AS400 object, the
// file will be created on this server.
AS400 sys = new AS400("mySystem.myCompany.com");
// ....
Example 3: When creating a file specifying a RecordFormat object, the RecordFormat object is specified
on the create() method. The method sets the record format for the object. The setRecordFormat() method
must not be called for the object.
// ....
You can use the AS400File class to read, write, update, and delete records in files on the server.
The record is accessed through the Record class, which is described by a RecordFormat class. The record
format must be set through the setRecordFormat() method before the file is opened, unless the file was
just created (without an intervening close()) by one of the create() methods, which sets the record format
for the object.
Use the read() methods to read a record from the file. Methods are provided to do the following:
v read() - read the record at the current cursor position
v readFirst() - read the first record of the file
v readLast() - read the last record of the file
v readNext() - read the next record in the file
v readPrevious() - read the previous record in the file
....
Use the update() method to update the record at the cursor position.
For example:
// Create an AS400 object, the file exists on this
// server.
AS400 sys = new AS400("mySystem.myCompany.com");
....
Use the write() method to append records to the end of a file. A single record or an array of records can
be appended to the file.
Use the deleteCurrentRecord() method to delete the record at the cursor position.
Related information:
AS400File Javadoc
Locking files:
The Java program can lock a file to prevent other users from accessing the file while the first Java
program is using the file.
Lock types are as follows. You can find more information about the lock types in the AS400File Javadoc.
v Read/Exclusive Lock - The current Java program reads records, and no other program can access the
file.
v Read/Allow shared read Lock - The current Java program reads records, and other programs can read
records from the file.
v Read/Allow shared write Lock - The current Java program reads records, and other programs can
change the file.
v Write/Exclusive Lock - The current Java program changes the file, and no other program can access
the file.
v Write/Allow shared read Lock - The current Java program changes the file, and other programs can
read records from the file.
v Write/Allow shared write Lock - The current Java program changes the file, and other programs can
change the file.
To give up the locks obtained through the lock() method, the Java program starts the
releaseExplicitLocks() method.
Related information:
AS400File Javadoc
The IBM Toolbox for Java AS400File class uses record blocking to improve performance.
v If the file is opened for read-only access, a block of records is read when the Java program reads a
record. Blocking improves performance because subsequent read requests may be handled without
accessing the server. Little performance difference exists between reading a single record and reading
several records. Performance improves significantly if records can be served out of the block of records
cached on the client.
The number of records to read in each block can be set when the file is opened. For example:
IBM Toolbox for Java 169
// Create an AS400 object, the file exists on this
// server.
AS400 sys = new AS400("mySystem.myCompany.com");
// The records read in this loop will be served out of the block of
// records cached on the client.
record = myFile.readNext();
}
....
....
An open file has a cursor. The cursor points to the record to be read, updated, or deleted. When a file is
first opened the cursor points to the beginning of the file. The beginning of the file is before the first
record.
The following example shows how to use the positionCursorToFirst() method to position the cursor.
// Create an AS400 object, the file exists on this
// server.
AS400 sys = new AS400("mySystem.myCompany.com");
....
Commitment control:
Through commitment control, your Java program has another level of control over changing a file. With
commitment control turned on, transactions to a file are pending until they are either committed or rolled
back. If committed, all changes are put to the file. If rolled back, all changes are discarded. The
transaction can be changing an existing record, adding a record, deleting a record, or even reading a
record depending on the commitment control lock level specified on the open().
The levels of commitment control are as follows. To see more details about each level, refer to the
AS400File Javadoc.
v All - Every record accessed in the file is locked until the transaction is committed or rolled back.
v Change - Updated, added, and deleted records in the file are locked until the transaction is committed
or rolled back.
v Cursor Stability - Updated, added, and deleted records in the file are locked until the transaction is
committed or rolled back. Records that are accessed but not changed are locked only until another
record is accessed.
v None - There is no commitment control on the file. Changes are immediately put to the file and cannot
be rolled back.
You can use the AS400File startCommitmentControl() method to start commitment control. Commitment
control applies to the AS400 connection. Once commitment control is started for a connection, it applies
to all files opened under that connection from the time that commitment control was started. Files
opened before commitment control is started are not under commitment control. The level of
commitment control for individual files is specified on the open() method. Specify
COMMIT_LOCK_LEVEL_DEFAULT to use the same level of commitment control as was specified on the
startCommitmentControl() method.
For example:
// Create an AS400 object, the files exist on this
// server.
AS400 sys = new AS400("mySystem.myCompany.com");
ourFile.setRecordFormat(new OURFILEFormat());
// Specify a different commit lock level than
// when commitment control was started
ourFile.open(AS400File.READ_WRITE, 0, COMMIT_LOCK_LEVEL_CURSOR_STABILITY);
The commit() method commits all transactions since the last commit boundary for the connection. The
rollback() method discards all transactions since the last commit boundary for the connection.
Commitment control for a connection is ended through the endCommitmentControl() method. If a file is
closed before invoking the commit() or rollback() method, all uncommitted transactions are rolled back.
All files opened under commitment control must be closed before the endCommitmentControl() method
is called.
The following examples shows how to start commitment control, commit or roll back functions, and then
end commitment control:
// ... assume the AS400 object and file have been
// instantiated.
SaveFile class
The SaveFile class represents a save file on a server.
Related information:
SaveFile Javadoc
ServiceProgramCall class
The IBM Toolbox for Java ServiceProgramCall class allows you to call an IBM i service program.
ServiceProgramCall is a subclass of the ProgramCall class that you use to call IBM i programs. If you
want to call an IBM i program, use the ProgramCall class.
The ServiceProgramCall class makes it possible for you to call an IBM i service program, pass data to a
service program through input parameters, and access data the service program returns through output
parameters. Using ServiceProgramCall causes the AS400 object to connect to the server. See managing
connections for information about managing connections.
The default behavior is for service programs to run in a separate server job, even when the Java program
and the service program are on the same server. You can override the default behavior and have the
service program run in the Java job using the setThreadSafe() method, inherited from ProgramCall.
In order to use the ServiceProgramCall class, you must be sure to meet the following requirements:
v The service program must be on an server
v You can pass no more than seven parameters to the service program
v The return value of the service program is void or numeric
The ProgramParameter class works with the ServiceProgramCall class to pass parameter data to and from
an IBM i service program. You pass input data to the service program with setInputData().
You request the amount of output data you want returned with setOutputDataLength(). You retrieve the
output data after the service program is finished running with getOutputData(). In addition to the data
itself, ServiceProgramCall needs to know how to pass parameter data to the service program. The
setParameterType() method of ProgramParameter is used to supply this information. The type indicates if
the parameter is pass by value or pass by reference. In either case, data is sent from the client to the
server. Once the data is on the server, the server uses the parameter type to correctly call the service
program.
All parameters will be in the form of a byte array. Therefore, to convert between IBM i and Java formats,
you use the data conversion and description classes.
ServiceProgramCall Javadoc
ProgramCall Javadoc
Subsystem class
The Subsystem class represents a subsystem on the server.
Related information:
Subsystem Javadoc
SystemStatus classes
The SystemStatus classes allow you to retrieve system status information and to retrieve and change
system pool information.
The SystemStatus object allows you to retrieve system status information including the following:
v getUsersCurrentSignedOn(): Returns the number of users currently signed on the system
v getUsersTemporarilySignedOff(): Returns the number of interactive jobs that are disconnected
v getDateAndTimeStatusGathered(): Returns the date and time when the system status information was
gathered
v getJobsInSystem(): Returns the total number of user and system jobs that are currently running
v getBatchJobsRunning(): Returns the number of batch jobs currently running on the system
v getBatchJobsEnding(): Returns the number of batch jobs that are in the process of ending
v getSystemPools(): Returns an enumeration containing a SystemPool object for each system pool
In addition to the methods within the SystemStatus class, you also can access SystemPool through
SystemStatus. SystemPool allows you to get information about system pools and change system pool
information.
Example
Note: Read the Code example disclaimer for important legal information.
This example shows you how to use caching with the SystemStatus class:
AS400 system = new AS400("MyAS400");
SystemStatus status = new SystemStatus(system);
SystemPool class:
The SystemPool class allows you to retrieve and change system pool information.
Example
Note: Read the Code example disclaimer for important legal information.
//Create AS400 object.
AS400 as400 = new AS400("system name");
System values
The system value classes allow a Java program to retrieve and change system values and network
attributes. You can also define your own group to contain the system values you want.
Using the SystemValue class, retrieve a single system value by using the getValue() method and change a
system value by using the setValue() method.
You can also retrieve group information about a particular system value:
Whenever the value of a system value is retrieved for the first time, the value is retrieved from the server
and cached. On subsequent retrievals, the cached value is returned. If the current value is what you want
instead of the cached value, a clear() must be done to clear the current cache.
SystemValueList represents a list of system values on the specified server. The list is divided into several
system-defined groupsthat allow the Java program to access a portion of the system values at a time.
SystemValueGroup represents a user-defined collection of system values and network attributes. Rather
than a container, it is instead a factory for generating and maintaining unique collections of system
values.
You can create a SystemValueGroup by specifying one of the system-defined groups (one of the constants
in the SystemValueList class) or by specifying an array of system value names.
You can individually add the names of system values to include in the group by using the add() method.
You can also remove them by using the remove() method.
Once the SystemValueGroup is populated with the required system value names, obtain the real
SystemValue objects from the group by calling the getSystemValues() method. In this way, a
SystemValueGroup object takes a set of system value names and generates a Vector of SystemValue
objects, all having the system, group name, and group description of the SystemValueGroup.
To refresh a Vector of SystemValue objects all at once, use the refresh() method.
Note: Read the Code example disclaimer for important legal information.
The following example shows how to create and retrieve a system value:
//Create an AS400 object
AS400 sys = new AS400("mySystem.myCompany.com");
//At this point QSECOND is cached. Clear the cache to retrieve the most
//up-to-date value from the system.
sysval.clear();
second = (String)sysval.getValue();
The following example shows how to build a group of system value names and then manipulate them:
//Create an AS400 object
AS400 sys = new AS400("mySystem.myCompany.com");
//Create a system value group initially representing all of the network attributes on the system.
String name = "My Group";
String description = "This is one of my system values.";
SystemValueGroup svGroup = new SystemValueGroup(sys, name, description, SystemValueList.GROUP_NET);
//Add some more system value names to the group and remove some we do not want.
svGroup.add("QDATE");
svGroup.add("QTIME");
svGroup.remove("NETSERVER");
svGroup.remove("SYSNAME");
//Obtain the actual SystemValue objects. They are returned inside a Vector.
Vector sysvals = svGroup.getSystemValues();
//We can add another SystemValue object from another system into the group.
AS400 sys2 = new AS400("otherSystem.myCompany.com");
SystemValue sv = new SystemValue(sys2, "QDATE");
sysvals.addElement(sv);
Trace class
The Trace class allows the Java program to log trace points and diagnostic messages. This information
helps reproduce and diagnose problems.
Note: You can also set tracing by using the trace system properties.
The IBM Toolbox for Java classes also use the trace categories. When a Java program enables logging,
IBM Toolbox for Java information is included with the information that is recorded by the application.
You can enable the trace for a single category or a set of categories. Once the categories are selected, use
the setTraceOn method to turn tracing on and off. Data is written to the log using the log method.
You can send trace data for different components to separate logs. Trace data, by default, is written to
the default log. Use component tracing to write application-specific trace data to a separate log or
standard output. By using component tracing, you can easily separate trace data for a specific application
from other data.
Excessive logging can impact performance. Use the isTraceOn method to query the current state of the
trace. Your Java program can use this method to determine whether it builds the trace record before it
calls the log method. Calling the log method when logging is off is not an error, but it takes more time.
The default is to write log information to standard out. To redirect the log to a file, call the
setFileName() method from your Java application. In general, this works only for Java applications
because most browsers do not give applets access to write to the local file system.
Logging is off by default. Java programs provide a way for the user to turn on logging so that it is easy
to enable logging. For example, the application can parse for a command line parameter that indicates
which category of data is logged. The user can set this parameter when log information is needed.
Examples
Note: Read the Code example disclaimer for important legal information.
Example Using setTraceOn() and writing data to a log by using the log method
// Enable diagnostic, information, and warning logging.
Trace.setTraceDiagnosticOn(true);
Trace.setTraceInformationOn(true);
Trace.setTraceWarningOn(true);
// Send IBM Toolbox for Java and the component trace data each to separate files.
// The trace will contain all trace information, while each
// component log file will only contain trace information specific to
// that component. If a Trace file is not specified, all trace data
// will go to standard out with the component specified in front of
// each trace message.
// Trace.setFileName("c:\\bit.bucket");
// Trace.setFileName(myComponent1, "c:\\Component1.log");
// Trace.setFileName(myComponent2, "c:\\Component2.log");
// Log component specific trace data or general IBM Toolbox for Java
// trace data.
Trace.setFileName("c:\\bit.bucket");
Trace.setFileName(myComponent1, "c:\\Component1.log");
Related information:
Trace Javadoc
Some of the user information you can retrieve includes previous sign-on date, status, date the password
was last changed, date the password expires, and user class. When you access the User object, use the
setSystem() method to set the system name and the setName() method to set the user name. After those
steps, you use the loadUserInformation() method to get the information from the server.
The UserGroup object represents a special user whose user profile is a group profile. Using the
getMembers() method, a list of users that are members of the group can be returned.
The Java program can iterate through the list using an enumeration. All elements in the enumeration are
User objects; for example:
The only property of the UserList object that must be set is the AS400 object that represents the system
from which the list of users is to be retrieved.
By default, all users are returned. Use a combination of UserList methods setUserInfo() and
setGroupInfo() to specify exactly which users are returned.
User Javadoc
UserGroup Javadoc
UserList Javadoc
AS400 Javadoc
“Example: Using UserList to list all of the user in a given group” on page 554
This source is an example of IBM Toolbox for Java UserList. This program lists all of the users in a
given group.
UserSpace class
The UserSpace class represents a user space on the server. Required parameters are the name of the user
space and the AS400 object that represents the server that has the user space.
The UserSpace object requires the integrated file system path name of the program. See integrated file
system path names for more information.
The following example creates a user space, then writes data to it.
Note: Read the Code example disclaimer for important legal information.
// Create an AS400 object.
AS400 sys = new AS400("mySystem.myCompany.com");
Commtrace classes
The IBM Toolbox for Java commtrace classes enable your Java programs to work with communications
trace data for a specified LAN (Ethernet or token ring) line description. The commtrace package includes
a class that you can run as a standalone utility program to format communications trace data.
When you dump a communications trace for a server to a stream file, the information is saved in a
binary format. The commtrace classes enable you to work with the various components of the stream file.
Note: Communications trace files may contain confidential information, for example, unencrypted
passwords. When the communications trace file is on server, only users who have *SERVICE
special authority can access the trace data. If you move the file to a client, make sure that you
protect the file in an appropriate manner. For more information about communications traces, see
the links at the bottom of this page.
Other classes in the com.ibm.as400.commtrace package not listed here are specific to the type of trace
data that you want to work with. For more information about communications traces and about all the
commtrace classes, see Communications trace.
Commtrace model
The following illustration shows how the commtrace classes correspond to a communications trace file.
The graphic also indicates the naming conventions that the commtrace classes use for the components in
a communications trace.
The very first 24-byte section of data contains general information about the contents of the frame, such
as the frame number and data length. Use the Frame class to process this information.
The Format class serves as the interface between the calling program and the frames of the trace. The
FormatProperties class enables you to set and retrieve properties that determine how the Format object
behaves when it encounters information in the Frames of the trace.
Format class
Use the format class to read both the raw trace data and the trace data that you have already formatted
by using the commtrace classes.
Note: You cannot use the commtrace classes to read a communications trace that you formatted by using
the Print Communications Trace (PRTCMNTRC) control language command.
Use the Format class to parse and format the information in a trace, then send that formatted information
to a file or a print device. Additionally, you might want to create a graphical front end that displays the
information in a standalone application or within a browser. When you want to select only specific data,
IBM Toolbox for Java 183
use the Format class to supply that information to your Java program. For example you could use the
Format class to read IP addresses out of a trace and then use that data in your program.
The Format constructors accept arguments that represent unformatted data, such as an
IFSFileInputStream object, a local file, or the binary trace file. To display a trace that you have already
formatted, use the default Format constructor, then use Format.openIFSFile() or Format.openLclFile() to
specify the formatted file that you want to display.
Examples
The following examples show how you can display a saved trace or format a binary trace.
Note: Read the Code example disclaimer for important legal information.
You can also run the Format class as a standalone utility program. For more information, see the
following topic:
FormatProperties class
Use the FormatProperties class to specify and retrieve the properties for your Format object. In other
words, when you use the Format class to send information to a file, use the FormatProperties class to
filter the information that you want to send.
These properties specify how you want your Format object to handle the information that it encounters in
the Frames of the communications trace. The default behavior is for the Format object to ignore
properties for which you have not given a specific value.
Most of the properties are available to your Format object as filters that you set to explicitly include
specific data. Once you set the filters, the Format object displays only data that matches those filters. For
example, the following code set a filter to display frames that occurred between a particular start and end
time:
FormatProperties prop = new FormatProperties();
// Set the filter to start and end times of 22 July, 2002,
// 2:30 p.m. and 2:45 p.m. GMT.
// The time is expressed as a Unix(TM) timestamp, which is
// based on the standard epoch of 01/01/1970 at 00:00:00 GMT.
prop.setStartTime("1027348200");
prop.setEndTime("1027349100");
Example
The following example shows how you can use many of the commtrace classes, including the Format and
FormatProperties classes, to display trace information to your monitor:
In addition to using the Format class in your Java programs, you can run it as a standalone, command
line utility to format a communications trace. The program connects an IFSFileOutputStream to the
specified outfile and writes the data to that file.
Running format as a standalone utility enables you to format files by using the processing power and
storage space of your server.
To run the Format utility from a command line prompt, use the following command:
java com.ibm.as400.commtrace.Format [options]
where [options] equals one or more of the available options. Options include:
v The system to which you want to connect
v The userID and password for the system
v The communications trace that you want to parse
v The file in which you want to store the results
For a complete list of available options, see the Javadoc reference documentation for the Format class.
String[] args2 =
{ "-c", "true", "-t", "/path/to/trace", "-o", "/path/to/trace.extension"};
jaCall.setParameters(args2);
if (jaCall.run() != true) {
// Call Failed
}
Related information:
Format Javadoc
Prolog class
The IBM Toolbox for Java Prolog class represents the initial 256-byte section of a communications trace
for a LAN line description. The Prolog contains general information about the trace, such as start and end
times, number of bytes collected, and so on. Use the Prolog class to retrieve information from this section
of trace, which you can then print, display, filter, or process in some other way.
The Prolog class provides methods that allow you to perform a variety of actions that include the
following:
v Retrieve values from the fields of the prolog, such as the trace description, Ethernet Type, data
direction, IP address, and so on
v Return a formatted String that contains all the fields of the prolog
v Test the prolog fields for invalid data
Example
The following example shows how you can use many of the commtrace classes, including the Prolog
class, to display trace information to your monitor:
Frame class
The Frame class represents all the data in one record, or frame, in a communications trace for a LAN line
description.
Each Frame contains three main sections of data that appear in the following order:
1. An initial 24-byte section that contains general information about the frame
2. General information about the frame (represented by the LanHeader class)
3. The packet data (represented by subclasses of the IPacket abstract class)
Use the Frame class to parse and create a printable representation the data in the frame. The Frame class
maintains the packet data in a linked list-like structure that uses specific formats. For specific information
about the possible formats for packet data in a frame and for general information about the structure of a
frame, see “Commtrace model” on page 182.
The Frame class provides methods that allow you to perform a variety of actions that include the
following:
You can use the following process to access the data in a packet:
1. Use Frame.getPacket() to retrieve the packet
2. Access the data in the header by calling Packet.getHeader()
3. After you retrieve the header, call Header.getType() to find the type
4. Use the specific Header subclass to access the data associated with that header (the payload) and any
additional headers
Example
The following example shows how you can use many of the commtrace classes, including the Format and
FormatProperties classes, to display trace information to your monitor:
LanHeader class
The LanHeader class retrieves information from the section of data that occurs once, near the beginning
of a frame, in the initial 24-byte section. This section typically contains hardware-specific information that
includes general information about the frame, such as the frame number, and data length.
Use the LanHeader class to parse and print the information in the LanHeader. The kind of information
contained by the LanHeader includes:
v The byte that identifies the start of the first header in this packet
v Medium Access Control (MAC) addresses
v Token ring addresses and routing information
LanHeader also provides two methods that enable you to return a formatted String that contains the
following:
v Token ring routing data
v Source MAC addresses, destination MAC addresses, frame format, and frame type
Related information:
LanHeader Javadoc
IPPacket class
The IBM Toolbox for Java IPPacket class represents all the data packets that the network transmitted for
this frame during the communications trace. IPPacket is an abstract class, so you will use the various
concrete subclasses to process the headers and data in the packets.
Packet classes enable you to retrieve the type of packet and access the raw data (the header and payload)
that the packet contains. All the subclasses use similar constructors and include one additional method
that returns a printable version of the packet contents as a String.
The Packet classes provide methods that allow you to perform a variety of actions that include the
following:
v Retrieve the name and type of the packet
v Set the type of the packet
v Return the top-level Header object associated with the packet
v Return all the packet data as an unformatted String
v Return specific data from the packet as a formatted String
IPPacket Javadoc
ARPPacket Javadoc
IP4Packet Javadoc
IP6Packet Javadoc
UnknownPacket Javadoc
Header class
The Header class is the abstract superclass for creating classes that represent specific kinds of packet
headers. Packet headers include the associated data (or payload), which can be other headers and
payloads.
Header classes enable you to retrieve the data for the header and the payload. One header can
encapsulate other headers and their payloads.
Creating an instance of a Packet class automatically creates the appropriate Header object. The Header
classes provide methods that allow you to perform a variety of actions that include the following:
v Return the length, name, and type of the header
v Retrieve the data in the header as a byte array
v Retrieve the next header in the packet
v Retrieve the payload as a byte array, ASCII string, and hexadecimal string
v Return all the header data as an unformatted String
v Return specific data from the header as a formatted String
Header Javadoc
ARPHeader Javadoc
ExtHeader Javadoc
ICMP4Header Javadoc
ICMP6Header Javadoc
188 IBM i: Programming IBM Toolbox for Java
IP4Header Javadoc
IP6Header Javadoc
TCPHeader Javadoc
UDPHeader Javadoc
UnknownHeader Javadoc
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////
//
// Example using the commtrace classes to print communications trace
// data to a monitor by using a communications trace binary file as
// the source for the data.
//
// Command syntax:
// java CommTraceExample
//
//////////////////////////////////////////////////////////////////////
import com.ibm.as400.util.commtrace.*;
public CommTraceExample() {
// Create a FormatProperties. By default display everything.
FormatProperties fmtprop = new FormatProperties();
// If IP6 IPPacket
if (p.getType() == IPPacket.IP6) {
// If IP6 Header
if (h.getType() == Header.IP6) {
// If it is a TCP header
if (h.getType() == Header.TCP) {
// Cast so we can access methods
TCPHeader tcp = (TCPHeader) h;
System.out.println(h.getName() +" src:" + tcp.getSrcPort() +" dst:" + tcp.getDstPort());
System.out.println("Complete " + h.getName() + ":\n" + tcp.toString(fmtprop));
// If it is a UDP header
} else if (h.getType() == Header.UDP) {
// Cast so we can access methods
UDPHeader udp = (UDPHeader) h;
System.out.println(h.getName() +" src:" + udp.getSrcPort() + " dst:" + udp.getDstPort());
System.out.println("Complete " + h.getName() + ":\n" + udp.toString(fmtprop));
}
}
}
}
}
}
}
HTML Classes
The IBM Toolbox for Java HTML classes provide representations for many common HTML tag elements.
The HTML classes implement the HTMLTagElement interface. Each class produces an HTML tag for a
specific element type. The tag may be retrieved using the getTag() method and can then be embedded
into any HTML document. The tags you generate with the HTML classes are consistent with the HTML
3.2 specification.
The HTML classes can work with servlet classes to get data from the server. However, they can also be
used alone if you supply the table or form data.
Note: The jt400Servlet.jar file includes both the HTML and Servlet classes. You must update your
CLASSPATH to point to the jt400Servlet.jar file if you want to use the classes in the
com.ibm.as400.util.html package.
Related information:
HTMLTagElement Javadoc
DirFilter Javadoc - Use to determine if a File object is a directory
HTMLFileFilter Javadoc - Use to determine if a File object is a file
URLEncoder Javadoc - Encodes delimiters to use in a URL string
URLParser Javadoc - Allows you to parse a URL string for the URI, properties, and reference
BidiOrdering class
The IBM Toolbox for Java BidiOrdering class represents an HTML tag that alters the language and
direction of text. An HTML <BDO> string requires two attributes, one for language and the other for the
direction of the text.
For more information about using the <BDO> HTML tag, see the W3C Web site.
Note: Read the Code example disclaimer for important legal information.
The following example creates a BidiOrdering object and sets its language and direction:
// Create a BidiOrdering object and set the language and direction.
BidiOrdering bdo = new BidiOrdering();
bdo.setDirection(HTMLConstants.RTL);
bdo.setLanguage("AR");
// Add the text to the BidiOrdering and get the HTML tag.
bdo.addItem(text);
bdo.getTag();
When you use this tag in an HTML page, browsers that can understand the <BDO> tag display the
example like this:
The HTMLAlign class represents the <DIV> tag and its associated align attribute. You can use right, left,
or center alignment.
You can use this class to perform a variety of actions that include the following:
v Add or remove items from the list of tags you want to align
v Get and set the alignment
v Get and set the direction of the text interpretation
v Get and set the language of the input element
v Get a string representation of the HTMLAlign object
Note: Read the Code example disclaimer for important legal information.
The following example creates an unordered list, then creates an HTMLAlign object to align the entire
list:
// Create an unordered list.
UnorderedList uList = new UnorderedList();
uList.setType(HTMLConstants.DISC);
UnorderedListItem uListItem1 = new UnorderedListItem();
uListItem1.setItemData(new HTMLText("Centered unordered list"));
uList.addListItem(uListItem1);
UnorderedListItem uListItem2 = new UnorderedListItem();
uListItem2.setItemData(new HTMLText("Another item"));
uList.addListItem(uListItem2);
When you use this tag in an HTML page, it looks like this:
v Centered unordered list
v Another item
Related information:
HTMLAlign Javadoc
HTMLDocument class
The HTMLDocument class enables you to use existing IBM Toolbox for Java HTML classes to create
either HTML pages or Portable Document Format (PDF) documents.
When you create an HTMLDocument, you specify whether it contains HTML tags or Extensible
Stylesheet Language (XSL) Formatting Object (FOs) tags:
v When you want to create HTML pages, the HTMLDocument class offers you an easier way to group
all the required HTML tags. However, HTML pages do not always look the same when you print them
as when you view them in a Web browser.
To use HTMLDocument, you need to include an XML parser and an XSLT processor in your
CLASSPATH environment variable. For more information, see the following pages:
v “JAR files” on page 10
v “XML parser and XSLT processor” on page 417
You can process the resulting HTML or XSL source data the way you want, for example, by displaying
the HTML, saving the XSL to a file, or using the streamed data in another part of your Java program.
For more information about creating HTML pages and XSL FO source data, see the following pages:
v “Using HTMLDocument to create HTML data”
v “Using HTMLDocument to create XSL FO data” on page 194
v “Examples: Using HTMLDocument” on page 196
HTMLDocument Javadoc
An HTMLDocument functions as a wrapper that holds the information necessary to create either HTML
or Extensible Stylesheet Language (XSL) Formatting Object (FO) source data. When you want to create
HTML pages, the HTMLDocument class offers you an easier way to group all the required HTML tags.
When creating HTML source, HTMLDocument retrieves HTML tags from the HTML objects you have
created. You can use either HTMLDocument.getTag() to stream all the elements you have defined or the
getTag() for each individual HTML object.
HTMLDocument generates HTML data as you define it in your Java program, so be sure that the
resulting HTML is complete and correct.
When you call HTMLDocument.getTag(), the HTMLDocument object performs the following actions:
v Generates the opening <HTML> tag. At the end of the data, it generates the closing </HTML> tag.
v Converts your HTMLHead and HTMLMeta objects into HTML tags.
v Generates the opening <BODY> tag immediately after the <HEAD> tag. At the end of the data, just
before the closing </HTML> tag, it generates the closing </BODY> tag.
Note: If you do not specify a <HEAD> tag, HTMLDocument generates the <BODY> tag after the
<HTML> tag.
v Converts your remaining HTML objects into HTML tags as your program directs.
Note: HTMLDocument streams the HTML tags as your Java program directs, so make sure that you call
the tags in the proper order.
The following example shows how to use HTMLDocument to generate HTML source data (and XSL FO
source):
“Example: Using HTMLDocument to generate both HTML source and XSL FO source” on page 199
For more information about the HTMLDocument class, see the following Javadoc reference
documentation:
HTMLDocument
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
An HTMLDocument functions as a wrapper that holds the information necessary to create either
Extensible Stylesheet Language (XSL) Formatting Object (FO) or HTML source data.
Generated XSL FO source follows the XSL FO formatting model. The model uses rectangular elements,
called areas, to hold the individual content elements, which can be images, text, other XSL FOs, or
nothing. The following list describes the four basic types of areas:
v Regions function as the highest level container.
v Block areas represent block level elements, for example, paragraphs or list items.
v Line areas represent a line of text inside of a block.
v Inline areas represent parts of a line, for example, a single character, a footnote, or a mathematical
equation.
XSL FO tags created by IBM Toolbox for Java adhere to the XSL standards described the W3C
recommendation. For more information about XSL, XSL FOs, and the W3C recommendation, see the
following:
When creating XSL FO source, HTMLDocument properties represent XSL FO tags that specify page size,
orientation, and margins. Additionally, HTMLDocument retrieves from many HTML classes the
corresponding XSL FO tags for that content element.
After you use HTMLDocument to generate the XSL FO source, you can use an XSL formatter (for
example, the XSLReportWriter class) to place the content elements on the pages of a document.
Note: Trying to retrieve XSL FO tags from HTML classes that do not have the getFoTag() method
results in a comment tag.
For more information about the HTML classes that include methods for working with XSL FO tags, see
the following Javadoc reference documentation:
After you create an instance of HTMLDocument and set the layout properties, retrieve XSL FO tags from
HTML objects by using the setUseFO(), getFoTag(), and getTag() methods.
v You can use setUseFO() on either the HTMLDocument or the individual HTML objects. When you use
setUseFO(), you can retrieve XSL FO tags by using HTMLDocument.getTag().
v Alternatively, you can use the getFoTag() method on either the HTMLDocument or the individual
HTML objects. You might want to use this alternative method when you need to be able to generate
both XSL FO and HTML source from the HTMLDocument or the HTML objects.
After you create XSL FO source data, you need to convert that XSL FO data to a form that your users can
view and print. The following examples show how to generate XSL FO source data (and HTML source)
and convert the XSL FO source data to a PDF document by using the XSLReportWriter and Context
classes:
“Example: Using HTMLDocument to generate both HTML source and XSL FO source” on page 199
For more information about the HTMLDocument class, see the following Javadoc reference
documentation:
HTMLDocument
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
This topic describes the IBM Toolbox for Java classes that are compatible with the HTMLDocument class.
Many IBM Toolbox for Java HTML classes feature the following methods, which enable instances of those
classes to work with HTMLDocument:
v getFoTag()
v getTag()
v setUseFO()
For more information about the HTMLDocument class and about the HTML classes that include methods
for working with XSL FOs, see the following Javadoc reference documentation:
v HTMLDocument
v BidiOrdering
v HTMLAlign
v HTMLHead
v HTMLHeading
v HTMLImage
v HTMLList
v HTMLListItem
v HTMLTable
v HTMLTableCaption
v HTMLTableCell
v HTMLTableHeader
v HTMLTableRow
v HTMLTagElement
v OrderedList
v UnorderedList
The following examples show ways that you can use the HTMLDocument class to generate HTML and
Extensible Stylesheet Language (XSL) Formatting Object (FO) source data.
Example: Using HTMLDocument to generate both HTML source and XSL FO source
The following example shows how to generate both HTML source data and XSL FO source data at the
same time:
“Example: Using HTMLDocument to generate both HTML source and XSL FO source” on page 199
After you create XSL FO source data, you need to convert that XSL FO data to a form that your users can
view and print. The following example shows how to convert a file that contains XSL FO source data to a
PDF document by using the XSLReportWriter and Context classes:
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
This example program should not be used as the XSLReportProcessor class is no longer supported.
Note: Read the Code example disclaimer for important legal information.
///////////////////////////////////////////////////////////////////////////////
//
// Example: Converting XSL FO source to a PDF.
//
// This program uses the IBM Toolbox for Java ReportWriter classes to convert
// XSL FO source data (created by using HTMLDocument) to a PDF.
//
// This example requires the following.jars to be in the classpath.
//
// composer.jar
// outputwriters.jar
// reportwriter.jar
// x4j400.jar
// xslparser.jar
//
// These JAR files are part of the IBM ToolBox for Java, and reside in directory
// /QIBM/ProdData/HTTP/Public/jt400/lib on your server.
//
// You will also need the class definition for
// org/apache/xerces/dom/NodeContainer, which resides
// in directory /QIBM/ProdData/OS400/xml/lib.
//
// Command syntax:
// ProcessXslFo FOfilename PDFfilename
//
///////////////////////////////////////////////////////////////////////////////
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.awt.print.Paper;
import java.awt.print.PageFormat;
import org.w3c.dom.Document;
import com.ibm.xsl.composer.framework.Context;
import com.ibm.as400.util.reportwriter.pdfwriter.PDFContext;
import com.ibm.as400.util.reportwriter.processor.XSLReportProcessor;
try
{
String inName = args[0];
String outName = args[1];
try
{
fin = new FileInputStream(inName);
fout = new FileOutputStream(outName);
}
catch (Exception e)
{
e.printStackTrace();
System.exit(0);
}
/*
* Setup Page format.
*/
Paper paper = new Paper();
paper.setSize(612, 792);
paper.setImageableArea(0, 0, 756, 936);
/*
* Create a PDF context. Set output file name.
*/
PDFContext pdfContext = new PDFContext(fout, pageFormat);
/*
* Create XSLReportProcessor instance.
*/
XSLReportProcessor report = new XSLReportProcessor(pdfContext);
/*
* Open XML FO source.
*/
try
{
report.setXSLFOSource(fin);
}
catch (Exception e)
{
e.printStackTrace();
System.exit(0);
}
/*
* Process the report.
*/
try
{
report.processReport();
/* exit */
System.exit(0);
}
}
Example: Using HTMLDocument to generate both HTML source and XSL FO source:
This example uses the HTMLDocument class to generate HTML and XSL FO source data.
Note: Read the Code example disclaimer for important legal information.
///////////////////////////////////////////////////////////////////////////////
//
// Example: Using the Toolbox HTMLDocument Class
// to generate both HTML and XSL FO source data.
//
// This program uses the HTMLDocument class to
// generate two files: one that has HTML source and
// another than has XSL FO source.
//
// Command syntax:
// HTMLDocumentExample
//
///////////////////////////////////////////////////////////////////////////////
import com.ibm.as400.util.html.*;
import java.*;
import java.io.*;
import java.lang.*;
import java.beans.PropertyVetoException;
// Create an UnorderedList.
UnorderedList uList = new UnorderedList(HTMLConstants.SQUARE);
// Create and set the data for UnorderedListItems.
UnorderedListItem listItem1 = new UnorderedListItem();
UnorderedListItem listItem2 = new UnorderedListItem();
listItem1.setItemData(new HTMLText("First item"));
listItem2.setItemData(new HTMLText("Second item"));
// Add the list items to the UnorderedList.
uList.addListItem(listItem1);
uList.addListItem(listItem2);
// Create an OrderedList.
OrderedList oList = new OrderedList(HTMLConstants.SMALL_ROMAN);
// Create the OrderedListItems.
OrderedListItem olistItem1 = new OrderedListItem();
OrderedListItem olistItem2 = new OrderedListItem();
OrderedListItem olistItem3 = new OrderedListItem();
// Set the data in the OrderedListItems.
olistItem1.setItemData(new HTMLText("First item"));
olistItem2.setItemData(new HTMLText("Second item"));
olistItem3.setItemData(new HTMLText("Third item"));
// Add the list items to the OrderedList.
oList.addListItem(olistItem1);
oList.addListItem(olistItem2);
// Add (nest) the unordered list to OrderedListItem2
oList.addList(uList);
// Add another OrderedListItem to the OrderedList
// after the nested UnorderedList.
oList.addListItem(olistItem3);
table.addColumnHeader(account_header);
// Add rows to the table. Each customer record represents a row in the table.
int numCols = 3;
for (int rowIndex=0; rowIndex< 5; rowIndex++)
{
HTMLTableRow row = new HTMLTableRow();
row.setHorizontalAlignment(HTMLTableRow.CENTER);
row.addColumn(new HTMLTableCell(account));
row.addColumn(new HTMLTableCell(name));
row.addColumn(new HTMLTableCell(balance));
}
}
The constructor for the HTMLForm object takes a URL address. This address is referred to as an action
URL. It is the location of the application on the server that will process the form input. The action URL
can be specified on the constructor or by setting the address using the setURL() method. Form attributes
are set using various set methods and retrieved using various get methods.
Any HTML tag element may be added to an HTMLForm object using addElement() and removed using
removeElement().
Of course, you can add other tag elements to a form, including HTMLText, HTMLHyperlink, and
HTMLTable.
HTMLForm Javadoc
“HTML Text class” on page 218
The IBM Toolbox for Java HTMLText class allows you to access text properties for your HTML page.
Using the HTMLText class, you can get, set, and check the status of many text attributes.
“HTMLHyperlink class” on page 211
The IBM Toolbox for Java HTMLHyperlink class represents an HTML hyperlink tag. You use the
HTMLHyperlink class to create a link within your HTML page.
“HTML Table classes” on page 216
The IBM Toolbox for Java HTMLTable class allows you to easily set up tables that you can use in
HTML pages.
“Example: Using the HTML form classes” on page 597
The following IBM Toolbox for Java example shows you how to use the HTML form classes.
“HTML class example output” on page 607
These are some possible sample outputs you may get from running the HTML class example.
FormInput classes:
The IBM Toolbox for Java FormInput class represents an input element in an HTML form.
The FormInput class is extended by the classes in the following list. These classes provide a way to create
specific types of form input elements and allow you to get and set various attributes or retrieve the
HTML tag for the input element:
v ButtonFormInput: Represents a button element for an HTML form
v FileFormInput: Represents a file input type, for an HTML form
v HiddenFormInput: Represents a hidden input type for an HTML form
v ImageFormInput: Represents an image input type for an HTML form.
v ResetFormInput: Represents a reset button input for an HTML form
ButtonFormInput class:
FileFormInput class:
The IBM Toolbox for Java FileFormInput class represents a file input type in an HTML form.
The following code example shows you how to create a new FileFormInput object
FileFormInput file = new FileFormInput("myFile");
System.out.println(file.getTag());
HiddenFormInput class:
The IBM Toolbox for Java HiddenFormInput class represents a hidden input type in an HTML form.
ImageFormInput class:
You can retrieve and update many of the attributes for the ImageFormInput class by using the methods
provided.
v Get or set the source
v Get or set the alignment
v Get or set the height
v Get or set the width
The following code example shows you how to create an ImageFormInput object:
ImageFormInput image = new ImageFormInput("myPicture", "myPicture.gif");
image.setAlignment(HTMLConstants.TOP);
image.setHeight(81);
image.setWidth(100);
ResetFormInput class:
The ResetFormInput class represents a reset button input type in an HTML form.
The following code example shows you how to create a ResetFormInput object:
ResetFormInput reset = new ResetFormInput();
reset.setValue("Reset");
System.out.println(reset.getTag());
SubmitFormInput class:
The SubmitFormInput class represents a submit button input type in an HTML form.
The following code example shows you how to create a SubmitFormInput object:
SubmitFormInput submit = new SubmitFormInput();
submit.setValue("Send");
System.out.println(submit.getTag());
TextFormInput class:
The TextFormInput class represents a single line text input type in an HTML form. The TextFormInput
class provides methods that let you get and set the maximum number of characters a user can enter in
the text field.
The following example shows you how to create a new TextFormInput object:
TextFormInput text = new TextFormInput("userID");
text.setSize(40);
System.out.println(text.getTag());
PasswordFormInput class:
The PasswordFormInput class represents a password input field type in an HTML form.
The following code example shows you how to create a new PasswordFormInput object:
PasswordFormInput pwd = new PasswordFormInput("password");
pwd.setSize(12);
System.out.println(pwd.getTag());
RadioFormInput class:
The RadioFormInput class represents a radio button input type in an HTML form. The radio button may
be initialized as selected when constructed.
A set of radio buttons with the same control name make a radio button group. The
RadioFormInputGroup class creates radio button groups. Only one radio button within the group may be
selected at any time. Also, a specific button may be initialized as selected when the group is constructed.
The following code example shows you how to create a RadioFormInput object:
RadioFormInput radio = new RadioFormInput("age", "twentysomething", "Age 20 - 29", true);
System.out.println(radio.getTag());
The IBM Toolbox for Java CheckboxFormInput class represents a checkbox input type in an HTML form.
The user may select more than one of the choices presented as checkboxes within a form.
The following example shows you how to create a new CheckboxFormInput object:
CheckboxFormInput checkbox = new CheckboxFormInput("uscitizen", "yes", "textLabel", true);
System.out.println(checkbox.getTag());
LayoutFormPanel class:
The IBM Toolbox for Java LayoutFormPanel class represents a layout of form elements for an HTML
form. You can use the methods provided by the LayoutFormPanel to add and remove elements from a
panel or get the number of elements in the layout.
GridLayoutFormPanel:
The GridLayoutFormPanel class represents a grid layout of form elements. You use this layout for an
HTML form where you specify the number of columns for the grid.
// Create the GridLayoutFormPanel object with two columns and add the form elements.
GridLayoutFormPanel panel = new GridLayoutFormPanel(2);
panel.addElement(sysPrompt);
panel.addElement(system);
panel.addElement(userPrompt);
panel.addElement(user);
panel.addElement(passwordPrompt);
panel.addElement(password);
LineLayoutFormPanel class:
The LineLayoutFormPanel class represents a line layout of form elements for an HTML form. The form
elements are arranged in a single row within a panel.
This example creates a LineLayoutFormPanel object and adds two form elements.
CheckboxFormInput privacyCheckbox =
new CheckboxFormInput("confidential", "yes", "Confidential", true);
CheckboxFormInput mailCheckbox =
new CheckboxFormInput("mailingList", "yes", "Join our mailing list", false);
LineLayoutFormPanel panel = new LineLayoutFormPanel();
panel.addElement(privacyCheckbox);
panel.addElement(mailCheckbox);
String tag = panel.getTag();
TextAreaFormElement class:
The TextAreaFormElement class represents a text area element in an HTML form. You specify the size of
the text area by setting the number of rows and columns. You can determine the size that a text area
element is set for with the getRows() and getColumns() methods.
You set the initial text within the text area with the setText() method. You use the getText() method to see
what the initial text has been set to.
LabelFormElement class:
You use the LabelFormElement class to label elements of an HTML form such as a text area or password
form input. The label is one line of text that you set using the setLabel() method. This text does not
respond to user input and is there to make the form easier for the user to understand.
The following code example shows you how to create a LabelFormElement object:
LabelFormElement label = new LabelFormElement("Account Balance");
System.out.println(label.getTag());
SelectFormElement class:
The SelectFormElement class represents a select input type for an HTML form. You can add and remove
various options within the select element.
SelectFormElement has methods available that allow you to view and change attributes of the select
element:
v Use setMultiple() to set whether or not the user can select more than one option
v Use getOptionCount() to determine how many elements are in the option layout
v Use setSize() to set the number of options visible within the select element and use getSize() to
determine the number of visible options.
The following example creates a SelectFormElement object with three options. The SelectFormElement
object named list, is highlighted. The first two options added specify the option text, name, and select
attributes. The third option added is defined by a SelectOption object.
SelectFormElement list = new SelectFormElement("list1");
SelectOption option1 = list.addOption("Option1", "opt1");
SelectOption option2 = list.addOption("Option2", "opt2", false);
SelectOption option3 = new SelectOption("Option3", "opt3", true);
list.addOption(option3);
System.out.println(list.getTag());
SelectOption class:
The SelectOption class represents an option in an HTML SelectFormElement. You use the option form
element in a select form.
Methods are provided that you can use to retrieve and set attributes within a SelectOption. For instance,
you can set whether the option defaults to being selected. You can also set the input value it will use
when the form is submitted.
The following example creates three SelectOption objects within a select form. Each of the following
SelectOption objects are highlighted. They are named option1, option2 and option3. The option3 object is
initially selected.
SelectFormElement list = new SelectFormElement("list1");
SelectOption option1 = list.addOption("Option1", "opt1");
SelectOption option2 = list.addOption("Option2", "opt2", false);
SelectOption option3 = new SelectOption("Option3", "opt3", true);
list.addOption(option3);
System.out.println(list.getTag());
RadioFormInputGroup class:
The RadioFormInputGroup class represents a group of RadioFormInput objects. A user can select only
one of the RadioFormInput objects from a RadioFormInputGroup.
The RadioFormInputGroup class methods allow you to work with various attributes of a group of radio
buttons. With these methods, you can:
v Add a radio button
v Remove a radio button
v Get or set the name of the radio group
HTMLHead class
The IBM Toolbox for Java HTMLHead class represents an HTML head tag. The head section of an HTML
page features an opening and closing head tag that typically contains other tags. Typically, the head tag
contains a title tag and possibly meta tags.
Constructors for HTMLHead enable you to construct a head tag that is empty, that contains a title tag, or
that contains a title tag and a meta tag. You can easily add title and meta tags to the empty HTMLHead
object.
Methods for the HTMLHead class include setting and getting the page title and the meta tags. Define the
contents of the meta tags by using the HTMLMeta class.
HTMLHyperlink class
The IBM Toolbox for Java HTMLHyperlink class represents an HTML hyperlink tag. You use the
HTMLHyperlink class to create a link within your HTML page.
You can get and set many attributes of hyperlinks with this class, including:
v Get and set the Uniform Resource Identifier for the link
v Get or set the title for the link
v Get or set the target frame for the link
The HTMLHyperlink class can print the full hyperlink with defined properties so that you can use the
output in your HTML page.
The HTMLImage class provides methods that allow you to get and set image attributes, including the
following:
v Get or set the height of the image
v Get or set the width of the image
v Get or set the name of the image
v Get or set the alternate text for the image
v Get or set the horizontal space around the image
v Get or set the vertical space around the image
v Get or set the absolute or relative reference to the image
v Retrieve a string representation of the HTMLImage object
The print statement produces the following tag on a single line. Text wrapping is for display purposes
only.
<img src="http://myWebSite/picture.gif"
alt="Alternate text for this graphic"
height="94" width="105" />
Related information:
HTMLImage Javadoc
HTMLList classes
The IBM Toolbox for Java HTMLList classes allow you to easily create lists within your HTML pages.
These classes provide methods to get and set various attributes of the lists and the items within the lists.
In particular, the parent class HTMLList provides a method to produce a compact list that displays items
in as small a vertical space as possible.
v Methods for HTMLList include:
– Compact the list
– Add and remove items from the list
– Add and remove lists from the list (making it possible to nest lists)
v Methods for HTMLListItem include:
– Get and set the contents of the item
– Get and set the direction of the text interpretation
– Get and set the language of the input element
Use the subclasses of HTMLList and HTMLListItem to create your HTML lists:
v OrderedList and OrderedListItem
v UnorderedList and UnorderedListItem
Use the OrderedList and OrderedListItem classes to create ordered lists in your HTML pages.
v Methods for OrderedList include:
– Get and set the starting number for the first item in the list
– Get and set the type (or style) for the item numbers
v Methods for OrderedListItem include:
– Get and set the number for the item
– Get and set the type (or style) for the item number
By using the methods in OrderedListItem, you can override the numbering and type for a specific item in
the list.
Use the UnorderedList and UnorderedListItem classes to create unordered lists in your HTML pages.
v Methods for UnorderedList include:
– Get and set the type (or style) for the items
v Methods for UnorderedListItem include:
– Get and set the type (or style) for the item
The following examples show you how to use the HTMLList classes to create ordered lists, unordered
lists, and nested lists.
// Create an OrderedList.
OrderedList oList = new OrderedList(HTMLConstants.SMALL_ROMAN);
// Create the OrderedListItems.
OrderedListItem listItem1 = new OrderedListItem();
OrderedListItem listItem2 = new OrderedListItem();
OrderedListItem listItem3 = new OrderedListItem();
// Set the data in the OrderedListItems.
listItem1.setItemData(new HTMLText("First item"));
listItem2.setItemData(new HTMLText("Second item"));
listItem3.setItemData(new HTMLText("Third item"));
// Add the list items to the OrderedList.
oList.addListItem(listItem1);
oList.addListItem(listItem2);
// Add (nest) the unordered list to OrderedListItem2
oList.addList(uList);
// Add another OrderedListItem to the OrderedList
// after the nested UnorderedList.
oList.addListItem(listItem3);
System.out.println(oList.getTag());
HTMLMeta class
The IBM Toolbox for Java HTMLMeta class represents meta-information used within an HTMLHead tag.
Attributes in META tags are used when identifying, indexing, and defining information within the HTML
document.
For example, to help search engines determine the contents of a page, you might use the following META
tag:
<META name="keywords" lang="en-us" content="games, cards, bridge">
You can also use HTMLMeta to redirect a user from one page to another.
HTMLParameter class
The HTMLParameter class represents the parameters you can use with the HTMLServlet class. Each
parameter has its own name and value.
HTMLServlet class
The HTMLServlet class represents a server-side include. The servlet object specifies the name of the
servlet and, optionally, its location. You may also choose to use the default location on the local system.
The HTMLServlet class works with the HTMLParameter class, which specifies the parameters available to
the servlet.
// Create the alternate text if the Web server does not support the servlet tag.
servlet.setText("The Web server providing this page does not support the SERVLET tag.");
System.out.println(servlet);
HTMLTableCell class:
The HTMLTableCell class takes any HTMLTagElement object as input and creates the table cell tag with
the specified element. The element can be set on the constructor or through either of two setElement()
methods.
Many cell attributes can be retrieved or updating using methods that are provided in the HTMLTableCell
class. Some of the actions you can do with these methods are:
v Get or set the row span
v Get or set the cell height
v Set whether the cell data will use normal HTML line breaking conventions
The following example creates an HTMLTableCell object and displays the tag:
//Create an HTMLHyperlink object.
HTMLHyperlink link = new HTMLHyperlink("http://www.ibm.com",
"IBM Home Page");
HTMLTableCell cell = new HTMLTableCell(link);
cell.setHorizontalAlignment(HTMLConstants.CENTER);
System.out.println(cell.getTag());
HTMLTableRow class:
The HTMLTableRow class creates a row within a table. This class provides various methods for getting
and setting attributes of a row.
row.addColumn(new HTMLTableCell(account));
row.addColumn(new HTMLTableCell(name));
row.addColumn(new HTMLTableCell(balance));
// Add the row to an HTMLTable object (assume that the table already exists).
table.addRow(row);
Related information:
HTMLTableRow Javadoc
HTMLTableHeader class:
The HTMLTableHeader class inherits from the HTMLTableCell class. It creates a specific type of cell, the
header cell, giving you a <th> cell instead of a <td> cell. Like the HTMLTableCell class, you call various
methods in order to update or retrieve attributes of the header cell.
// Add the table headers to an HTMLTable object (assume that the table already exists).
table.addColumnHeader(account_header);
table.addColumnHeader(name_header);
table.addColumnHeader(balance_header);
Related information:
HTMLTableHeader Javadoc
HTMLTableCaption class:
The HTMLTableCaption class creates a caption for your HTML table. The class provides methods for
updating and retrieving the attributes of the caption. For example, you can use the setAlignment()
method to specify to which part of the table the caption should be aligned.
// Add the table caption to an HTMLTable object (assume that the table already exists).
table.setCaption(caption);
Related information:
HTMLTableCaption Javadoc
The following example shows you how to create an HTMLText object and set its bold attribute on and its
font size to 5.
HTMLText text = new HTMLText("IBM");
text.setBold(true);
text.setSize(5);
System.out.println(text.getTag());
When you use this tag in an HTML page, it looks like this:
IBM
Related information:
HTMLText Javadoc
HTMLTree classes
The HTMLTree class allows you to easily set up a hierarchical tree of HTML elements that you can use in
HTML pages.
This class provides methods to get and set various attributes of the tree, in addition to methods allowing
you to:
v Get and set the HTTP Servlet Request
v Add an HTMLTreeElement or FileTreeElement to the tree
v Remove an HTMLTreeElement or FileTreeElement from the tree
The following examples show different ways to use the HTMLTree classes.
v “Example: Using HTMLTree classes” on page 608
v “Example: Creating a traversable integrated file system tree”
Related information:
HTMLTree Javadoc
The following example is made of three files that, together, show how you can create a traversable
integrated file system tree. The example uses frames to display an HTMLTree and FileListElement in a
servlet.
v FileTreeExample.java - generates the HTML frames and starts the servlet
v TreeNav.java - builds and manages the tree
v TreeList.java - displays the contents of selections made in the TreeNav.java class
Many tree element attributes can be retrieved or updating using methods that are provided in the
HTMLTreeElement class. Some of the actions you can do with these methods are:
v Get or set the visible text of the tree element
v Get or set the URL for the expanded and collapsed icon
v Set whether the tree element will be expanded
The following example creates an HTMLTreeElement object and displays the tag:
// Create an HTMLTree.
HTMLTree tree = new HTMLTree();
The getTag() method in the above example generates HTML tags like the following:
<table cellpadding="0" cellspacing="3">
<tr>
<td><font color="#0000FF"><u>-</u></font> </td>
<td><font color="#0000FF"><u>My Web Page</u></font></td>
</tr>
<tr>
<td> </td>
<td>
<table cellpadding="0" cellspacing="3">
<tr>
<td><font color="#0000FF"><u>-</u></font> </td>
<td><font color="#0000FF"><u>Another Web Page</u></font> </td>
</tr>
</table>
</td>
</tr>
</table>
Related information:
HTMLTreeElement Javadoc
FileTreeElement class:
The IBM Toolbox for Java FileTreeElement class represents the Integrated File System within an
HTMLTree view.
Many tree element attributes can be retrieved or updating using methods that are provided in the
HTMLTreeElement class. You can also get and set the name and path of NetServer shared drives.
The following example creates a FileTreeElement object and displays the tag:
// Create an HTMLTree.
HTMLTree tree = new HTMLTree();
// Create a FileTreeElement.
FileTreeElement node = new FileTreeElement(dirList[i]);
System.out.println(tree.getTag());
FileListElement class:
The IBM Toolbox for Java FileListElement class allows you to create a file list element, which represents
the contents of an integrated file system directory.
You can use the FileListElement object to represent the contents of a NetServer shared drive by getting
and setting the name and path of NetServer shared drives.
You can use the FileListElement class with other classes in the html package:
v With a FileListRenderer, you can specify how you want to display the list of files
v With the FileTreeElement class, you can create a traversable list of integrated file system files or
NetServer shared files
The following example shows how you can use the FileListElement class with HTMLTree classes
(FileTreeElement and HTMLTreeElement) to create a traversable integrated file system tree. The example
also includes code for setting the path of a NetServer shared drive.
FileListRenderer class:
The IBM Toolbox for Java FileListRenderer class renders any field for File objects (directories and files) in
a FileListElement.
The FileListRenderer class offers methods that allow you to perform the following actions:
v Get the name of the directory
v Get the name of the file
v Get the name of the parent directory
v Return the row data that you want to display in the FileListElement
If you don't want to use the default renderer, you can extend FileListRenderer and override methods or
create new ones. For example, you might want to ensure that you prevent passing the names of specific
directories or files with certain extensions to the FileListElement. By extending the class and overriding
the appropriate method, you can return null for these files and directories, ensuring that they are not
displayed.
To fully customize the rows within a FileListElement, use the getRowData() method. An example of
customizing row data using getRowData() might be adding a column to the row data or rearranging the
columns. When the default behavior of FileListRenderer is satisfactory, you need no additional
programming because the FileListElement class creates a default FileListRenderer.
Related reference:
“FileListElement class” on page 221
The IBM Toolbox for Java FileListElement class allows you to create a file list element, which represents
the contents of an integrated file system directory.
Related information:
ReportWriter classes
The com.ibm.as400.util.reportwriter package provides classes that enable you to easily access and format
data from an XML source file or data produced by servlets or JavaServer Pages.
The reportwriter package is a convenient way to name three different but related packages:
v com.ibm.as400.util.reportwriter.pclwriter
v com.ibm.as400.util.reportwriter.pdfwriter
v com.ibm.as400.util.reportwriter.processor
These packages include a variety of classes that allow you to format XML data streams and generate
reports in those formats. Make sure you have the necessary JAR files in your CLASSPATH, including an
XML parser and an XSLT processor. For more information, see the following pages:
v JAR files
Context classes (in the pclwriter and pdfwriter packages) define methods that the ReportProcessor classes
need to render XML and JSP data in the chosen format:
v Use PCLContext in combination with a ReportWriter class to generate a report in the Hewlett Packard
Printer Control Language (PCL) format.
v Use PDFContext in combination with a ReportWriter class to generate a report in the Adobe Portable
Document Format (PDF).
ReportProcessor classes (in the processor package) enable you to generate formatted reports from
information your application gathers from Java servlets and JavaServer Pages (JSPs).
v Use the JSPReportProcessor class to retrieve data from servlets and JSP pages to produce reports in the
available formats (contexts).
Context classes
The IBM Toolbox for Java context classes support specific data formats, that, in combination with the
OutputQueue and SpooledFileOutputStream classes, enable the ReportWriter classes to generate reports
in that format and put those reports in a spool file.
Your application only has to create an instance of the Context class, which the ReportWriter classes then
use to generate the reports. Your application never directly calls any of the methods in either Context
class. The PCLContext and PDFContext methods are meant to be used internally by the ReportWriter
classes.
Constructing an instance of the Context class requires an OutputStream (from the java.io package) and a
PageFormat (from the java.awt.print package). Example: Using JSPReportProcessor with PDFContext
show how you can construct and use the Context classes with other ReportWriter classes to generate
reports.
OutputQueue Javadoc
SpooledFileOutputStream Javadoc
“ReportWriter classes”
The com.ibm.as400.util.reportwriter package provides classes that enable you to easily access and
format data from an XML source file or data produced by servlets or JavaServer Pages.
“Example: Using XSLReportProcessor with PCLContext” on page 633
This example should not be used as the XSLReportProcessor class is no longer supported.
“Example: Using JSPReportProcessor with PDFContext” on page 629
This example uses the JSPReportProcessor and the PDFContext classes to obtain data from a specified
URL and convert the data to the PDF format. The data is then streamed to a file as a PDF document.
Use this class to obtain a JSP or servlet from a given URL and create a document from the contents. The
JSP or servlet must provide the document data, including XSL formatting objects. You must specify the
output context and the JSP input data source before you can generate any pages of the document. You
can then convert the report data to a specified output data stream format.
The following examples show how you can use the JSPReportProcessor and the PDFContext classes to
generate a report. The examples include both the Java and the JSP code, which you can view by using the
following links. You can also download a ZIP file that contains the example JSP, XML, and XSL source
files for the JSPReportProcessor examples:
v “Example: Using JSPReportProcessor with PDFContext” on page 629
v “Example: JSPReportProcessor sample JSP file” on page 630
Java Server Pages technology
XSLReportProcessor class
The XSLReportProcessor class is no longer supported and should not be used.
The XSLReportProcessor class enables you to create a document or report by transforming and formatting
your XML source data using an XSL stylesheet. Use this class to create the report by using an XSL
stylesheet that contains XSL formatting objects (FOs), which must conform to the XSL specification. You
then use a Context class to convert the report data to a specified output data stream format.
Examples
The following examples show how you can use the XSLReportProcessor and the PCLContext classes to
generate a report. The examples include the Java, XML, and XSL code, which you can view by using the
following links. You can also download a zip file that contains the example XML, XSL, and JSP source
files for both the XSLReportProcessor and JSPReportProcessor examples:
v Example: Using XSLReportProcessor with PCLContext
v Example: XSLReportProcessor sample XML file
v Example: XSLReportProcessor sample XSL file
For more information about XML and XSL, see the XML Toolkit topic in the Information Center.
Resource classes
The Resource package and its classes have been deprecated. You are advised to use the Access package
instead.
Note: The NetServer classes in the access package are also concrete subclasses of Resource.
v ResourceList - an object that represents a list of system resources, such as a list of users, printers, jobs,
messages, or files. Concrete subclasses of resource include:
– RIFSFileList
– RJobList
– RJobLog
– RMessageQueue
– RPrinterList
– RUserList
v Presentation - an object that allows you to present information about resource objects, resource lists,
attributes, selections, and sorts to end users
Resource
Resource is an abstract class that provides generic access to the attributes of any resource. Every attribute
is identified using an attribute ID, and any given subclass of Resource will normally document the
attribute IDs that it supports.
The ChangeableResource abstract class, a subclass of Resource, adds the ability to change attribute values
of a system resource. Attribute changes are cached internally until they are committed or canceled. This
allows you to change many attribute values at once.
Note: The NetServer classes in the access package are also concrete subclasses of Resource and
ChangeableResource.
Examples
The following examples show how you can directly use concrete subclasses of Resource and
ChangeableResource, and also how generic code can work with any Resource or ChangeableResource
subclass.
v Retrieving an attribute value from RUser, a concrete subclass of Resource
v Setting attribute values for RJob, a concrete subclass of ChangeableResource
v Using generic code to access resources
Resource lists
The Resource package and its classes have been deprecated. You are advised to use the Access package
instead.
A resource list is always either open or closed. The resource list must be open in order to access its
contents. In order to provide immediate access to the contents of the list and manage memory efficiently,
most resource lists are loaded incrementally.
You can also filter resource lists by using selection values. Every selection value is identified using a
selection ID. Similarly, resource lists can be sorted using sort values. Every sort value is identified using a
sort ID. Any given subclass of ResourceList will normally document the selection IDs and sort IDs that it
supports.
The following examples show various ways of working with resource lists:
v Example: Getting and printing the contents of a ResourceList
v Example: Using generic code to access a ResourceList
v Example: Presenting a resource list in a servlet (HTML table)
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
Presentation class
The Resource package and its classes have been deprecated. You are advised to use the Access package
instead.
Every resource object, resource list, and meta data object has an associated
com.ibm.as400.resource.Presentation object that provides translated information, such as the name, full
name, and icon.
Example: Printing a resource list and its sort values using their Presentations
You can use the Presentation information to present resource objects, resource lists, attributes, selections,
and sorts to end users in text format.
void printCurrentSort(ResourceList resourceList) throws ResourceException
{
// Get the presentation for the ResourceList and print its full name.
Presentation resourceListPresentation = resourceList.getPresentation();
System.out.println(resourceListPresentation.getFullName());
Security classes
You use the IBM Toolbox for Java security classes to provide secured connections to a server, verify a
user's identity, and associate a user with the operating system thread when running on the local server.
Using SSL negatively affects performance because SSL connections perform more slowly than connections
that do not have encryption. Use SSL connections when the security of the data transferred is a higher
priority than performance, for example, when transferring credit card or bank statement information.
Using encryption between the IBM Toolbox for Java classes and the IBM i servers
Using SSL to encrypt data between IBM Toolbox for Java and IBM i servers:
You can use SSL to encrypt data exchanged between IBM Toolbox for Java classes and IBM i servers.
On the client side, use JSSE to encrypt the data. On the server side, you must use the IBM i digital
certificate manager to configure the IBM i servers to exchange encrypted data.
To encrypt data flowing between the IBM Toolbox for Java classes and IBM i servers, complete the
following tasks:
1. Set up your servers to exchange encrypted data.
2. Use the SecureAS400 object to force IBM Toolbox for Java to encrypt data.
Note: Completing the first two steps above only creates a secure path between the client and the
server. Your application must use the SecureAS400 object to tell the IBM Toolbox for Java which
data to encrypt. Data that flows through the SecureAS400 object is the only data that is
encrypted. If you use an AS400 object, data is not encrypted and the normal path to the server
is used.
To set up your system to use SSL with IBM Toolbox for Java, complete the following steps.
1. Get and configure the server certificate.
2. Apply the certificate to the following systems that are used by IBM Toolbox for Java:
v QIBM_OS400_QZBS_SVR_CENTRAL
v QIBM_OS400_QZBS_SVR_DATABASE
v QIBM_OS400_QZBS_SVR_DTAQ
v QIBM_OS400_QZBS_SVR_NETPRT
v QIBM_OS400_QZBS_SVR_RMTCMD
v QIBM_OS400_QZBS_SVR_SIGNON
v QIBM_OS400_QZBS_SVR_FILE
v QIBM_OS400_QRW_SVR_DDM_DRDA
Before you get and configure your server certificate, you need to install the following products:
The process you follow to get and configure your server certificate depends on the kind of certificate you
use:
v If you get a certificate from a trusted authority (such as VeriSign, Inc., or RSA Data Security, Inc.),
install the certificate on the system then apply it to the host servers.
v If you choose not to use a certificate from a trusted authority, you can build your own certificate to be
used on the system. Build the certificate by using Digital Certificate Manager:
1. Create the certificate authority on the system. See the Information Center topic Acting as your own
CA.
2. Create a system certificate from the certificate authority that you created.
3. Assign which host servers will use the system certificate that you created.
Authentication services
Classes are provided by the IBM Toolbox for Java that interact with the security services provided by
IBM i.
Specifically, support is provided to authenticate a user identity, sometimes referred to as a principal, and
password against the IBM i user registry. A credential representing the authenticated user can then be
established. You can use the credential to alter the identity of the current IBM i thread to perform work
under the authorities and permissions of the authenticated user. In effect, this swap of identity results in
the thread acting as if a signon was performed by the authenticated user.
The AS400 object provides authentication for a given user profile and password against the server. You
can also retrieve Kerberos tickets and profile tokens that represent authenticated user profiles and
passwords for the system.
Note: Using Kerberos tickets requires that you install J2SDK, v1.4 and configure the Java General
Security Services (JGSS) Application Programming Interface. For more information about JGSS, see
the J2SDK, v1.4 Security Documentation .
To use Kerberos tickets, set only the system name (and not the password) into the AS400 object. The user
identity is retrieved through the JGSS framework. You can set only one means of authentication in an
AS400 object at a time. Setting the password clears any Kerberos ticket or profile token.
To use profile tokens, use the getProfileToken() methods to retrieve instances of the
ProfileTokenCredential class. Think of profile tokens as a representation of an authenticated user profile
and password for a specific server. Profile tokens expire based on time, up to one hour, but can be
refreshed in certain cases to provide an extended life span.
Note: If you use the ProfileTokenCredential class, make sure to review the information at the bottom of
this page that discuss the methods for setting tokens.
The following example creates a system object and uses that object to generate a profile token. The
example then uses the profile token to create another system object, and uses the second system object to
connect to the command service:
You can establish a credential on either a remote or local context. Once created, you can serialize or
distribute the credential as required by the calling application. When passed to a running process on the
associated server, a credential can be used to modify or swap the IBM i thread identity and perform work
on behalf of the previously authenticated user.
A practical application of this support might be in a two tier application, with authentication of a user
profile and password being performed by a graphical user interface on the first tier (i.e. a PC) and work
being performed for that user on the second tier (the server). By utilizing ProfileTokenCredentials, the
application can avoid directly passing user IDs and passwords over the network. The profile token can
then be distributed to the program on the second tier, which can perform the swap() and operate under
the IBM i authorities and permissions assigned to the user.
Note: While inherently more secure than passing a user profile and password due to limited life span,
profile tokens should still be considered sensitive information by the application and handled
accordingly. Since the token represents an authenticated user and password, it could potentially be
exploited by a hostile application to perform work on behalf of that user. It is ultimately the
responsibility of the application to ensure that credentials are accessed in a secure manner.
The methods for setting tokens in ProfileTokenCredential class require that you distinguish different ways
to specify passwords:
v As a special value, such as *NOPWD or *NOPWDCHK, by using a defined special value integer
v As the password for the user profile by using a String that represents the password
Note: In V5R3, IBM Toolbox for Java deprecates the setToken methods that do not require you to
distinguish how to specify the password.
Additionally, the setToken methods allow remote users to specify password special values and allow
longer user profile passwords of up to 128 characters.
To specify a password special value integer, such as *NOPWD or *NOPWDCHK, use one of the following
methods:
v setToken(AS400Principal principal, int passwordSpecialValue)
v setToken(String name, int passwordSpecialValue)
The ProfileTokenCredential class includes the following static constants for password special value
integers:
v ProfileTokenCredential.PW_NOPWD: indicates *NOPWD
v ProfileTokenCredential.PW_NOPWDCHK: indicates *NOPWDCHK
To specify a user profile password as a String, use one of the following methods:
v setTokenExtended(AS400Principal principal, String password)
v setTokenExtended(String name, String password)
The setTokenExended methods do not allow you to pass password special value strings as the password
parameter. For example, these methods do not allow a password string of *NOPWD.
Example
Refer to this code for an example of how to use a profile token credential to swap the IBM i thread
identity and perform work on behalf of a specific user.
AS400 Javadoc
ProfileTokenCredential Javadoc
Servlet classes
The servlet classes that are provided with IBM Toolbox for Java work with the access classes, which are
located on the Webserver, to give you access to information located on the server. You decide how to use
the servlet classes to assist you with your own servlet projects.
The following diagram shows how the servlet classes work between the browser, webserver, and IBM i
data. A browser connects to the webserver that is running the servlet. jt400Servlet.jar and jt400.jar files
reside on the webserver because the servlet classes use some of the access classes to retrieve the data and
the HTML classes to present the data. The webserver is connected to the server where the data is.
“Long description of
Figure 1: How servlets work (rzahh585.gif)”
Note: The jt400Servlet.jar file includes both the HTML and Servlet classes. You must update your
CLASSPATH to point to both jt400Servlet.jar and jt400.jar if you want to use classes in the
com.ibm.as400.util.html and com.ibm.as400.util.servlet packages.
For more information about servlets in general, see the reference section.
Description
Note: The Web server does not have to be on an IBM i server, but it can be, and can even be the same
server as that indicated by the System i Data image.
v Lines that connect the images together.
A line labeled HTML connects the Browser (the left image) to a Servlet (the green oval) on the Web server
(middle image). The line is labeled HTML because servlets most often use HTML to 'serve' data to the
browser.
The Web server is running two IBM Toolbox for Java JAR files (the tan circles), jt400Servlet.jar and
jt400.jar. The classes in jt400Servlet.jar, along with the classes in jt400.jar, enable the Web server to run a
servlet that easily connects to servers that contain IBM i data (the right image). The line with arrowheads
on both ends that connects the two images indicates this connection.
Authentication classes
Two classes in the servlet package perform authentication for servlets, AuthenticationServlet and
AS400Servlet.
AuthenticationServlet class
AS400Servlet class
The AS400Servlet class is an abstract subclass of AuthenticationServlet that represents an HTML servlet.
You can use a connection pool to share connections and manage the number of connections to the server
that a servlet user can have.
RowData class
The RowData class is an abstract class that provides a way to describe and access a list of data.
RowData position
There are several methods that allow you to get and set the current position within a list. The following
table lists both the set and get methods for the RowData classes.
Related information:
RowData Javadoc
ListRowData class:
The IBM Toolbox for Java ListRowData class represents a list of data in table form. In the table, each row
contains a finite number of columns determined by the ListMetaData object and each column within a
row contains an individual data item. The data can be a directory in the integrated file system, a list of
jobs, a list of printers, or a variety of other data.
The ListRowData class represents a list of data. ListRowData can represent many types of information,
including the following, through IBM Toolbox for Java access classes:
v A directory in the integrated file system
v A list of jobs
v A list of messages in a message queue
v A list of users
v A list of printers
v A list of spooled files
The following example shows how the ListRowData and HTMLTableConverter classes work. The
example shows the Java code, HTML code, and HTML look and feel.
RecordListRowData class:
The IBM Toolbox for Java RecordListRowData class allows you to do the following:
v Add and remove rows to and from the record list.
v Get and set the row
v Set the record format with the setRecordFormat method
v Get the record format
The RecordListRowData class represents a list of records. A record can be obtained from the server in
different formats, including:
v A record to be written to or read from a server file
v An entry in a data queue
v The parameter data from a program call
v Any data returned that needs to be converted between the server format and Java format
This example shows you how RecordListRowData and HTMLTableConverter work. It shows the java
code, HTML code, and HTML look and feel.
Related information:
RecordListRowData Javadoc
ResourceListRowData class:
The IBM Toolbox for Java ResourceListRowData class represents a resource list of data. Use
ResourceListRowData objects to represent any implementation of the ResourceList interface.
Resource lists are formatted into a series of rows, where each row contains a finite number of columns
determined by the number of column attribute IDs. Each column within a row contains an individual
data item.
The ResourceListRowData class offers methods that enable you to perform the following actions:
v Get and set column attribute IDs
v Get and set the resource list
v Retrieve the number of rows in the list
v Get the column data for the current row
v Get the property list of the data object
v Get the metadata for the list
The following disclaimer applies to all of the IBM Toolbox for Java examples:
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
Related reference:
“Resource lists” on page 226
The Resource package and its classes have been deprecated. You are advised to use the Access package
instead.
Related information:
ResourceListRowData Javadoc
SQLResultSetRowData class:
The SQLResultSetRowData class represents an SQL result set as a list of data. This data is generated by
an SQL statement through JDBC. With methods provided, you can get set the result set metadata.
This example shows you how ListRowData and HTMLTableConverter work. It shows the Java code,
HTML code, and HTML look and feel.
Related reference:
“JDBC classes” on page 60
JDBC is an application programming interface (API) included in the Java platform that enables Java
programs to connect to a wide range of databases.
Related information:
SQLResultSetRowData Javadoc
RowMetaData classes
The RowMetaData class defines an interface that you use to find out information about the columns of a
RowData object.
ListMetaData class:
The IBM Toolbox for Java ListMetaData class lets you get information about and change settings for the
columns in a ListRowData class. It uses the setColumns() method to set the number of columns, clearing
any previous column information. Alternatively, you can also pass the number of columns when you set
the constructor's parameters.
The following example shows how ListMetaData, ListRowData and HTMLTableConverter work. It shows
the Java code, HTML code, and HTML look and feel.
RecordFormatMetaData class:
The RecordFormatMetaData makes use of the IBM Toolbox for Java RecordFormat class. It allows you to
provide the record format when you set the constructor's parameters or use the get set methods to access
the record format.
SQLResultSetMetaData class:
Converter classes
You use the IBM Toolbox for Java converter classes to convert row data into formatted string arrays.
The result is in HTML format and ready for presentation on your HTML page. The following classes take
care of the conversion for you:
StringConverter class:
The StringConverter class is an abstract class that represents a row data string converter. It provides a
convert() method to convert row data. This returns a string array representation of that row's data.
Related information:
StringConverter Javadoc
HTMLFormConverter class:
The IBM Toolbox for Java HTMLFormConverter classes extend StringConverter by providing an
additional convert method called convertToForms(). This method converts row data into an array of
single-row HTML tables. You can use these table tags to display the formatted information on a browser.
You can tailor the appearance of the HTML form by using the various get and set methods to view or
change the attributes of the form. For example, some of the attributes that you can set include:
v Alignment
v Cell spacing
v Header hyper links
v Width
The following example illustrates using HTMLFormConverter. (You can compile and run this example
with a webserver running.)
Using HTMLFormConverter
Related reference:
“StringConverter class”
The StringConverter class is an abstract class that represents a row data string converter. It provides a
convert() method to convert row data. This returns a string array representation of that row's data.
Related information:
HTMLFormConverter Javadoc
HTMLTableConverter class:
The setMaximumTableSize() method allows you to limit the number of rows in a single table. If the row
data does not all fit within the specified size of table, the converter will produce another HTML table
object in the output array. This will continue until all row data has been converted.
Examples
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
HTMLTableConverter Javadoc
Utility classes
The utility classes enable you to do administrative tasks, such as using the AS400JarMaker class.
Because program temporary fixes (PTFs) are applied to this location, Java programs that access these
classes directly on the server automatically receive these updates. But, accessing the classes from the
server does not always work, specifically for the following situations:
v If a low-speed communication link connects server and the client, the performance of loading the
classes from the server may be unacceptable.
v If Java applications use the CLASSPATH environment variable to access the classes on the client file
system, you need IBM i Access for Windows to redirect file system calls to the server. It may not be
possible for IBM i Access for Windows to reside on the client.
Also, the AS400ToolboxJarMaker class can unzip a JAR file for you to gain access to the individual
content files for basic use.
Flexibility of AS400ToolboxJarMaker
All of the AS400ToolboxJarMaker functions are performed with the JarMaker class and the
AS400ToolboxJarMaker subclass:
v The generic JarMaker tool operates on any JAR or Zip file; it splits a JAR file or reduces the size of a
JAR file by removing classes that are not used.
v The AS400ToolboxJarMaker customizes and extends JarMaker functions for easier use with IBM
Toolbox for Java JAR files.
According to your needs, you can invoke the AS400ToolboxJarMaker methods from within your own Java
program or from a command line. Call AS400ToolboxJarMaker from the command line by using the
following syntax:
java utilities.JarMaker [options]
where
v options = one or more of the available options
For a complete set of options available to run at a command line prompt, see the following in the
Javadoc:
v Options for the JarMaker base class
v Extended options for the AS00ToolboxJarMaker subclass
Using AS400ToolboxJarMaker
You can use AS400ToolboxJarMaker to work with JAR files in several ways:
v Uncompress one file bundled within a JAR file
v Split a large JAR file into smaller JAR files
v Exclude any IBM Toolbox for Java files that your application does not need to run
Suppose you wanted to uncompress just one file bundled within a JAR file. AS400ToolboxJarMaker
allows you to expand the file into one of the following:
v Current directory (extract(jarFile))
v Another directory (extract(jarFile, outputDirectory))
For example, with the following code, you are extracting AS400.class and all of its dependent classes from
jt400.jar:
java utilities.AS400ToolboxJarMaker -source jt400.jar
-extract outputDir
-requiredFile com/ibm/as400/access/AS400.class
In the following code, jt400.jar is split into a set of smaller JAR files, none larger than 300KB:
java utilities.AS400ToolboxJarMaker -split 300
With AS400ToolboxJarMaker, you can exclude any IBM Toolbox for Java files not needed by your
application by selecting only the IBM Toolbox for Java components, languages, and CCSIDs that you
need to make your application run. AS400ToolboxJarMaker also provides you with the option of
including or excluding the JavaBean files associated with the components you select.
For example, the following command creates a JAR file that contains only those IBM Toolbox for Java
classes needed to make the CommandCall and ProgramCall components of the IBM Toolbox for Java
work:
java utilities.AS400ToolboxJarMaker -component CommandCall,ProgramCall
Additionally, if it is unnecessary to convert text strings between Unicode and the double byte character
set (DBCS) conversion tables, you can create a 400KB byte smaller JAR file by omitting the unneeded
conversion tables with the -ccsid option:
java utilities.AS400ToolboxJarMaker -component CommandCall,ProgramCall -ccsid 61952
Note: Conversion classes are not included with the program call classes. When including program call
classes, you must also explicitly include the conversion classes used by your program by using the
-ccsid option.
JarMaker Javadoc
AS400ToolboxJarMaker Javadoc
Following table lists the component IDs that you can specify when invoking the AS400ToolboxJarMaker
tool.
v The Component column lists the common name for the component.
v The Keyword column lists the keyword that you should specify when using the -component option tag.
v The Constant column lists the Integer value that you should specify in setComponents() and
getComponents().
IBM Toolbox for Java is shipped with a set of conversion tables, named according to the CCSID.
These tables are used internally by IBM Toolbox for Java classes (such as CharConverter) when
converting data that is transferred to or from an IBM i system. For example, the conversion table for
CCSID 1027 is in file com/ibm/as400/access/ConvTable1027.class. Conversion tables for the following
CCSIDs are included in the IBM Toolbox for Java JAR file; other encodings are supported by using the
JDK. The central server on the server is no longer used to download tables at runtime. Any specified
CCSID for which a conversion table or a JDK encoding cannot be found will cause an exception to be
thrown. Some of these tables may be redundant to tables included in your JDK. IBM Toolbox for Java
presently supports the following 122 different IBM i CCSIDs.
For additional information about CCSIDs, including a complete list of CCSIDs that are recognized on the
IBM i platform, see Globalization.
CommandHelpRetriever class
The CommandHelpRetriever class retrieves help text for IBM i control language (CL) commands and
generates that text either in HTML or User Interface Manager (UIM) format. You can run
CommandHelpRetriever from a command line or embed the functionality into your Java program.
To use CommandHelpRetriever, your server must have an XML parser and XSL processor in the
CLASSPATH environment variable. For more information, see “XML parser and XSLT processor” on page
417.
You can run the CommandHelpRetriever class as a stand-alone command line program. To run
CommandHelpRetriever from a command line, you must pass the following minimum parameters:
v The library on your server that contains the CL command. System commands reside in the QSYS
library.
v The CL command.
You can also pass optional parameters to CommandHelpRetriever that include the server, the user ID,
password, and the location for the generated file.
The following example generates an HTML file called CRTLIB.html in the current directory.
Note: The example command appears on two lines for display purposes only. Type your command on a
single line.
java com.ibm.as400.util.CommandHelpRetriever -library QSYS -command CRTLIB
-system MySystem -userid MyUserID -password MyPassword
You can also use the CommandHelpRetriever class in your Java application to display the help
documentation for specified CL commands. After you create a CommandHelpRetriever object, you can
use the generateHTML and generateUIM methods to generate help documentation in either format.
When you use generateHTML(), you can display the generated HTML in the panel group for the
command or you can specify a different panel group.
The following example creates a CommandHelpRetriever object and generates String objects that
represent the HTML and UIM help documentation for the CRTLIB command.
CommandHelpRetriever helpGenerator = new CommandHelpRetriever();
AS400 system = new AS400("MySystem", "MyUserID", "MyPassword");
Command crtlibCommand = new Command(system, "/QSYS.LIB/CRTLIB.CMD");
String html = helpGenerator.generateHTML(crtlibCommand);
String uim = helpGenerator.generateUIM(crtlibCommand);
Related information:
CommandHelpRetriever Javadoc
CommandPrompter class
The IBM Toolbox for Java CommandPrompter class prompts for the parameter on a given command.
The CommandPrompter class offers functionality that is similar to the CL command prompt (pressing F4)
and the same as the Management Central command prompt.
Using CommandPrompter requires that you have the following JAR files in your CLASSPATH:
v jt400.jar
v jui400.jar
v util400.jar
v jhall.jar
You must also have an XML parser in your CLASSPATH. For more information about using a suitable
XML parser, see the following page:
All of the JAR files, except for jhall.jar, are included in IBM Toolbox for Java. For more information about
IBM Toolbox for Java JAR files, see Jar files. For more information about downloading jhall.jar, see the
Sun JavaHelp Web site .
The CommandPrompter display is a modal dialog that the user must close before returning to the parent
frame. The CommandPrompter handles any errors encountered during prompting. For a programming
example that shows one way to use the CommandPrompter, see the following page:
RunJavaApplication
The RunJavaApplication and VRunJavaApplication classes are utilities to run Java programs on the IBM i
JVM.
Unlike JavaApplicationCall and VJavaApplicationCall classes that you call from your Java program,
RunJavaApplication and VRunJavaApplication are complete programs.
The RunJavaApplication class is a command line utility. It lets you set the environment (CLASSPATH and
properties, for example) for the Java program. You specify the name of the Java program and its
parameters, then you start the program. Once started, you can send input to the Java program which it
receives via standard input. The Java program writes output to standard output and standard error.
The VRunJavaApplication utility has the same capabilities. The difference is VJavaApplicationCall uses a
graphical user interface while JavaApplicationCall is a command line interface.
RunJavaApplication Javadoc
VRunJavaApplication Javadoc
“JavaApplicationCall class” on page 60
The JavaApplicationCall class provides you with the ability to have your client use the server JVM to
run a Java program that resides on the server.
“VJavaApplicationCall class” on page 262
The VJavaApplicationCall class allows you to run a Java application on the server from a client by
using a graphical user interface (GUI).
JPing
The JPing class is a command line utility that allows you to query your servers to see which services are
running and which ports are in service. To query your servers from within a Java application, use the
AS400JPing class.
See the JPing Javadoc for more information about using JPing from within your Java application.
Call JPing from the command line by using the following syntax:
java utilities.JPing System [options]
where:
v System = the system that you want to query
v [options] = one or more of the available options
Options
You can use one or more of the following options. For options that have abbreviations, the abbreviation is
listed in parenthesis.
-help (-h or -?)
Displays the help text.
For example, use the following command to ping the as-dtaq service, including ssl ports, with a timeout
of 5 seconds:
java utilities.JPing myServer -s as-dtaq -ssl -t 5000
Related information:
JPing Javadoc
AS400JPing Javadoc
Vaccess classes
The Vaccess package and its classes have been deprecated. You are advised to use the Access package in
combination with Java Swing instead.
IBM Toolbox for Java provides a set of graphical user interface (GUI) classes in the vaccess package.
These classes use the access classes to retrieve data and to present the data to the user.
Java programs that use the IBM Toolbox for Java vaccess classes require the Swing package, which comes
with the Java 2 Platform, Standard Edition (J2SE). For more information about Swing, see the Sun Java
Foundation Classes Web site.
For more information about the relationships between theIBM Toolbox for Java GUI classes, the Access
classes, and Java Swing, see the Vaccess classes diagram.
Note: AS400 panes are used with other vaccess classes (see items marked above with an asterisk) to
present and allow manipulation of system resources.
When programming with the IBM Toolbox for Java graphical user interface components, use the Error
events classes to report and handle error events to the user.
See Access classes for more information about accessing system data.
Vaccess classes
The Vaccess package and its classes have been deprecated. You are advised to use the Access package in
combination with Java Swing instead.
IBM Toolbox for Java provides graphical user interface (GUI) classes in the vaccess package to retrieve,
display, and in some cases manipulate, server data. These classes use the Java Swing 1.1 framework.
Figure 1 shows the relationship between these classes:
This figure shows the relationship between the classes in the vaccess package, the access package, and the
Java Swing classes.
Description
A Java application (the area delineated by the thick brown border) contains vaccess classes (the tan
polygon) and Java Swing classes (the green polygon). The vaccess classes enable the Java application to
access the following data and functions on the server (small images in the tan polygon):
AS400Panes, CommandCall, DataQueues, integrated file system, JDBC, jobs, messages, print,
ProgramCall, record-level input and output, and users and groups
The Java application uses IBM Toolbox for Java access classes (the light blue bar) to create one or more
socket connections (the dark blue bar). The socket connections enable the Java application to
communicate (the lightning bolt) with the server (bottom image of the IBM i server).
AS400Panes
AS400Panes are components in the vaccess package that present and allow manipulation of one or more
server resources in a GUI. The behavior of each server resource varies depending on the type of resource.
All panes extend the Java Component class. As a result, they can be added to any AWT Frame, Window,
or Container.
Server resources
Server resources are represented in the graphical user interface with an icon and text. Server resources are
defined with hierarchical relationships where a resource might have a parent and zero or more children.
These are predefined relationships and are used to specify what resources are displayed in an AS400Pane.
For example, VJobList is the parent to zero or more VJobs, and this hierarchical relationship is
represented graphically in an AS400Pane.
The IBM Toolbox for Java provides access to the following server resources:
v VIFSDirectory represents a directory in the integrated file system
v VJob and VJobList represent a job or a list of jobs
v VMessageList and VMessageQueue represent a list of messages returned from a CommandCall or
ProgramCall or a message queue
v VPrinter, VPrinters, and VPrinterOutput represent a printer, a list of printers, or a list of spooled files
v VUserList represents a list of users
To specify which server resources are presented in an AS400Pane, set the root using the constructor or
setRoot() method. The root defines the top level object and is used differently based on the pane:
v AS400ListPane presents all of the root's children in its list
v AS400DetailsPane presents all of the root's children in its table
v AS400TreePane uses the root as the root of its tree
v AS400ExplorerPane uses the root as the root of its tree
The following example creates an AS400DetailsPane to present the list of users defined on the system:
// Create the server resource
// representing a list of users.
// Assume that "system" is an AS400
// object created and initialized
// elsewhere.
VUserList userList = new VUserList (system);
When AS400Pane objects and server resource objects are created, they are initialized to a default state.
The relevant information that makes up the contents of the pane is not loaded at creation time.
To load the contents, the application must explicitly call the load() method. In most cases, this initiates
communication to the server to gather the relevant information. Because it can sometimes take a while to
gather this information, the application can control exactly when it happens. For example, you can:
v Load the contents before adding the pane to a frame. The frame does not appear until all information
is loaded.
v Load the contents after adding the pane to a frame and displaying that frame. The frame appears, but
it does not contain much information. A "wait cursor" appears and the information is filled in as it is
loaded.
The following example loads the contents of a details pane before adding it to a frame:
// Load the contents of the details
// pane. Assume that the detailsPane
// was created and initialized
// elsewhere.
detailsPane.load ();
In some cases, the pop-up menu also presents an item that allows the user to view a properties pane. A
properties pane shows various details about the resource and may allow the user to change those details.
The application can control whether actions and properties panes are available by using the
setAllowActions() method on the pane.
Models
The AS400Panes are implemented using the model-view-controller paradigm, in which the data and the
user interface are separated into different classes. The AS400Panes integrate IBM Toolbox for Java models
with Java GUI components. The models manage server resources and the vaccess components display
them graphically and handle user interaction.
The AS400Panes provide enough functionality for most requirements. However, if an application needs
more control of the JFC component, then the application can access a server model directly and provide
customized integration with a different vaccess component.
Examples
v Present a list of users on the system using an AS400ListPane with a VUserList object. Figure 1 shows
the finished product:
Figure 1: Using AS400ListPane with a VUserList object
v Present the list of messages generated by a command call using an AS400DetailsPane with a
VMessageList object. Figure 2 shows the finished product:
v Present an integrated file system directory hierarchy using an AS400TreePane with a VIFSDirectory
object. Figure 3 shows the finished product:
Figure 3: Using AS400TreePane with a VIFSDirectory object
v Present print resources using an AS400ExplorerPane with a VPrinters object. Figure 4 shows the
finished product:
Figure 4: Using AS400ExplorerPane with a VPrinters object
AS400DetailsPane Javadoc
AS400ExplorerPane Javadoc
AS400JDBCDataSourcePane Javadoc
AS400ListPane Javadoc
AS400TreePane Javadoc
VNode Javadoc
A CommandCallButton object represents a button that calls a server command when pressed. The
CommandCallButton class extends the Java Foundation Classes (JFC) JButton class so that all buttons
have a consistent appearance and behavior.
Similarly, a CommandCallMenuItem object represents a menu item that calls a server command when
selected. The CommandCallMenuItem class extends the JFC JMenuItem class so that all menu items also
have a consistent appearance and behavior.
To use a command call graphical user interface component, set both the system and command properties.
These properties can be set using a constructor or through the setSystem() and setCommand() methods.
The following example creates a CommandCallButton. At run time, when the button is pressed, it creates
a library called "FRED":
// Create the CommandCallButton
// object. Assume that "system" is
// an AS400 object created and
// initialized elsewhere. The button
// text says "Press Me", and there is
// no icon.
CommandCallButton button = new CommandCallButton ("Press Me", null, system);
When a server command runs, it may return zero or more server messages. To detect when the server
command runs, add an ActionCompletedListener to the button or menu item using the
addActionCompletedListener() method. When the command runs, it fires an ActionCompletedEvent to all
such listeners. A listener can use the getMessageList() method to retrieve any server messages that the
command generated.
This example adds an ActionCompletedListener that processes all server messages that the command
generated:
// Add an ActionCompletedListener that
// is implemented using an anonymous
// inner class. This is a convenient
// way to specify simple event
// listeners.
button.addActionCompletedListener (new ActionCompletedListener ()
{
public void actionCompleted (ActionCompletedEvent event)
{
// Cast the source of the event to a
// CommandCallButton.
CommandCallButton sourceButton = (CommandCallButton) event.getSource ();
Data queues
The data queue graphical components allow a Java program to use any Java Foundation Classes (JFC)
graphical text component to read or write to a server data queue.
Data queue documents associate the contents of a text component with a server data queue. (A text
component is a graphical component used to display text that the user can optionally edit.) The Java
program can read and write between the text component and data queue at any time. Use
DataQueueDocument for sequential data queues and KeyedDataQueueDocument for keyed data queues.
To use a DataQueueDocument, set both the system and path properties. These properties can be set using
a constructor or through the setSystem() and setPath() methods. The DataQueueDocument object is then
"plugged" into the text component, usually using the text component's constructor or setDocument()
method. KeyedDataQueueDocuments work the same way.
The following example creates a DataQueueDocument whose contents are associated with a data queue:
// Create the DataQueueDocument
// object. Assume that "system" is
// an AS400 object created and
// initialized elsewhere.
DataQueueDocument dqDocument = new DataQueueDocument (system, "/QSYS.LIB/MYLIB.LIB/MYQUEUE.DTAQ");
Initially, the contents of the text component are empty. Use read() or peek() to fill the contents with the
next entry on the queue. Use write() to write the contents of the text component to the data queue. Note
that these documents only work with String data queue entries.
Examples
Figure 1 shows the DataQueueDocument graphical user interface component being used in a JTextField.
A button has been added to provide a GUI interface for the user to write the contents of the test field to
the data queue.
Related information:
DataQueueDocument Javadoc
KeyedDataQueueDocument Javadoc
Error events
In most cases, the IBM Toolbox for Java GUI components fire error events instead of throw exceptions.
You can provide an error listener that handles all error events that are fired by a particular graphical user
interface component. Whenever an exception is thrown, the listener is called, and it can provide
appropriate error reporting. By default, no action takes place when error events are fired.
The IBM Toolbox for Java provides a graphical user interface component called ErrorDialogAdapter,
which automatically displays a dialog to the user whenever an error event is fired.
Examples
The following examples show how you can handle errors and define a simple error listener.
The following example shows how you can handle error events by displaying a dialog:
// All the setup work to lay out a graphical user interface component
// is done. Now add an ErrorDialogAdapter as a listener to the component.
// This will report all error events fired by that component through
You can write a custom error listener to handle errors in a different way. Use the ErrorListener interface
to accomplish this.
The following example shows how to define an simple error listener that only prints errors to System.out:
class MyErrorHandler
implements ErrorListener
{
// This method is invoked whenever an error event is fired.
public void errorOccurred(ErrorEvent event)
{
Exception e = event.getException ();
System.out.println ("Error: " + e.getMessage ());
}
}
The following example shows how to handle error events for a graphical user interface component using
this customized handler:
MyErrorHandler errorHandler = new MyErrorHandler ();
component.addErrorListener (errorHandler);
Related reference:
“Vaccess classes” on page 248
The Vaccess package and its classes have been deprecated. You are advised to use the Access package in
combination with Java Swing instead.
“Exceptions” on page 47
The IBM Toolbox for Java access classes throw exceptions when device errors, physical limitations,
programming errors, or user input errors occur. The exception classes are based upon the type of error
that occurs instead of the location where the error originates.
Related information:
ErrorDialogAdapter Javadoc
To use the integrated file system graphical user interface components, set both the system and the path or
directory properties. These properties can be set using a constructor or through the setDirectory() (for
IFSFileDialog) or setSystem() and setPath() methods (for VIFSDirectory and IFSTextFileDocument).
Set the path to something other than "/QSYS.LIB" because this directory is typically large, and
downloading its contents can take a long time.
IFSFileSystemView:
JFileChooser is a standard Java way to build dialogs for navigating and choosing files, and is the
recommended replacement for IFSFileDialog.
File dialogs:
The IFSFileDialog class is a dialog that allows the user to traverse the directories of the integrated file
system on the server and select a file. The caller can set the text on the buttons on the dialog. In addition,
the caller can use FileFilter objects, which allow the user to limit the choices to certain files.
If the user selects a file in the dialog, use the getFileName() method to get the name of the selected file.
Use the getAbsolutePath() method to get the full path name of the selected file.
The following example sets up an integrated file system file dialog with two file filters:
// Create a IFSFileDialog object
// setting the text of the title bar.
// Assume that "system" is an AS400
// object and "frame" is a JFrame
// created and initialized elsewhere.
IFSFileDialog dialog = new IFSFileDialog (frame, "Select a file", system);
Example
IFSFileDialog Javadoc
FileFilter Javadoc
Directories in AS400Panes:
AS400Panes are GUI components that present and allow manipulation of one or more server resources. A
VIFSDirectory object is a resource that represents a directory in the integrated file system for use in
AS400Panes. AS400Pane and VIFSDirectory objects can be used together to present many views of the
integrated file system, and to allow the user to navigate, manipulate, and select directories and files.
To use a VIFSDirectory, set both the system and path properties. You set these properties using a
constructor or through the setSystem() and setPath() methods. You then plug the VIFSDirectory object
into the AS400Pane as the root, using the constructor or setRoot() method of the AS400Pane.
VIFSDirectory has some other useful properties for defining the set of directories and files that are
presented in AS400Panes. Use setInclude() to specify whether directories, files, or both appear. Use
setPattern() to set a filter on the items that are shown by specifying a pattern that the file name must
match. You can use wildcard characters, such as "*" and "?", in the patterns. Similarly, use setFilter() to set
a filter with an IFSFileFilter object.
At run-time, a user can perform actions on any directory or file by right-clicking it to display the context
menu. The directory context menu can include the following items:
v Create file - creates a file in the directory. This will give the file a default name
v Create directory - creates a subdirectory with a default name
v Rename - renames a directory
v Delete - deletes a directory
v Properties - displays properties such as the location, number of files and subdirectories, and
modification date
Users can only read or write directories and files to which they are authorized. In addition, the caller can
prevent the user from performing actions by using the setAllowActions() method on the pane.
Example
Present an integrated file system directory hierarchy using an AS400TreePane with a VIFSDirectory object.
IFSTextFileDocument:
Text file documents allow a Java program to use any Java Foundation Classes (JFC) graphical text
component to edit or view text files in the integrated file system on a server. (A text component is a
graphical component used to display text that the user can optionally edit.)
The IFSTextFileDocument class is an implementation of the JFC Document interface. It can be used
directly with any JFC graphical text component. Several text components, such as single line fields
(JTextField) and multiple line text areas (JTextArea), are available in JFC.
Text file documents associate the contents of a text component with a text file. The Java program can load
and save between the text component and the text file at any time.
To use an IFSTextFileDocument, set both the system and path properties. These properties can be set
using a constructor or through the setSystem() and setPath() methods. The IFSTextFileDocument object is
then "plugged" into the text component, typically using the text component's constructor or
setDocument() method.
Initially, the contents of the text component are empty. Use load() to load the contents from the text file.
Use save() to save the contents of the text component to the text file.
Example
IFSTextFileDocument Javadoc
VJavaApplicationCall class
The VJavaApplicationCall class allows you to run a Java application on the server from a client by using
a graphical user interface (GUI).
The GUI is a panel with two sections. The top section is an output window that displays output that the
Java program writes to standard output and standard error. The bottom section is an input field where
the user enters the Java environment, the Java program to run with parameters and input the Java
program receives via standard input. Refer to the Java command options for more information.
For example, this code might create the following GUI for your Java program.
VJavaApplicationCall is a class that you call from your Java program. However, the IBM Toolbox for Java
also provides a utility that is a complete Java application that can be used to call your Java program from
a workstation. Refer to the RunJavaApplication class for more information.
Related information:
VJavaApplicationCall Javadoc
JDBC classes
The JDBC graphical user interface components allow a Java program to present various views and
controls for accessing a database using SQL (Structured Query Language) statements and queries.
All JDBC graphical user interface components communicate with the database using a JDBC driver. The
JDBC driver must be registered with the JDBC driver manager in order for any of these components to
work. The following example registers the IBM Toolbox for Java JDBC driver:
// Register the JDBC driver.
DriverManager.registerDriver (new com.ibm.as400.access.AS400JDBCDriver ());
SQL connections
An SQLConnection object represents a connection to a database using JDBC. The SQLConnection object
is used with all of the JDBC graphical user interface components.
To use an SQLConnection, set the URL property using the constructor or setURL(). This identifies the
database to which the connection is made. Other optional properties can be set:
v Use setProperties() to specify a set of JDBC connection properties.
v Use setUserName() to specify the user name for the connection.
v Use setPassword() to specify the password for the connection.
The actual connection to the database is not made when the SQLConnection object is created. Instead, it
is made when getConnection() is called. This method is normally called automatically by the JDBC
graphical user interface components, but it can be called at any time in order to control when the
connection is made.
An SQLConnection object can be used for more than one JDBC graphical user interface component. All
such components will use the same connection, which can improve performance and resource usage.
Alternately, each JDBC graphical user interface component can use a different SQL object. It is sometimes
necessary to use separate connections, so that SQL statements are issued in different transactions.
When the connection is no longer needed, close the SQLConnection object using close(). This frees up
JDBC resources on both the client and server.
SQLConnection Javadoc
An SQLStatementButton object represents a button that issues an SQL (Structured Query Language)
statement when pressed. The SQLStatementButton class extends the Java Foundation Classes (JFC)
JButton class so that all buttons have a consistent appearance and behavior.
To use either of these classes, set both the connection and the SQLStatement properties. These properties
can be set using a constructor or the setConnection() and setSQLStatement() methods.
The following example creates an SQLStatementButton. When the button is pressed at run time, it deletes
all records in a table:
// Create an SQLStatementButton object.
// The button text says "Delete All",
// and there is no icon.
SQLStatementButton button = new SQLStatementButton ("Delete All");
SQLStatementDocument class:
The SQLStatementDocument class is an implementation of the Java Foundation Classes (JFC) Document
interface. It can be used directly with any JFC graphical text component.
Several text components, such as single line fields (JTextField) and multiple line text areas (JTextArea), are
available in JFC. SQLStatementDocument objects associate the contents of text components with
SQLConnection objects. The Java program can run the SQL statement contained in the document contents
at any time and then process the results, if any.
To use an SQLStatementDocument, you must set the connection property. Set this property by using the
constructor or the setConnection() method. The SQLStatementDocument object is then "plugged" into the
text component, typically using the text component's constructor or setDocument() method. Use the
execute() method at any time to run the SQL statement contained in the document.
SQLResultSetFormPane class:
An SQLResultSetFormPane presents the results of an SQL (Structured Query Language) query in a form.
The form displays one record at a time and provides buttons that allow the user to scroll forward,
backward, to the first or last record, or refresh the view of the results.
To use an SQLResultSetFormPane, set the connection and query properties. Set these properties by using
the constructor or the setConnection() and setQuery() methods. Use load() to execute the query and
present the first record in the result set. When the results are no longer needed, call close() to ensure that
the result set is closed.
SQLResultSetTablePane class:
An SQLResultSetTablePane presents the results of an SQL (Structured Query Language) query in a table.
Each row in the table displays a record from the result set and each column displays a field.
To use an SQLResultSetTablePane, set the connection and query properties. Set properties by using the
constructor or the setConnection() and setQuery() methods. Use load() to execute the query and present
the results in the table. When the results are no longer needed, call close() to ensure that the result set is
closed.
Example
Present an SQLResultSetTablePane that displays the contents of a table. This example uses an
SQLStatementDocument (denoted in the following image by the text, "Enter a SQL statement here") that
allows the user to type in any SQL statement, and an SQLStatementButton (denoted by the text, "Delete
all rows") that allows the user to delete all rows from the table.
Related information:
SQLResultSetTablePane Javadoc
SQLResultSetTableModel class:
SQLResultSetTablePane is implemented using the model-view-controller paradigm, in which the data and
the user interface are separated into different classes. The implementation integrates
SQLResultSetTableModel with the Java Foundation Classes' (JFC) JTable. The SQLResultSetTableModel
class manages the results of the query and JTable displays the results graphically and handles user
interaction.
SQLResultSetTablePane provides enough functionality for most requirements. However, if a caller needs
more control of the JFC component, then the caller can use SQLResultSetTableModel directly and provide
customized integration with a different graphical user interface component.
To use an SQLResultSetTableModel, set theconnection and query properties. Set these properties by using
the constructor or the setConnection() and setQuery() methods. Use load() to execute the query and load
the results. When the results are no longer needed, call close() to ensure that the result set is closed.
The following example creates an SQLResultSetTableModel object and presents it with a JTable:
// Create an SQLResultSetTableModel
// object. Assume that "connection"
// is an SQLConnection object that is
// created and initialized elsewhere.
SQLResultSetTableModel tableModel = new SQLResultSetTableModel (connection,
To use an SQLQueryPane, set the connection property. This property can be set using the constructor or
the setConnection() method. Use load() to load data needed for the query builder graphical user interface.
Use getQuery() to get the SQL query that the user has built.
Example
Present an SQLQueryBuilderPane and a button. When the button is clicked, present the results of the
query in an SQLResultSetFormPane in another frame.
Jobs
The jobs vaccess (GUI) components allow a Java program to present lists of server jobs and job log
messages in a GUI.
You can use AS400Panes, VJobList objects, and VJob objects together to present many views of a job list
or job log.
To use a VJobList, set the system, name, number, and user properties. Set these properties by using a
constructor or through the setSystem(), setName(), setNumber(), and setUser() properties.
To use a VJob, set the system property. Set this property by using a constructor or through the
setSystem() method.
VJobList has some other useful properties for defining the set of jobs that are presented in AS400Panes.
Use setName() to specify that only jobs with a certain name appear. Use setNumber() to specify that only
jobs with a certain number appear. Similarly, use setUser() to specify that only jobs for a certain user
appear.
When AS400Pane, VJobList, and VJob objects are created, they are initialized to a default state. The list of
jobs or job log messages are not loaded at creation time. To load the contents, the caller must explicitly
call the load() method on either object. This will initiate communication to the server to gather the
contents of the list.
At run-time, right-click a job, job list, or job log message to display the shortcut menu. Select Properties
from the shortcut menu to perform actions on the selected object:
v Job - Work with properties, such as the type and status. You can also change the value of some of the
properties.
v Job list - Work with the properties, such as name, number, and user properties. You can also change the
contents of the list.
v Job log message - Display properties, such as the full text, severity, and time sent.
Users can only access jobs to which they are authorized. In addition, the Java program can prevent the
user from performing actions by using the setAllowActions() method on the pane.
Examples
This VJobList example presents an AS400ExplorerPane filled with a list of jobs. The list shows jobs on the
system that have the same job name.
The following image shows the VJobList graphical user interface component:
AS400Panes are graphical user interface components that present and allow manipulation of one or more
server resources. VMessageList and VMessageQueue objects are resources that represent lists of server
messages in AS400Panes.
You can use AS400Pane, VMessageList, and VMessageQueue objects together to present many views of a
message list and to allow the user to select and perform operations on messages.
VMessageList class:
A VMessageList object is a resource that represents a list of messages for use in AS400Panes. This is for
message lists generated by command or program calls.
When AS400Pane and VMessageList objects are created, they are initialized to a default state. The list of
messages is not loaded at creation time. To load the contents, the caller must explicitly call the load()
method on either object.
At run-time, a user can perform actions on a message by right-clicking it to display the context menu.
The message context menu can include an item called Properties that displays properties such as the
severity, type, and date.
The caller can prevent the user from performing actions by using the setAllowActions() method on the
pane.
The following example creates a VMessageList for the messages generated by a command call and
presents it in an AS400DetailsPane:
// Create the VMessageList object.
// Assume that "command" is a
// CommandCall object created and run
// elsewhere.
VMessageList root = new VMessageList (command.getMessageList ());
Example
Present the list of messages generated by a command call using an AS400DetailsPane with a
VMessageList object. Figure 1 shows the VMessageList graphical user interface component:
Related reference:
“AS400Panes” on page 250
AS400Panes are components in the vaccess package that present and allow manipulation of one or more
server resources in a GUI. The behavior of each server resource varies depending on the type of resource.
Related information:
VMessageList Javadoc
A VMessageQueue object is a resource that represents the messages in a server message queue for use in
AS400Panes.
To use a VMessageQueue, set the system and path properties. These properties can be set using a
constructor or through the setSystem() and setPath() methods. The VMessageQueue object is then
"plugged" into the AS400Pane as the root by using the constructor or setRoot() method of the AS400Pane.
VMessageQueue has some other useful properties for defining the set of messages that are presented in
AS400Panes. Use setSeverity() to specify the severity of messages that appear. Use setSelection() to specify
the type of messages that appear.
When AS400Pane and VMessageQueue objects are created, they are initialized to a default state. The list
of messages is not loaded at creation time. To load the contents, the caller must explicitly call the load()
method on either object. This will initiate communication to the server to gather the contents of the list.
At run-time, a user can perform actions on a message or message queue by right-clicking it to display the
context menu. The context menu for message queues can include the following items:
v Clear - clears the message queue
v Properties - allows the user to set the severity and selection properties. This may be used to change the
contents of the list
Of course, users can only access message queues to which they are authorized. In addition, the caller can
prevent the user from performing actions by using the setAllowActions() method on the pane.
Example
Present the list of messages in a message queue using an AS400ExplorerPane with a VMessageQueue
object. Figure 1 shows the VMessageQueue graphical user interface component:
Permission classes
The Permission classes information can be used in a graphical user interface (GUI) through the VIFSFile
and VIFSDirectory classes. Permission has been added as an action in each of these classes.
The following example shows how to use Permission with the VIFSDirectory class:
// Create AS400 object
AS400 as400 = new AS400();
AS400Panes are GUI components that present and allow manipulation of one or more server resources.
VPrinters, VPrinter, and VPrinterOutput objects are resources that represent lists of server print resources
in AS400Panes.
You can use AS400Pane, VPrinters, VPrinter, and VPrinterOutput objects together to present many views
of print resources and to allow the user to select and perform operations on them.
VPrinters class:
A VPrinters object is a resource that represents a list of printers for use in AS400Panes.
To use a VPrinters object, set the system property. Set this property by using a constructor or through the
setSystem() method. The VPrinters object is then "plugged" into the AS400Pane as the root, using the
pane's constructor or setRoot() method.
A VPrinters object has another useful property for defining the set of printers that is presented in
AS400Panes. Use setPrinterFilter() to specify a filter that defines which printers should appear.
At run-time, a user can perform actions on any printer list or printer by right-clicking it to display the
context menu. The printer list context menu can include an item called Properties that allows the user to
set the printer filter property, which can change the contents of the list.
Users can only access printers to which they are authorized. In addition, the caller can prevent the user
from performing actions by using the setAllowActions() method on the pane.
Example
Present print resources using an AS400ExplorerPane with a VPrinters object. Figure 1 shows the VPrinters
graphical user interface component:
Related information:
VPrinters Javadoc
A VPrinter object is a resource that represents a server printer and its spooled files for use in AS400Panes.
To use a VPrinter, set the printer property. Set this property by using a constructor or through the
setPrinter() method. The VPrinter object is then "plugged" into the AS400Pane as the root, using the
pane's constructor or setRoot() method.
When AS400Pane and VPrinter objects are created, they are initialized to a default state. The printer's
attributes and list of spooled files are not loaded at creation time.
To load the contents, the caller must explicitly call the load() method on either object. This will initiate
communication to the server to gather the contents of the list.
At run-time, a user can perform actions on any printer or spooled file by right-clicking it to display the
context menu. The context menu for message queues can include the following items:
v Hold - holds the printer
v Release - releases the printer
v Start - starts the printer
v Stop - stops the printer
v Make available - makes the printer available
v Make unavailable - makes the printer unavailable
v Properties - displays properties of the printer and allows the user to set filters
The context menu for spooled files listed for a printer can include the following items:
v Reply - replies to the spooled file
v Hold - holds the spooled file
v Release - releases the spooled file
v Print next - prints the next spooled file
v Send - sends the spooled file
v Move - moves the spooled file
v Delete - deletes the spooled file
v Properties - displays many properties of the spooled file and allows the user to change some of them
Users can only access printers and spooled files to which they are authorized. In addition, the caller can
prevent the user from performing actions by using the setAllowActions() method on the pane.
Present print resources using an AS400ExplorerPane with a VPrinter object. Figure 1 shows the VPrinter
graphical user interface component:
Related information:
VPrinter Javadoc
VPrinterOutput class:
A VPrinterOutput object is a resource that represents a list of spooled files on a server for use in
AS400Panes.
To use a VPrinterOutput object, set the system property. This property can be set using a constructor or
through the setSystem() method. The VPrinterOutput object is then "plugged" into the AS400Pane as the
root, using the constructor or setRoot() method of the AS400Pane.
A VPrinterOutput object has other useful properties for defining the set of spooled files that is presented
in AS400Panes. Use setFormTypeFilter() to specify which types of forms should appear. Use
setUserDataFilter() to specify which user data should appear. Finally, use setUserFilter() to specify which
users spooled files should appear.
When AS400Pane and VPrinterOutput objects are created, they are initialized to a default state. The list of
spooled files is not loaded at creation time. To load the contents, the caller must explicitly call the load()
method on either object. This will initiate communication to the server to gather the contents of the list.
At run-time, a user can perform actions on any spooled file or spooled file list by right-clicking it to
display the context menu. The spooled file list context menu can include an item called Properties that
allows the user to set the filter properties, which can change the contents of the list.
The spooled file context menu can include the following items:
v Reply - replies to the spooled file
v Hold - holds the spooled file
v Release - releases the spooled file
v Print next - prints the next spooled file
v Send - sends the spooled file
v Move - moves the spooled file
v Delete - deletes the spooled file
v Properties - displays many properties of the spooled file and allows the user to change some of them
Example
Present a list of spooled files by using the print resource, VPrinterOutput object. Figure 1 shows the
VPrinterOutput graphical user interface component:
Related information:
VPrinterOutput Javadoc
SpooledFileViewer class:
The IBM Toolbox for Java SpooledFileViewer class creates a window for viewing Advanced Function
Printing (AFP) and Systems Network Architecture character string (SCS) files that have been spooled for
printing.
The class essentially adds a "print preview" function to your spooled files, common to most word
processing programs, as illustrated in Figure 1.
The spooled file viewer is especially helpful when viewing the accuracy of the layout of the files is more
important than printing the files, or when viewing the data is more economical than printing, or when a
printer is not available.
Three constructor methods are available to create an instance of the SpooledFileViewer class. The
SpooledFileViewer() constructor can be used to create a viewer without a spooled file associated with it.
If this constructor is used, a spooled file will need to be set later using setSpooledFile(SpooledFile). The
SpooledFileViewer(SpooledFile) constructor can be used to create a viewer for the given spooled file, with
page one as the initial view. Finally, the SpooledFileViewer(spooledFile, int) constructor can be used to
create a viewer for the given spooled file with the specified page as the initial view. No matter which
constructor is used, once a viewer is created, a call to load() must be performed in order to actually
retrieve the spooled file data.
Then, your program can traverse the individual pages of the spooled file by using the following methods:
v load FlashPage()
v load Page()
v pageBack()
v pageForward()
If, however, you need to examine particular sections of the document more closely, you can magnify or
reduce the image of a page of the document by altering the ratio proportions of each page with the
following:
v fitHeight()
v fitPage()
v fitWidth()
v actualSize()
Your program concludes with calling the close() method that closes the input stream and releases any
resource associations with the stream.
Note: You can either select a button on the image in Figure 1 for an explanation of its function, or (if
your browser is not JavaScript enabled) see the toolbar description.
// Assume splf is the spooled file.
// Create the spooled file viewer
SpooledFileViewer splfv = new SpooledFileViewer(splf, 1);
splfv.load();
// Add the spooled file viewer to a frame
JFrame frame = new JFrame("My Window");
frame.getContentPane().add(splfv);
frame.pack();
frame.show();
Figure 1: SpooledFileViewer
The actual size button returns the spooled file page image to its original size by using the
actualSize() method.
The fit width button stretches the spooled file page image to the left and right edges of the
viewer's frame by using the fitWidth() method.
The fit page button stretches the spooled file page image vertically and horizontally to fit within
the spooled file viewer's frame by using the fitPage() method.
The zoom button allows you to increase or decrease the size of the spooled file page image by
selecting one of the preset percentages or entering your own percent in a text field that appears in a
dialog box after selecting the zoom button.
The go to page button allows you to go to a specific page within the spooled file when selected.
The first page button takes you to the first page of the spooled file when selected and indicates
that you are on the first page when deactivated.
The next page button advances you to the page immediately after the page you are viewing
when selected.
The last page button advances you to the last page of the spooled file when selected and indicates
that you are on the last page when deactivated.
The load flash page button loads the previously viewed page by using the loadFlashPage()
method when selected.
The set paper size button allows you to set the paper size when selected.
The set viewing fidelity button allows you to set the viewing fidelity when selected.
SpooledFileViewer Javadoc
A ProgramCallButton object represents a button that calls an server program when pressed. The
ProgramCallButton class extends the Java Foundation Classes (JFC) JButton class so that all buttons have
a consistent appearance and behavior.
Similarly, a ProgramCallMenuItem object represents a menu item that calls an server program when
selected. The ProgramCallMenuItem class extends the JFC JMenuItem class so that all menu items also
have a consistent appearance and behavior.
To use a vaccess program call component, set both the system and program properties. Set these
properties by using a constructor or through the setSystem() and setProgram() methods.
The following example creates a ProgramCallMenuItem. At run time, when the menu item is selected, it
calls a program:
// Create the ProgramCallMenuItem
// object. Assume that "system" is
// an AS400 object created and
// initialized elsewhere. The menu
// item text says "Select Me", and
// there is no icon.
ProgramCallMenuItem menuItem = new ProgramCallMenuItem ("Select Me", null, system);
When a server program runs, it may return zero or more server messages. To detect when the server
program runs, add an ActionCompletedListener to the button or menu item using the
addActionCompletedListener() method. When the program runs, it fires an ActionCompletedEvent to all
such listeners. A listener can use the getMessageList() method to retrieve any server messages that the
program generated.
This example adds an ActionCompletedListener that processes all server messages that the program
generated:
// Add an ActionCompletedListener
// that is implemented by using an
// anonymous inner class. This is a
// convenient way to specify simple
// event listeners.
menuItem.addActionCompletedListener (new ActionCompletedListener ()
{
public void actionCompleted (ActionCompletedEvent event)
{
// Cast the source of the event to a
// ProgramCallMenuItem.
ProgramCallMenuItem sourceMenuItem = (ProgramCallMenuItem) event.getSource ();
Parameters
ProgramParameter objects are used to pass parameter data between the Java program and the server
program. Input data is set with the setInputData() method. After the program is run, output data is
retrieved with the getOutputData() method.
Each parameter is a byte array. It is up to the Java program to convert the byte array between Java and
server formats. The data conversion classes provide methods for converting data.
You can add parameters to a program call graphical user interface component one at a time using the
addParameter() method or all at once using the setParameterList() method.
For more information about using ProgramParameter objects, see the ProgramCall access class.
Examples
ProgramParameter Javadoc
ProgramCallButton Javadoc
ProgramCallMenuItem Javadoc
ActionCompletedListener Javadoc
ActionCompletedEvent Javadoc
Keyed access
You can use the record-level access graphical user interface components with keyed access to a server file.
Keyed access means that the Java program can access the records of a file by specifying a key.
Keyed access works the same for each record-level access graphical user interface component. Use
setKeyed() to specify keyed access instead of sequential access. Specify a key using the constructor or the
setKey() method. See Specifying the key for more information about how to specify the key.
The following example creates a RecordListTablePane object to display all records less than or equal to a
key.
// Create a key that contains a
// single element, the Integer 5.
Object[] key = new Object[1];
key[0] = new Integer (5);
// Create a RecordListTablePane
// object. Assume that "system" is an
// AS400 object that is created and
// initialized elsewhere. Specify
// the key and search type.
RecordListTablePane tablePane = new RecordListTablePane (system,
"/QSYS.LIB/QGPL.LIB/PARTS.FILE", key, RecordListTablePane.KEY_LE);
RecordListFormPane class:
A RecordListFormPane presents the contents of a server file in a form. The form displays one record at a
time and provides buttons that allow the user to scroll forward, backward, to the first or last record, or
refresh the view of the file contents.
To use a RecordListFormPane, set the system and fileName properties. Set these properties by using the
constructor or the setSystem() and setFileName() methods. Use load() to retrieve the file contents and
present the first record. When the file contents are no longer needed, call close() to ensure that the file is
closed.
Example
Related information:
RecordListFormPane Javadoc
RecordListTablePane class:
A RecordListTablePane presents the contents of a server file in a table. Each row in the table displays a
record from the file and each column displays a field.
To use a RecordListTablePane, set the system and fileName properties. Set these properties by using the
constructor or the setSystem() and setFileName() methods. Use load() to retrieve the file contents and
present the records in the table. When the file contents are no longer needed, call close() to ensure that
the file is closed.
RecordListTablePane is implemented using the model-view-controller paradigm, in which the data and
the user interface are separated into different classes.
The implementation integrates RecordListTableModel with Java Foundation Classes' (JFC) JTable. The
RecordListTableModel class retrieves and manages the contents of the file and JTable displays the file
contents graphically and handles user interaction.
RecordListTablePane provides enough functionality for most requirements. However, if a caller needs
more control of the JFC component, then the caller can use RecordListTableModel directly and provide
customized integration with a different graphical user interface component.
To use a RecordListTableModel, set the system and fileName properties. Set these properties by using the
constructor or the setSystem() and setFileName() methods. Use load() to retrieve the file contents. When
the file contents are no longer needed, call close() to ensure that the file is closed.
The following example creates a RecordListTableModel object and presents it with a JTable:
// Create a RecordListTableModel
// object. Assume that "system" is
// an AS400 object that is created
// and initialized elsewhere.
RecordListTableModel tableModel = new RecordListTableModel (system, "/QSYS.LIB/QIWS.LIB/QCUSTCDT.FILE");
RecordListTableModel Javadoc
Pop-up menus are enabled by default for both ResourceListPane and ResourceListDetailsPane.
Most errors are reported as com.ibm.as400.vaccess.ErrorEvents rather than thrown exceptions. Listen for
ErrorEvents in order to diagnose and recover from error conditions.
This example creates a ResourceList of all users on a system and displays it in a GUI (details pane):
// Create the resource list.
AS400 system = new AS400("MYSYSTEM", "MYUSERID", "MYPASSWORD");
RUserList userList = new RUserList(system);
You also have the option to create your own GUIs using the Java Foundation Classes (JFC). The
VSystemStatus object represents a system status on the server. The VSystemPool object represents a
system pool on the server. The VSystemStatusPane represents a visual pane that displays the system
status information.
The VSystemStatus class allows you to get information about the status of a server session within a GUI
environment:
v The getSystem() method returns the server where the system status information is contained
v The getText() method returns the description text
v The setSystem() method sets the server where the system status information is located
In addition to the methods mentioned above, you can also access and change system pool information in
a GUI.
You use VSystemStatus with VSystemStatusPane. VSystemPane is the visual display pane where
information is shown for both system status and system pool.
VSystemPool class:
The VSystemPool class allows you to retrieve and set system pool information from a server using a GUI
design. VSystemPool works with various panes in the vaccess package including the VSystemStatusPane.
The following list is some of the methods that are available to use in VSystemPool:
v The getActions() method returns a list of actions that you can perform
v The getSystem() method returns the server where the system pool information is found
v The setSystemPool() method sets the system pool object
Related information:
VSystemPool Javadoc
VSystemStatusPane
VSystemStatusPane class:
The VSystemStatusPane class allows a Java program to display system status and system pool
information.
The following example shows you how to use the VSystemStatusPane class:
// Create an as400 object.
AS400 mySystem = new AS400("mySystem.myCompany.com");
// Create a VSystemStatusPane
VSystemStatusPane myPane = new VSystemStatusPane(mySystem);
To use the System Value GUI component, set the system name with a constructor or through the
setSystem() method.
Example The following example creates a system value GUI using the AS400Explorer Pane:
//Create an AS400 object
AS400 mySystem = newAS400("mySystem.myCompany.com");
VSystemValueList mySystemValueList = new VSystemValueList(mySystem);
as400Panel=new AS400ExplorerPane((VNode)mySystemValueList);
//Create and load an AS400ExplorerPane object
as400Panel.load();
Related information:
AS400Pane and VUserList objects can be used together to present many views of the list. They can also
be used to allow the user to select users and groups.
To use a VUserList, you must first set the system property. Set this property by using a constructor or
through the setSystem() method. The VUserList object is then "plugged" into the AS400Pane as the root,
using the constructor or setRoot() method of the AS400Pane.
VUserList has some other useful properties for defining the set of users and groups that are presented in
AS400Panes:
v Use the setUserInfo() method to specify the types of users that should appear.
v Use the setGroupInfo() method to specify a group name.
You can use the VUserAndGroup object to get information about the Users and Groups on the system.
Before you can get information about a particular object, you need to load the information so that it can
be accessed. You can display the server in which the information is found by using the getSystem
method.
When AS400Pane objects and VUserList or VUserAndGroup objects are created, they are initialized to a
default state. The list of users and groups has not been loaded. To load the contents, the Java program
must explicitly call the load() method on either object to initiate communication to the server to gather
the contents of the list.
At run-time, right-click a user, user list, or group to display the shortcut menu. Select Properties from the
shortcut menu to perform actions on the selected object:
v User - Display a list of user information including the description, user class, status, job description,
output information, message information, international information, security information, and group
information.
v User list - Work with user information and group information properties. You can also change the
contents of the list.
v Users and groups - Display properties, such as the user name and description.
Users can only access users and groups to which they are authorized. In addition, the Java program can
prevent the user from performing actions by using the setAllowActions() method on the pane.
Other Examples
Present a list of users on the system using an AS400ListPane with a VUserList object.
The following image shows the VUserList graphical user interface component:
VUser Javadoc
VUserAndGroup Javadoc
You can incorporate the panels into your Java applications, applets, or System i Navigator plug-ins. The
panels may contain data obtained from the system, or data obtained from another source such as a file in
the local file system or a program on the network.
The Resource Script Converter converts Windows resource scripts into an XML representation that is
usable by Java programs. With the Resource Script Converter you can process Windows resource scripts
(RC files) from your existing Windows dialogs and menus. These converted files can then be edited with
the GUI Builder. Property sheets and wizards can be made from RC files using the resource script
converter along with the GUI Builder.
Underlying these two tools is a new technology called the Panel Definition Markup Language, or
PDML. PDML is based on the Extensible Markup Language (XML) and defines a platform-independent
language for describing the layout of user interface elements. Once your panels are defined in PDML,
you can use the runtime API provided by the Graphical Toolbox to display them. The API displays your
panels by interpreting the PDML and rendering your user interface using the Java Foundation Classes.
Note: Using PDML requires that you run version 1.4 or later of the Java Runtime Environment.
The Graphical Toolbox provides you with two tools and, therefore, two ways of automating the creation
of your user interfaces. You can use the GUI Builder to quickly and easily create new panels from scratch,
GUI Builder
Two windows are displayed when you invoke the GUI Builder for the first time, as shown in Figure 1:
Use the File Builder window to create and edit your PDML files.
Use the Properties window to view or change the properties of the currently selected control.
The panel being edited is displayed in the Panel Builder window. Figure 5 shows how the windows work
together:
The Resource Script Converter consists of a two-paned tabbed dialog. On the Convert pane you specify
the name of the Microsoft or VisualAge® for Windows RC file that is to be converted to PDML. You can
specify the name of the target PDML file and associated Java resource bundle that will contain the
translated strings for the panels. In addition, you can request that online help skeletons be generated for
the panels, generate Java source code skeletons for the objects that supply data to the panels, and
serialize the panel definitions for improved performance at runtime. The Converter's online help provides
a detailed description of each input field on the Convert pane.
You must also ensure that your workstation meets the requirements to run IBM Toolbox for Java.
To develop Java programs using the Graphical Toolbox, first install the Graphical Toolbox JAR files on
your workstation. Use one of the following methods:
Transfer the JAR Files
Note: The following list represents some of the methods you can use to transfer the JAR files. The
IBM Toolbox for Java licensed program must be installed on your system. Additionally, you need
to download the JAR file for JavaHelp, jhall.jar, from the Sun JavaHelp Web site .
v Use FTP (ensure you transfer the files in binary mode) and copy the JAR files from the
directory /QIBM/ProdData/HTTP/Public/jt400/lib to a local directory on your workstation
v Use IBM i Access for Windows to map a network drive.
Install JAR files with IBM i Access for Windows
You can also install the Graphical Toolbox when you install IBM i Access for Windows. The IBM
Toolbox for Java is now shipped as part of IBM i Access for Windows. If you are installing IBM i
Access for Windows for the first time, choose Custom Install and select the IBM Toolbox for Java
component on the install menu. If you have already installed IBM i Access for Windows, you
can use the Selective Setup program to install this component if it is not already present.
To use the Graphical Toolbox, you must add these JAR files to your CLASSPATH environment variable
(or specify them on the classpath option on the command line).
For example, if you have copied the files to the directory C:\gtbox\lib on your workstation, you must
add the following path names to your classpath:
C:\gtbox\lib\uitools.jar;
C:\gtbox\lib\jui400.jar;
C:\gtbox\lib\data400.jar;
C:\gtbox\lib\util400.jar;
C:\gtbox\lib\jhall.jar;
You also need to add an XML parser to your CLASSPATH. For more information, see the following page:
If you have installed the Graphical Toolbox using IBM i Access for Windows, the JAR files (except
jhall.jar) will all reside in the directory \Program Files\Ibm\Client Access\jt400\lib on the drive where
you have installed IBM i Access for Windows. IBM i Access for Windows installs jhall.jar in the \Program
Files\Ibm\Client Access\jre\lib directory. The path names in your classpath reflect this.
Note: You can use internationalized versions of the GUI Builder and Resource Script Converter tools. To
run a non-U.S. English version, you must add to your Graphical Toolbox installation the correct
version of uitools.jar for your language and country or region. These JAR files are available on the
server in /QIBM/ProdData/HTTP/Public/jt400/Mri29xx, where 29xx is the 4-digit IBM i NLV code
that corresponds to your language and country or region. The names of the JAR files in the various
Mri29xx directories include 2-character suffixes for the Java language code and the country or
region code. This additional JAR file is be added to your classpath ahead of uitools.jar in the
search order.
Once you have installed the Graphical Toolbox, follow these links to learn how to use the tools:
v Using the GUI Builder
v Using the Resource Script Converter
If you did not set your CLASSPATH environment variable to contain the Graphical Toolbox JAR files,
then you will need to specify them on the command line using the classpath option. See Setting Up the
Graphical Toolbox.
Options -plaf look and feel
The platform look and feel that you want. This option lets you override the default look and feel
that is set based on the platform you are developing on, so you can preview your panels to see
how they will look on different operating system platforms. The following look and feel values
are accepted:
v Windows
v Metal
v Motif
Currently, additional look and feel attributes that Swing 1.1 may support are not supported by
the GUI Builder
When you start the GUI Builder for the first time, you need to create a new PDML file. From the menu
bar on the GUI Builder widow, select File --> New File. After you create your new PDML file, you can
define any of the following types of UI resources that you want it to contain.
Panel The fundamental resource type. It describes a rectangular area within which UI elements are
arranged. The UI elements may consist of simple controls, such as radio buttons or text fields,
images, animations, custom controls, or more sophisticated subpanels (see the following
definitions for Split Pane, Deck Pane and Tabbed Pane). A panel may define the layout for a
stand-alone window or dialog, or it may define one of the subpanels that is contained in another
UI resource.
Menu A popup window containing one or more selectable actions, each represented by a text string
("Cut", "Copy" and "Paste" are examples). You can define mnemonics and accelerator keys for
each action, insert separators and cascading submenus, or define special checked or radio button
menu items. A menu resource may be used as a stand-alone context menu, as a drop-down menu
in a menu bar, or it may itself define the menu bar associated with a panel resource.
Toolbar
A window consisting of a series of push buttons, each representing a possible user action. Each
button may contain text, an icon or both. You can define the toolbar as floatable, which lets the
user drag the toolbar out of a panel and into a stand-alone window.
Property Sheet
A stand-alone window or dialog consisting of a tabbed panels and OK, Cancel, and Help
buttons. Panel resources define the layout of each tabbed window.
Wizard
A stand-alone window or dialog consisting of a series of panels that are displayed to the user in a
predefined sequence, with Back, Next, Cancel, Finish, and Help buttons. The wizard window
may also display a list of tasks to the left of the panels which track the user's progress through
the wizard.
Split Pane
A subpane consisting of two panels separated by a splitter bar. The panels may be arranged
horizontally or vertically.
IBM Toolbox for Java 297
Tabbed Pane
A subpane that forms a tabbed control. This tabbed control can be placed inside of another panel,
split pane, or deck pane.
Deck Pane
A subpane consisting of a collection of panels. Of these, only one panel can be displayed at a
time. For example, at runtime the deck pane might change the panel which is displayed
depending on a given user action.
String Table
A collection of string resources and their associated resource identifiers.
Generated files
The translatable strings for a panel are not stored in the PDML file itself, but in a separate Java resource
bundle. The tools let you specify how the resource bundle is defined, either as a Java PROPERTIES file or
as a ListResourceBundle subclass. A ListResourceBundle subclass is a compiled version of the translatable
resources, which enhances the performance of your Java application. However, it will slow down the GUI
Builder's saving process, because the ListResourceBundle will be compiled in each save operation.
Therefore it's best to start with a PROPERTIES file (the default setting) until you're satisfied with the
design of your user interface.
You can use the tools to generate HTML skeletons for each panel in the PDML file. At runtime, the
correct help topic is displayed when the user clicks on the panel's Help button or presses F1 while the
focus is on one of the panel's controls. You must insert your help content at the appropriate points in the
HTML, within the scope of the <!-- HELPDOC:SEGMENTBEGIN --> and <!-- HELPDOC:SEGMENTEND --> tags. For
more specific help information see Editing Help Documents generated by GUI builder.
You can generate source code skeletons for the JavaBeans that will supply the data for a panel. Use the
Properties window of the GUI Builder to fill in the DATACLASS and ATTRIBUTE properties for the
controls which will contain data. The DATACLASS property identifies the class name of the bean, and
the ATTRIBUTE property specifies the name of the gettor/settor methods that the bean class
implements. Once you've added this information to the PDML file, you can use the GUI Builder to
generate Java source code skeletons and compile them. At runtime, the appropriate gettor/settor
methods will be called to fill in the data for the panel.
Note: The number and type of gettor/settor methods is dependent on the type of UI control with
which the methods are associated. The method protocols for each control are documented in the
class description for the DataBean class.
Finally, you can serialize the contents of your PDML file. Serialization produces a compact binary
representation of all of the UI resources in the file. This greatly improves the performance of your user
interface, because the PDML file must not be interpreted in order to display your panels.
To summarize: If you have created a PDML file named MyPanels.pdml, the following files will also be
produced based on the options you have selected on the tools:
v MyPanels.properties if you have defined the resource bundle as a PROPERTIES file
v MyPanels.java and MyPanels.class if you have defined the resource bundle as a ListResourceBundle
subclass
v <panel name>.html for each panel in the PDML file, if you have elected to generate online help
skeletons
v <dataclass name>.java and <dataclass name>.class for each unique bean class that you have specified
on your DATACLASS properties, if you have elected to generate source code skeletons for your
JavaBeans
v <resource name>.pdml.ser for each UI resource defined in the PDML file, if you've elected to serialize
its contents.
If you did not set your CLASSPATH environment variable to contain the Graphical Toolbox JAR files,
then you will need to specify them on the command line using the classpath option. See Setting Up the
Graphical Toolbox.
You can also run the Resource Script Converter in batch mode using the following command:
java com.ibm.as400.ui.tools.RC2XML file [options]
Where file is the name of the resource script (RC file) to be processed. Options
-x name
The name of the generated PDML file. Defaults to the name of the RC file to be processed.
-p name
The name of the generated PROPERTIES file. Defaults to the name of the PDML file.
-r name
The name of the generated ListResourceBundle subclass. Defaults to the name of the PDML file.
-package name
The name of the package to which the generated resources will be assigned. If not specified, no
package statements will be generated.
-l locale
The locale in which to produce the generated resources. If a locale is specified, the appropriate
2-character ISO language and country or region codes are suffixed to the name of the generated
resource bundle.
-h Generate HTML skeletons for online help.
-d Generate source code skeletons for JavaBeans.
-s Serialize all resources.
All dialogs, menus, and string tables found in the RC file will be converted to the corresponding
Graphical Toolbox resources in the generated PDML file. You can also define DATACLASS and
ATTRIBUTE properties for Windows controls that will be propagated to the new PDML file by following
a simple naming convention when you create the identifiers for your Windows resources. These
properties will be used to generate source code skeletons for your JavaBeans when you run the
conversion.
The elements of the Graphical Toolbox runtime environment are shown in Figure 1. Your Java program is
a client of one or more of the objects in the Runtime Managers box.
Assume that the panel MyPanel is defined in the file TestPanels.pdml, and that a properties file
TestPanels.properties is associated with the panel definition. Both files reside in the directory
com/ourCompany/ourPackage, which is accessible either from a directory defined in the classpath or
from a ZIP or JAR file defined in the classpath.
Note: Read the Code example disclaimer for important legal information.
PanelManager pm = null;
try {
pm = new PanelManager("com.ourCompany.ourPackage.TestPanels", "MyPanel", null);
}
catch (DisplayManagerException e) {
e.displayUserMessage(null);
System.exit(-1);
}
Once the DataBeans that supply data to the panel have been implemented and the attributes have been
identified in the PDML, the following code may be used to construct a fully-functioning dialog:
import com.ibm.as400.ui.framework.java.*;
import java.awt.Frame;
Frame owner;
...
PanelManager pm = null;
try {
pm = new PanelManager("com.ourCompany.ourPackage.TestPanels", "MyPanel", dataBeans, owner);
}
catch (DisplayManagerException e) {
e.displayUserMessage(null);
System.exit(-1);
}
A new service has been added to the existing panel manager. The dynamic panel manager dynamically
sizes the panel at runtime. Let's look at the MyPanel example again, using the dynamic panel manager:
import com.ibm.as400.ui.framework.java.*;
catch (DisplayManagerException e) {
e.displayUserMessage(null);
System.exit(-1);
}
This figure illustrates how the elements of the Graphical Toolbox runtime environment interact with
application code.
Description
The figure is composed of several boxes of differing shapes, sizes, and colors that are connected to each
other by lines terminated by arrowheads at one or both ends.
In order to visualize the figure, it is useful to divide it into three columns and four rows, numbering the
areas in sequence from top left to bottom right. fo example, The first row contains areas 1, 2, and 3; the
second row contains areas 4, 5, and 6; and so on:
v The image of a dialog box that occupies areas 2 and 5 represents the GUI interface for your Java
program. The dialog box features a variety of options, like check boxes, text fields, and so on.
v Two tan cylinders at the top of area 1 are labeled PDML Source and Resource Bundle. These cylinders
represent PDML source and Java resource files that reside on a storage medium.
v One tan cylinder in area 10 labeled PDML Serialized represents one or more serialized PDML files that
reside on a storage medium.
v Five blue rectangles that surround the bottom portion of the dialog box represent components of the
Graphical Toolbox. Starting at the leftmost rectangle and moving counter-clockwise, they are labeled:
– XML Parser (Pure Java) in area 4, which represents the IBM XML Parser.
– Runtime Managers (Pure Java) in area 7. Your Java program is a client of one or more of the objects
contained in Runtime Managers: Panels, Property sheets, Wizards, and Layout.
– Common Data Exchanger (Pure Java) in area 8.
– Common Formatters (Pure Java) in area 9.
– Common Handlers (Pure Java) in area 6.
v Three green rectangles represent code provided by the application programmer and are labeled:
– Custom Handlers (Java Application) in area 3
– Custom Formatters (Java Application) in are 12
– User Interface Data Beans (Pure Java) in area 11
v Lines connect many of the shapes:
– A line that has a single arrowhead (on one end) indicates an action. Single arrowhead lines point
toward a function or component that uses the object from which the line originates. In the following
description, the word "use" means that a line with a single arrowhead points toward an object from
the component that acts upon it.
– A line that has a double arrowhead (one at each end) indicates an interaction. These lines connect
objects that share a two-way exchange of information. In the following description, the word
"interact" means that the components are connected by a line with a double arrowhead.
The GUI interface for your Java program (the image of the dialog in areas 2 and 5) interacts with the
Runtime Managers for the Graphical Toolbox (the blue rectangle in area 7).
Your GUI-enabled Java program operates on data in one of the following ways:
v Having the GUI interface interact with custom handlers (the green rectangle in area 3) and common
handlers (the blue rectangle in area 6)
v Having the common data exchanger (the blue rectangle in area 8) use the GUI interface to obtain
information
The custom handlers, common handlers, and the common data exchanger all interact with the user
interface data beans (the green rectangle in area 11), passing information back and forth. The common
data exchanger interacts with common formatters (the blue rectangle in area 9) and custom formatters
(the green rectangle in area 12) to convert the data into appropriate formats for the user interface data
beans.
The Help Document is a valid HTML file and can be viewed in any browser and edited using most
HTML editors. Tags that define the sections in a Help Document are embedded within comments, so they
do not show up in a browser. The comment tags are used to break the Help Document into several
sections:
v Header
v Topic section for each dialog
v Topic section for each control that is help-enabled
v Footer
In addition, you can add additional topic sections before the footer to provide additional information or
common information. Topic sections have only the html body until they are split, when a header and
footer are created. When the Help Document is split up, the processor adds a header and footer to the
topic section to make a complete HTML file. The header and footer from the Help Document are used as
default header and footer. However, you can override the default header with your own.
If you want to override the default header for all of the individual topics when they are split, use
the HEADER keyword and provide the name of an html fragment to include. For example:
<!-- HELPDOC:HEADEREND HEADER="defaultheader.html" -->
Topic segment
Each topic is surrounded by the following tags:
and
<!-- HELPDOC:SEGMENTEND -->
Immediately following the SEGMENTBEGIN tag is an anchor tag which names the segment. It also
provides the file name of the HTML document that is created when the Help Document is split.
The name of the segment combines the panel identifier, control identifier, and future file
extension (html). For example: "MY_PANEL.MY_CONTROL.html" Segments for panels have only
the panel identifier and future file extension.
The help generator will place text in the document indicating where you place your help
information:
<!-- HELPDOC:SEGMENTBEGIN PDMLSYNCH="YES" --><A NAME="MY_PANEL.MY_CONTROL.html"></A>
<H2>My favorite control</H2>
Insert help for "My favorite control" here.
<P><!-- HELPDOC:SEGMENTEND -->
You can add additional HTML 2.0 tags as needed after the anchor tag and before the SEGMENTEND
tag.
The PDMLSYNCH tag controls how closely a segment is tied to the controls defined in PDML. If
PDMLSYCH is "YES", the Help Document segment will be removed if the control of the same name
is removed in the PDML. PDMLSYNCH="NO" indicates the topic must be kept in the Help Document
regardless of whether a corresponding control exists in the PDML. This is used, for example,
when you create additional topics for depth or a common topic.
The help generated for a panel has links to each control enabled for help on the panel. These
links are generated with a local anchor reference, so that you can test them as internal links in a
standard browser. When the Help Document is split, the processor removes the "#" on these
internal links making them external links in the resulting single topic HTML files. Because you
may want to have internal links within a topic, the processor only removes any preceding "#"
when the reference has ".html" embedded in it.
If you want to override the default header for any particular topic, use the HEADER keyword and
provide the name of an html fragment to include. For example:
<!-- HELPDOC:SEGMENTBEGIN PDMLSYNCH="YES" HEADER="specialheader.html" -->
Footer The footer in the Help Document begins with the following tag:
<!-- HELPDOC:FOOTERBEGIN -->
Adding links
You can add links to any external or internal URL as well as any other segment. However, you must
follow some conventions:
v External URLs are used in the standard manner. This includes internal links to external URLs
v Internal links within the same topic are written in the standard way, but must not have ".html" as part
of the tag name. This is because the Help Document processor assumes that any link with .html will
need to be an external link when the topics are separate. Therefore, it removes the preceding "#".
v Links to other topic segments must be written with a preceding "#" as though they are an internal
anchor reference.
v Internal links to other topic segments may also be created. Only the leading "#" is removed during
processing.
Note:
You can edit your help content in almost any visual HTML editor. Because the HELPDOC tags are
comments they may not be obvious in some editors. For convenience, a horizontal rule is added to the
help skeleton immediately before the SEGMENTBEGIN tag and immediately after the SEGMENTEND
tag. These horizontal rules provide clear visual indication of the entire segment in a visual editor. If you
select a segment because you want to move, copy, or delete it, select the surrounding horizontal rules to
be sure you have included the SEGMENTBEGIN and SEGMENTEND tags in your selection. These
horizontal rules are not copied to the final individual HTML files.
You can create additional topic segments in the Help Document. It is often easiest to do this by copying
another segment. When you copy the segment, you must copy the horizontal rules just before the
SEGMENTBEGIN and after the SEGMENTEND tag. This will make future visual editing much easier and
help avoid mismatched tags. For best results, use the following tips:
v The name of the anchor must be the name you want for the resulting single file when the Help
Document is split. It must end in ".html".
v Use the PDMLSYNCH="NO" keyword on the SEGMENTBEGIN tag to prevent the segment from being
removed if the help skeleton is regenerated.
v Any references to your new topic will be made as an internal link in the Help Document with a
preceding "#". This "#" will be removed in later processing when the segments are split into single files.
For most writing, you can check your links by viewing your document in a Web browser and selecting
different links. In the single Help Document, the links are still in their internal form.
As you reach completion, or when you want to test with the application you are developing help for, you
will need to break the Help Document into single files. You do this with Help Document to HTML
Processing.
If you need to regenerate the Help Document after editing, your writing will be preserved. You may
want to regenerate the Help Document if you add new controls after generating the original help
skeleton. In this case, the help generator checks for an existing Help Document before it creates a new
skeleton. If one is found, it preserves any existing segments and then adds the new controls.
This section describes how to convert the simple panel from the Graphical Toolbox Example to run in a
browser. The minimum browser levels supported are Netscape 4.05 and Internet Explorer 4.0. In order to
avoid having to deal with the idiosyncrasies of individual browsers, it is recommend that your applets
run using Sun's Java Plug-in. Otherwise, you will need to construct signed JAR files for Netscape, and
separate signed CAB files for Internet Explorer.
Note: Read the Code example disclaimer for important legal information.
The code to display a panel in an applet is nearly identical to the code used in the Java application
example, but first, the code must be repackaged in the init method of a JApplet subclass. Also, some
code was added to ensure that the applet panel is sized to the dimensions specified in the panel's PDML
definition. Here is the source code for the example applet, SampleApplet.java.
import com.ibm.as400.ui.framework.java.*;
import javax.swing.*;
import java.awt.*;
import java.applet.*;
import java.util.*;
// Do a check to make sure we’re running a Java virtual machine that’s compatible with Swing 1.1
if (System.getProperty("java.version").compareTo("1.1.5") < 0)
throw new IllegalStateException("SampleApplet cannot run on Java VM version " +
System.getProperty("java.version") +
" - requires 1.1.5 or higher");
The applet's content pane is passed to the Graphical Toolbox as the container to be laid out. In the start
method, the applet pane is set to its correct size, and then override the paint method in order to preserve
the panel's size when the browser window is resized.
When running the Graphical Toolbox in a browser, the HTML files for your panel's online help cannot be
accessed from a JAR file. They must reside as separate files in the directory where your applet resides.
The call to PanelManager.setHelpPath identifies this directory to the Graphical Toolbox, so that your
help files can be located.
HTML tags
Because it is recommended to use Sun's Java Plug-in to provide the correct level of the Java runtime
environment, the HTML for identifying a Graphical Toolbox applet is not as straightforward as preferred.
Fortunately, the same HTML template may be reused, with only slight changes, for other applets. The
markup is designed to be interpreted in both Netscape Navigator and Internet Explorer, and it generates
a prompt for downloading the Java Plug-in from Sun's Web site if it's not already installed on the user's
machine. For detailed information on the workings of the Java Plug-in see the Java Plug-in HTML
Specification.
Here is the HTML for the sample applet, in the file MyGUI.html:
<html>
<head>
<title>Graphical Toolbox Demo</title>
</head>
<body>
<h1>Graphical Toolbox Demo Using Java(TM) Plug-in</h1>
<p>
<!-- The following tags use a special syntax which allows both Netscape and Internet Explorer to load -->
<!-- the Java Plug-in and run the applet in the Plug-in’s JRE. Do not modify this syntax. -->
<!-- For more information see http://java.sun.com/products/jfc/tsc/swingdoc-current/java_plug_in.html.-->
<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
width="400"
height="200"
align="left"
codebase="http://java.sun.com/products/plugin/1.1.3/jinstall-113-win32.cab#Version=1,1,3,0">
<PARAM name="code" value="SampleApplet">
<PARAM name="codebase" value="http://www.mycompany.com/~auser/applets/">
<COMMENT>
<EMBED type="application/x-java-applet;version=1.1"
width="400"
height=200"
align="left"
code="SampleApplet"
codebase="http://www.mycompany.com/~auser/applets/"
archive="MyGUI.jar,jui400.jar,util400.jar,x4j400.jar"
pluginspage="http://java.sun.com/products/plugin/1.1.3/plugin-install.html">
<NOEMBED>
</COMMENT>
No support for JDK 1.1 applets found!
</NOEMBED>
</EMBED>
</OBJECT>
<p>
</body>
</html>
Note: In this example, the XML parser JAR file, x4j400.jar, is stored on the Web server. You can use other
XML parsers. For more information, see “XML parser and XSLT processor” on page 417. This is
required only when you include your PDML file as part of your applet's installation. For
performance reasons, you would normally serialize your panel definitions so that the Graphical
Toolbox does not have to interpret the PDML at runtime. This greatly improves the performance of
your user interface by creating compact binary representations of your panels. For more
information see the description of files generated by the tools.
Install the applet on your favorite Web server by performing the following steps:
1. Compile SampleApplet.java.
2. Create a JAR file named MyGUI.jar to contain the applet binaries. These include the class files
produced when you compiled SampleApplet.java and SampleBean.java, the PDML file
MyGUI.pdml, and the resource bundle MyGUI.properties.
3. Copy your new JAR file to a directory of your choice on your Web server. Copy the HTML files
containing your online help into the server directory.
4. Copy the Graphical Toolbox JAR files into the server directory.
5. Finally, copy the HTML file MyGUI.html containing the embedded applet into the server directory.
Tip: When testing your applets, ensure that you have removed the Graphical Toolbox JAR files from the
CLASSPATH environment variable on your workstation. Otherwise, you will see error messages
saying that the resources for your applet cannot be located on the server.
Now you are ready to run the applet. Point your Web browser to MyGUI.html on the server. If you do
not already have the Java Plug-in installed, you will be asked if you want to install it. Once the Plug-in is
installed and the applet is started, your browser display should look similar to the Figure 1:
Click Deck Pane to insert a deck pane on a panel. A deck pane contains a stack of panels. The user
can select any of the panels, but only the selected panel is fully visible.
Click Split Pane to insert a split pane on a panel. A split pane is one pane divided into two
horizontal or vertical panes.
Click Tabbed Pane to insert a tabbed pane on a panel. A tabbed pane contains a collection of panels
with tabs at the top. The user clicks a tab to display the contents of a panel. The title of the panel is used
as the text for a tab.
Click Align Top to align multiple components on a panel with the top edge of a specific, or primary,
component.
Click Align Bottom to align multiple components on a panel with the bottom edge of a specific, or
primary, component.
Click Center Vertically to center a selected component vertically relative to the panel.
Click Align Left to align multiple components on a panel with the left edge of a specific, or primary,
component.
Click Align Right to align multiple components on a panel with the left edge of a specific, or
primary, component.
Click Equalize Width to equalize the width of multiple components with the width of a specific, or
primary, component.
Click Center Horizontally to center a selected component horizontally relative to the panel.
Click Tab Order to control the selection order of each panel component when the user presses TAB
to navigate through the panel.
Click Help to get more specific information about the Graphical Toolbox.
JavaBeans can be either visual or nonvisual components. Non-visual JavaBeans still have a visual
representation, such as an icon or a name, to allow visual manipulation.
JavaBeans can be used within an application program or they can be visually manipulated in builder
tools, such as the IBM VisualAge for Java product.
Examples
The following examples show how to use JavaBeans in your program and how to create a program from
JavaBeans by using a visual bean builder:
JDBC
JDBC is an application programming interface (API) included in the Java platform that enables Java
programs to connect to a wide range of databases.
The IBM Toolbox for Java JDBC driver allows you to use JDBC API interfaces to issue structured query
language (SQL) statements to and process results from databases on the server. You can also use IBM
Developer Kit for Java JDBC driver, called the 'native' JDBC driver:
v Use the IBM Toolbox JDBC driver when the Java program is on one system and the database files are
on another system, as in a client/server environment
v Use the native JDBC driver when both the Java program and database files are on the same server
| Enhancements to IBM Toolbox for Java JDBC support for IBM i 7.1
| Many additions were made to JDBC support in IBM i 7.1.
| The enhancements to IBM Toolbox for Java JDBC support are detailed in the following sections:
| v “XML data type support” on page 315
| v “Database metadata updates” on page 316
| v “Currently committed support” on page 316
| v “Array type support” on page 316
| v “Long schema name support” on page 317
| The JDBC 4.0 interface specification adds new methods and classes for XML data type support. IBM
| Toolbox for Java implements XML support in its JDBC 4.0 driver. This allows JDBC clients easy access to
| IBM i 7.1 XML support.
| You can set the data in the JDBC SQLXML object by passing in various data types such as Java String. As
| is done for all other text column data types, IBM Toolbox for Java or the Database Management System
| (DBMS) does the necessary conversions of XML data to match column CCSID for the XML column.
| The DBMS reads and writes XML data using SQL locators.
| XML being sent as input to the DBMS has to be handled with a few special rules in order for correct
| CCSID conversion. Input XML data which has an XML declaration with encoding specified must
| correctly encode the XML data with that specified encoding. For example XML encoded in UTF-16 (Java
| String), but having a UTF-8 specified in its encoding in the XML declaration is incorrect. If the XML input
| data has no declaration, then the DBMS expects the data stream to be sent in UTF-8. In this case IBM
| Toolbox for Java first converts the XML data to UTF-8 before sending the data to the DBMS for
| processing.
| Note: XML columns in the database are stored without the XML declaration. When the XML data is
| retrieved, the XML declaration is dynamically generated, which can lead to the XML data not
| being identical to the XML data that was sent as input.
| The DBMS may optimize XML data when appropriate. For example an empty tag, "<tag><tag/>",
| becomes "</tag>". Generally if input XML data that is not in UTF-16 and has an XML declaration along
| with an encoding specified, it should not be passed into JDBC through PreparedStatement.setString. This
| is because the data in Strings is UTF-16 and it does not match the specified encoding.
| There are some rules that govern how XML declarations are returned from a query. JDBC handles the
| declaration visibility depending on which type ResultSet getter method called. Methods that return
| characters, such as getString() and getClob(), do not return the XML declaration with the data. Methods
| that return binary data, such as getBytes() and getBlob(), will return the XML declaration. This is due to
| the difference in XML declaration encoding and the CCSID of the actual XML column on the table. Note
| that calling getString() will return a Unicode String, which could be different from the CCSID specified in
| the XML declaration encoding. Because of this anomaly, the declaration is simply discarded unless
| accessed with binary getter methods. The retrieval of XML tags with methods such as getString will
| allow XML data to be easily concatenated with other XML data since it will have its declaration removed
| already.
| XML JDBC support is implemented in the following IBM Toolbox for Java JDBC methods:
| v AS400JDBCConnection.createSQLXML()
| v AS400JDBCSQLXML - all methods in this new class
| v AS400JDBCPreparedStatement.setSQLXML(int parameterIndex, SQLXML xmlObject)
| v AS400JDBCCallableStatement.setSQLXML(String parameterName, SQLXML xmlObject)
| v AS400JDBCCallableStatement.getSQLXML(int parameterIndex)
| v AS400JDBCCallableStatement.getSQLXML(String parameterName)
| v AS400JDBCResultSet.getSQLXML(int columnIndex)
| v AS400JDBCResultSet.getSQLXML(String columnLabel)
| v AS400JDBCResultSet.updateSQLXML(int columnIndex, SQLXML xmlObject)
| v AS400JDBCResultSet.updateSQLXML(String columnLabel, SQLXML xmlObject)
| v AS400JDBCRowSet.setSQLXML(int parameterIndex, SQLXML xmlObject)
| v AS400JDBCRowSet.setSQLXML(String parameterName, SQLXML xmlObject)
| Database metadata is obtained by calling the various methods of the AS400JDBCDatabaseMetaData class.
| Starting with IBM i 7.1, the default behavior of IBM Toolbox for Java JDBC is to obtain this metadata
| from a set of standard system stored procedures. This brings IBM Toolbox for Java into alignment with
| IBM i native JDBC support in addition to JDBC drivers on other platforms. Prior to IBM i 7.1, IBM
| Toolbox for Java obtained the metadata from the host servers ROI data server. This approach has worked
| well, and has also kept IBM Toolbox for Java in alignment with ODBC, .net, and other IBM i clients. The
| problem with this approach though, is that across IBM, all JDBC DB2 drivers should function the same
| way. This can be achieved by using a set of system stored procedures that are common across all of the
| DB2 platforms. These system stored procedures are called to obtain system database metadata.
| In order to provide backwards compatibility of the metadata functionality, a new connection property,
| "metadata source", can be used to force IBM Toolbox for Java JDBC to use the old method of retrieval of
| database metadata.
| Lock timeouts and deadlocks can occur under the isolation levels that perform row-level locking,
| especially with applications that are not designed to prevent such problems. Some high throughput
| database applications cannot tolerate waiting on locks that are issued during transaction processing, and
| some applications cannot tolerate processing uncommitted data, but still require non-blocking behavior
| for read transactions.
| Under the new currently committed semantics, if currently committed is enabled then only committed data
| is returned, as was the case previously, but now readers do not wait for writers to release row locks.
| Instead, the data returned to readers is based on the currently committed version; that is, data prior to
| the start of the write operation.
| This feature also implements a way to direct the database manager to wait for the outcome when
| encountering data in the process of being updated.
| IBM Toolbox for Java JDBC has added support for currently committed semantics on data sources and
| connections. This support is added with the following class updates:
| v AS400JDBCDataSource.CONCURRENTACCESS_NOT_SET
| v AS400JDBCDataSource.CONCURRENTACCESS_USE_CURRENTLY_COMMITTED
| v AS400JDBCDataSource.CONCURRENTACCESS_WAIT_FOR_OUTCOME
| v AS400JDBCDataSource.CONCURRENTACCESS_SKIP_LOCKS
| v AS400JDBCDataSource.setConcurrentAccessResolution (int)
| v AS400JDBCDataSource.getConcurrentAccessResolution ()
| v AS400JDBCConnection.setConcurrentAccessResolution (int)
| v AS400JDBCConnection.getConcurrentAccessResolution ()
| Note: Setting concurrent access resolution on the connection only affects new statements created on the
| connections following the change. Existing statements continue to use the value that was in effect
| when the statement was created. A corresponding connection property "concurrent access
| resolution" is also available for setting this information.
| IBM Toolbox for Java supports the IBM i 7.1 SQL array data type in stored procedure parameters. Arrays
| of all of the various DB2 types are supported except data that is returned in a locator.
| JDBC supports the calling of stored procedures in the java.sql.CallableStatement class, which IBM Toolbox
| for Java implements in AS400JDBCCallableStatement.
| The JDBC specification from Sun says that JDBC drivers support arrays by implementing java.sql.Array
| interface. The IBM Toolbox for Java implementation exists in the class
| com.ibm.as400.access.AS400JDBCArray. Below are new interfaces and methods which IBM Toolbox for
| Java has implemented to support arrays:
| v AS400JDBC.PreparedStatement.setArray (int parameterIndex, Array x)
| v AS400JDBCCallableStatement.getArray()
| v AS400JDBCArray.getResultSet()
| v AS400JDBCArray.getBaseType()
| v AS400JDBCArray.getBaseTypeName()
| v AS400JDBCArrayResultSet - all methods in this new class
| v AS400JDBConnection.createArrayOf(String typeName, Object[] elements)
| Note: An AS400JDBCArrayResultSet is a local copy of the array data in a ResultSet interface object.
| IBM i 7.1 DBMS has added support for 128 byte schema names. IBM Toolbox for Java JDBC is also
| adding support for long schema names.
| IBM Toolbox for Java converts schemas from Java Strings to the system CCSID prior to sending the data
| to the host DBMS. IBM Toolbox for Java does allow a long schema name as the default-schema. However,
| long schema names in the library list is not supported. If a long schema name is specified in the
| "libraries" property, a warning back from host and trace that the library was not added will be issued. If a
| long schema name is specified as the first name in the "libraries" property, then IBM Toolbox for Java still
| sets the name as the default schema, but does not add it to the library list. Clients which need to use long
| schema names in the library list have to make use of the DB2 SET PATH command.
| Database metadata also supports long schema names for parameters and ResultSets returned.
| The following metadata methods provide support for long schema names:
| v AS400JDBCDatabaseMetadata.getMaxSchemaNameLength()
| v AS400JDBCDatabaseMetadata.getProcedures(String catalog, String schemaPattern, String
| procedureNamePattern)
| v AS400JDBCDatabaseMetadata.getProcedureColumns(String catalog, String schemaPattern, String
| procedureNamePattern, String columnNamePattern)
| v AS400JDBCDatabaseMetadata.getTables(String catalog, String schemaPattern, String tableNamePattern,
| String types[])
| v AS400JDBCDatabaseMetadata.getSchemas()
| v AS400JDBCDatabaseMetadata.getColumns(String catalog, String schemaPattern, String
| tableNamePattern, String columnNamePattern)
| v AS400JDBCDatabaseMetadata.getColumnPrivileges(String catalog, String schema, String table, String
| columnNamePattern)
| v AS400JDBCDatabaseMetadata.getTablePrivileges(String catalog, String schemaPattern, String
| tableNamePattern)
| Enhancements to IBM Toolbox for Java JDBC support for IBM i 6.1
Many additions were made to JDBC support in IBM i 6.1.
The enhancements to IBM Toolbox for Java JDBC support are detailed in the following sections:
v “Support for JDBC 4.0”
v “Query storage limit”
v “Decimal float (DECFLOAT) data type” on page 319
v “Passing the client type and application name to the server” on page 320
v “Maximum length of cursor names extended” on page 321
v “Generated key support” on page 321
v “Improved default value support” on page 321
v “Increased maximum in GROUP BY clause” on page 321
v “Batch update support” on page 321
| Support for the JDBC 4.0 API with Java SE Version 6 is available using one of the following JAR files:
| v /QIBM/ProdData/HTTP/Public/jt400/lib/java6/jt400.jar
| v /QIBM/ProdData/OS400/jt400/lib/java6/jt400Native.jar
setQueryStorageLimit()
public void setQueryStorageLimit(int limit);
Specifies the query storage limit value to be used when statements in a connection are executed. Valid
values are -1 to 2 147 352 578. The default is value -1, indicating a special value of *NOMAX.
getQueryStorageLimit()
public int getQueryStorageLimit()
Returns the query storage limit value used when statements in a connection are executed. The default
value is -1, indicating a special value of *NOMAX.
Systems that run a release of IBM i prior to V6R1 will ignore the getQueryStorageLimit property.
The IBM Toolbox for Java JDBC driver has added the following methods to the AS400JDBCDataSource
class:
setDecfloatRoundingMode()
public void setDecfloatRoundingMode(int String mode)
getDecfloatRoundingMode()
public intString getDecfloatRoundingMode()
Web applications need a way to pass end-user-client information to the database server so that more
detailed information may be logged. The IBM Toolbox for Java JDBC driver allows an application to
override this information by calling the following java.sql.Connection.setClientInfo() methods:
This method sets the value of the client info property specified by name to the value specified by value.
See the DatabaseMetadata.getClientInfoProperties method description for the client info properties
supported by the IBM Toolbox for Java JDBC driver.
This method sets the value of the connection's client info properties. The Properties object contains the
names and values of the client info properties to be set. The set of client info properties contained in the
properties list replaces the current set of client info properties on the connection. If a property that is
currently set on the connection is not present in the properties list, that property is cleared. Specifying an
empty properties list will clear all of the properties on the connection.
This method returns the value of the client info property specified by name. This method may return null
if the specified client info property has not been set and does not have a default value.
Properties AS400JDBCConnection.getClientInfo()
This method returns a list containing the name and current value of each client info property supported
by the driver. The value of a client info property may be null if the property has not been set and does
not have a default value.
ResultSet AS400JDBCDatabaseMetaData.getClientInfoProperties()
This method retrieves a list of the client info properties that the driver supports. The IBM Toolbox for
Java JDBC driver returns a result set with the following information:
Table 2. Result set for getClientInfoProperties
Name Maximum length Default value Description
ApplicationName 255 "" The name of the application
currently utilizing the
connection.
ClientAccounting 255 "" Accounting information.
ClientHostname 255 "" The hostname of the
computer the application
using the connection is
running on.
ClientProgramID 255 "" The client program
identification.
ClientUser 255 "" The name of the user that
the application using the
connection is performing
work for. This may not be
the same as the user name
that was used in
establishing the connection.
Beginning in V6R1, the maximum length of cursors will be 128 characters. The previous maximum length
was 8 characters. An application can set the name of a cursor by calling the
java.sql.Statement.setCursorName() method.
In past releases, only one row of information could be returned from a multiple row insert operation.
Beginning in V6R1, you will be able to access more information about a multiple row insert operation.
This will allow you to retrieve generated column information such as ROWID, identity column, sequence,
or generated expressions. Generated key support will be implemented in the following IBM Toolbox for
Java JDBC methods:
v AS400JDBCStatement.getGeneratedKeys()
v AS400JDBCStatement.execute(String sql, int autoGeneratedKeys)
v AS400JDBCStatement.execute (String sql, int[] columnIndexes)
v AS400JDBCStatement.execute (String sql, String[] columnNames)
v AS400JDBCStatement.executeUpdate(String sql, int[] autoGeneratedKeys)
v AS400JDBCStatement.executeUpdate (String sql, int[] columnIndexes)
v AS400JDBCStatement.executeUpdate (String sql, String[] columnNames)
v AS400JDBCConnection.prepareStatement(String sql, int autoGeneratedKeys)
v AS400JDBCConnection.prepareStatement(String sql, int[] columnIndexes)
v AS400JDBCConnection.prepareStatement(String sql, String[] columnNames)
Beginning in V6R1, The IBM Toolbox for Java JDBC driver will return a column's default value as a string
through the DatabaseMetaData.getColumns() method. If the default value is null, a string with the value
'NULL' will be returned.
The IBM Toolbox for Java JDBC driver will use this information when creating a
java.sql.BatchUpdateException. AS400JDBCStatement and AS400JDBCPreparedStatement will also use this
information to return the correct information back from the executeBatch() method.
Enhancements to IBM Toolbox for Java JDBC support for IBM i 5.4
Several JDBC functions were enhanced for IBM i 5.4.
The enhancements to IBM Toolbox for Java JDBC support are detailed in the following sections:
v “2 MB statement size” on page 322
v “128 byte column name support” on page 322
IBM Toolbox for Java 321
v “Database host server trace support”
v “eWLM Correlator support”
For information about enhanced JDBC functions for previous releases, see “Enhancements to JDBC
support for Version 5 Release 3” on page 323 and “Enhanced JDBC functions for i5/OS Version 5 Release
2” on page 324.
2 MB statement size
Prior to V5R4, the limit on SQL statement size was 65 535 bytes. This corresponds to 65 535 characters
when the statement text is represented using a single-byte CCSID, and 32 767 characters when the
statement text is represented using a double-byte CCSID. Some customers, particularly those using
applications that automatically generate SQL statements, were affected by this limit.
In V5R4, the IBM i statement size limit has been increased to two megabytes, or 2 097 152 bytes. The
IBM Toolbox for Java JDBC driver always sends statement text in two byte Unicode. Therefore, the
maximum statement length in characters will be one megabyte or 1 048 576 characters.
Starting with V5R4, the database will support column names up to 128 bytes for SQL tables. Prior to
V5R4, column names up to 30 bytes were supported. The IBM Toolbox for Java JDBC driver will provide
these possibly longer names to its users.
There is one exception where 128 byte column names will not be returned. When local package caching is
used and column names exceed 30 characters, the server will return the column names as the system
column name.
A new option was added to the Toolbox for Java JDBC driver to turn on database host server tracing. To
support this feature, option "64" was added to the "server trace" connection property. For more details,
see “IBM Toolbox for Java JDBC properties” on page 326.
The IBM Toolbox for Java will accept an IBM Enterprise Workload Manager (eWLM) correlator and pass
it on to the host as a connection attribute correlator for use with the Application Response Measurement
(ARM) APIs. This correlator can be sent to the host at any time after a connection is made using the
following method in the AS400JDBCConnection class:
setDB2eWLMCorrelator
public void setDB2eWLMCorrelator(byte[] bytes)
throws SQLException
Sets the eWLM Correlator. It is assumed a valid correlator value is used. If the value is null, all
ARM/eWLM implementation will be turned off. eWLM correlators require i5/OS V5R3 or later servers.
This request is ignored when running to V5R2 or earlier servers.
Parameters:
v bytes: The eWLM correlator value
v SQLException: See the Class SQLException information at the Sun Microsystems, Inc. Web site.
For information about enhanced JDBC functions for previous releases, see V5R2 enhancements to IBM
Toolbox for Java JDBC support.
UTF-8 and UTF-16 support
UTF-8 data is stored in a character field with a CCSID of 1208. A UTF-8 character is a variable
number of bytes (one, two, three, or four) for a non-combining character, and any number of
bytes for a combining character. The length specified for a character field is the maximum
number of bytes the field can contain. You can tag the following data types with a UTF-8 1208
CCSID:
v Fixed length character (CHAR)
v Variable length character (VARCHAR)
v Character LOB (CLOB)
UTF-16 data is stored in a graphic field with a CCSID of 1200. A UTF-16 character can be either
two or four bytes (that is, Surrogate) in length for a non-combining character and any number of
bytes for a combining character. The length specified for a graphic data field is the maximum
number of two bytes characters the field can contain. You can tag the following data types with a
UTF-16 1200 CCSID:
v Fixed length graphic (GRAPHIC)
v Variable length graphic (VARGRAPHIC)
v Double-byte character LOB (DBCLOB)
Binary and Varbinary support
The BINARY and VARBINARY data types are similar to the CHAR and VARCHAR data types,
but contain binary data rather than character data. BINARY fields have a fixed length.
VARBINARY fields are of varying length. The BINARY and VARBINARY data types have the
following characteristics:
v The coded character set identifier (CCSID) for binary types is 65535
v In assignments and comparisons, binary data types are compatible only with other binary data
types (BINARY, VARBINARY, and BLOB)
v The pad character for binary data types is x'00' instead of the blank character
v In situations requiring trailing characters to be stripped to prevent truncation errors, x'00'
characters are stripped instead of trailing blanks
v When comparing binary data types, for two fields to be equal both the data and the lengths
must be the same. Trailing zeros are not ignored in comparisons
Be aware that accessing parameters by their index results in better performance than accessing
them by their name. You can also specify parameter names to set in CallableStatement. Where
you might have used the following in CallableStatement:
CallableStatement cs = connection.prepareCall( CALL MYPGM (?) );
cs.setString( 1 );
To use these new methods, you need JDBC 3.0 or later and the Java 2 Platform, version 1.4 (either
the Standard or the Enterprise Edition).
Retrieve auto-generated keys
The getGeneratedKeys() method on AS400JDBCStatement retrieves any auto-generated keys
created as a result of executing that Statement object. When the Statement object does not
generate any keys, an empty ResultSet object is returned. Currently the server supports returning
only one auto-generated key (the key for the last inserted row). The following example shows
how you might insert a value into a table then get the auto-generated key:
Statement s =
statement.executeQuery("INSERT INTO MYSCHOOL/MYSTUDENTS (FIRSTNAME) VALUES (’JOHN’");
ResultSet rs = s.getGeneratedKeys();
// Currently the server supports returning only one auto-generated
// key -- the key for the last inserted row.
rs.next();
String autoGeneratedKey = rs.getString(1);
// Use the auto-generated key, for example, as the primary key in another table
To retrieve auto-generated keys, you need JDBC 3.0 or later, and the Java 2 Platform, version 1.4
(either the Standard or the Enterprise Edition). Retrieving auto-generated keys also requires
connecting to a V5R2 or later version of i5/OS.
Improved performance when running SQL insert statements in a batch
Performance of running SQL insert statements in a batch has been improved. Run SQL statements
in a batch by using the different addBatch() methods available in AS400JDBCStatement,
AS400JDBCPreparedStatement, and AS400JDBCCallableStatement. Enhanced batch support affects
only insert requests. For example, using batch support to process several inserts involves only
one pass to the server. However, using batch support to process an insert, and update, and a
delete sends each request individually.
To use batch support, you need JDBC 2.0 or later and the Java 2 Platform, version 1.2 (either the
Standard or the Enterprise Edition).
Enhanced support for ResultSet.getRow()
Previously, the IBM Toolbox for Java JDBC driver was limited in its support for the getRow()
method in ResultSet. Specifically, using ResultSet.last(), ResultSet.afterLast(), and
ResultSet.absolute() with a negative value made the current row number not available. The
previous restrictions are lifted, making this method fully functional.
Using mixed case in column names
IBM Toolbox for Java methods must match either column names provided by the user or column
names provided by the application with the names that are on the database table. In either case,
when a column name is not enclosed in quotes, IBM Toolbox for Java changes the name to
The following tables list the different connection properties that are recognized by this driver. Some of
these properties affect performance and others are server job attributes. The tables organize the properties
into the following categories:
v “General properties”
v “Server properties” on page 327
v “Format properties” on page 331
v “Performance properties” on page 331
v “Sort properties” on page 336
v “Other properties” on page 336
General properties
General properties are system attributes that specify the user, password, and whether a prompt is
necessary to connect to the server.
Server properties
Server properties specify attributes that govern transactions, libraries, and databases.
"read committed"
"repeatable
read"
"serializable"
"translate hex" Specifies how hexadecimal literals are no "character" "character"
interpreted. (Interpret
hexadecimal
literals as
character data)
"binary"
(Interpret
hexadecimal
literals as
binary data)
"true Specifies whether the connection should use no "true" (Use true "false"
autocommit" true auto commit support. True autocommit autocommit.)
means that autocommit is on and is
"false" (Do not
running under a isolation level other than
use true
*NONE. By default, the driver handles
autocommit.)
autocommit by running under the server
isolation level of *NONE.
"xa loosely Specifies whether lock sharing is allowed no "0" = Locks "0"
coupled support" for loosely coupled transaction branches. cannot be
Note: This setting is ignored when running shared
to IBM i 5.3 or earlier.
"1" = Locks can
be shared
Format properties specify date and time formats, date and decimal separators, and table naming
conventions used within SQL statements.
Performance properties
Performance properties are attributes that include caching, data conversion, data compression, and
prefetching that affect performance.
Sort properties specify how the server performs stores and performs sorts.
Other properties
Other properties are those properties not easily categorized. These properties determine which JDBC
driver is used, and specify options related to level of database access, bidirectional string type, data
truncation and so on.
Other
property Description Required Choices Default
"access" Specifies the level of database access for the no "all" (all SQL "all"
connection. statements allowed)
"read call" (SELECT
and CALL
statements allowed)
"read only" (SELECT
statements only)
| "autocommit Specifies whether to throw an SQLException no "true" "false"
| exception" when Connection.commit() or
"false"
| Connection.rollback() is called if autocommit is
| enabled.
Related reference:
“Registering the JDBC driver” on page 78
Before using JDBC to access data in a server database file, you need to register the IBM Toolbox for Java
JDBC driver with the DriverManager.
Note: When a default SQL schema is specified on the URL and the libraries property is not used, the
default SQL schema is appended before the current library list
In the cases where a SQL type is not supported, the JDBC driver substitutes a similar SQL type.
The following table lists the SQL types that are not supported and the SQL type that JDBC driver
substitutes for each.
Proxy Support
IBM Toolbox for Java includes proxy support for some classes. Proxy support is the processing that IBM
Toolbox for Java needs to carry out a task on a Java virtual machine (JVM) when the application is on a
different JVM.
The proxy classes reside in jt400Proxy.jar, which ships with the rest of the IBM Toolbox for Java. The
proxy classes, like the other classes in the IBM Toolbox for Java, comprise a set of platform independent
Java classes that can run on any computer with a Java virtual machine. The proxy classes dispatch all
method calls to a server application, or proxy server. The full IBM Toolbox for Java classes are on the
proxy server. When a client uses a proxy class, the request is transferred to the proxy server which
creates and administers the real IBM Toolbox for Java objects.
Figure 1 shows how the standard and proxy client connect to the server. The proxy server can be the IBM
i server that contains the data.
An application that uses proxy support performs more slowly than if it uses standard IBM Toolbox for
Java classes due to the extra communication needed to support the smaller proxy classes. Applications
that make fewer method calls have less performance degradation.
Before proxy support, the classes containing the public interface, all the classes needed to process a
request, and the application itself ran on the same JVM. When using proxy support, the public interface
must be with the application, but classes for processing requests can run on a different JVM. Proxy
support does not change the public interface. The same program can run with either the proxy version of
IBM Toolbox for Java or the standard version.
The goal of the multiple-tier, proxy scenario is to make the public interface JAR file as small as possible,
so that downloading it from an applet takes less time. When you use the proxy classes, you don't need to
install the entire IBM Toolbox for Java on the client. Instead, use AS400JarMaker on the jt400Proxy.jar file
to include only the required components, which makes the JAR file as small as possible.
Figure 2 compares the size of the proxy JAR files with the standard JAR files:
Figure 2: Size comparison of proxy JAR files and standard JAR files
An additional benefit is that proxy support requires you to have fewer ports open through a firewall.
With standard IBM Toolbox for Java, you must have multiple ports open. This is because each IBM
Toolbox for Java service uses a different port to communicate with the server. For example, Command
call uses a different port than JDBC, which uses a different port than print, and so on. You must allow
each of these ports through the firewall. However, when using proxy support, all the data flows through
the same port.
Two options are available for running via a proxy: standard proxy and HTTP tunneling:
IBM Toolbox for Java uses the proxy server name to determine if standard proxy or tunneling proxy is
being used:
v For standard proxy, just use the server name. For example:
com.ibm.as400.access.AS400.proxyServer=myServer
v For tunneling, use a URL to force the proxy client to use tunneling. For example:
com.ibm.as400.access.AS400.proxyServer=http://myServer
When running standard proxy, a socket connection exists between the client and server. If that connection
fails, the server cleans up resources associated with that client.
When using HTTP tunneling, using the HTTP protocol makes proxy connectionless. That is, a new
connection is made for each data flow. Because the protocol is connectionless, the server does not know if
the client application is no longer active. Consequently, the server does not know when to clean up
resources. The tunneling server solves this problem by using a thread to clean up resources at a
predetermined interval (which is based on a timeout value).
At the end of the predetermined interval, the thread runs and cleans up resources that have not been
used lately. Two system properties govern the thread:
v com.ibm.as400.access.TunnelProxyServer. clientCleanupInterval is how often, in seconds, the cleanup
thread runs. The default is every two hours.
v com.ibm.as400.access.TunnelProxyServer. clientLifetime is how long, in seconds, a resource can be idle
before it is cleaned up. The default is 30 minutes.
To use the proxy server implementation of the IBM Toolbox for Java classes, complete the following steps:
1. Run AS400ToolboxJarMaker on jt400Proxy.jar to discard classes that you do not need. This step is
optional but recommended.
2. Deliver jt400Proxy.jar to the client. For Java applets, you may be able to download the JAR file from
the HTML server.
3. Determine what server you will use for the proxy server.
v For Java applications, the proxy server can be any computer.
v For Java applets, the proxy server must be running on the same computer as the HTTP server.
4. Ensure that you have put jt400.jar in the CLASSPATH on the server.
5. Start the proxy server or use the proxy servlet:
v For standard proxy, start the proxy server by using the following command:
java com.ibm.as400.access.ProxyServer
v For tunneling proxy, configure your HTTP server to use the proxy servlet. The servlet class name is
com.ibm.as400.access.TunnelProxyServer and it is contained in jt400.jar.
6. On the client, set a system property to identify the proxy server. IBM Toolbox for Java uses this
system property to determine if standard proxy or tunneling proxy is being used.
When you want to work with both the proxy classes and classes not in jt400Proxy.jar, you can refer to
jt400.jar instead of jt400Proxy.jar. jt400Proxy.jar is a subset of the jt400.jar and, therefore, all of the proxy
classes are contained in the jt400.jar file.
The following are three specific examples for using a proxy server with the steps listed above.
v Running a Java application using proxy support
v Running a Java applet using proxy support
v Running a Java application using tunneling proxy support.
Some IBM Toolbox for Java classes are enabled to work with the proxy server application. These include
the following:
v JDBC
v Record-level access
v Integrated file system
v Print
v Data Queues
v Command Call
v Program Call
v Service Program Call
v User space
v Data area
v AS400 class
v SecureAS400 class
Other classes are not supported at this time by jt400Proxy. Also, integrated file system permissions are
not functional using only the proxy JAR file. However, you can use the JarMaker class to include these
classes from the jt400.jar file.
Note: The proxy client code creates the correct servlet URL by concatenating "servlet" and the servlet
name to the server name. In this example, it converts http://psMachineName to
http://psMachineName/servlet/TunnelProxyServer
For more information about JSSE, see the Sun JSSE Web site .
JSSE provides the ability to perform server authentication, enable secure communications, and encrypt
data. Using JSSE, you can provide for secure data exchange between clients and servers that run any
application protocol (for example, HTTP and FTP) over TCP/IP.
If you have previously used sslight, you should migrate to JSSE. As of IBM i 5.4, JSSE is the only package
supported, and sslight is no longer shipped.
ToolboxME requirements
Your workstation, wireless device, and server must meet certain requirements (listed below) for
developing and running IBM Toolbox for Java 2 Micro Edition applications.
Although Toolbox ME is considered a part of IBM Toolbox for Java, it is not included in the licensed
product. ToolboxME (jt400Micro.jar) is included in the open source version of Toolbox for Java, called
JTOpen. You must separately download and set up ToolboxME, which is contained in JTOpen.
Requirements
To use ToolboxME, your workstation, Tier0 wireless device, and server must meet the following
requirements.
Workstation requirements
The only requirement for running ToolboxME applications on your Tier0 device is using a Java virtual
machine for wireless devices.
Server requirements
You can download ToolboxME from the IBM Toolbox for Java/JTOpen Web site that also offers
additional information about setting up ToolboxME.
How you set up ToolboxME is different for the Tier0 device, the development workstation, and the
server:
v Build an application for your wireless device (using jt400Micro.jar) and install the application as
documented by the device manufacturer.
v Make sure that the IBM i Host Servers are started on the server that contains the target data.
v Make sure that the system that you want to run the MEServer has access to jt400.jar.
The J2ME is the implementation of the Java 2 standard that provides Java runtime environments for Tier0
wireless devices, like personal digital assistants (PDAs) and cell phones. IBM Toolbox for Java 2 Micro
Edition adheres to this standard.
Tier0 devices
Wireless devices, such as PDAs and cell phones, that use wireless technology to connect to computers
and networks are referred to as Tier0 devices. This name is based on the common 3-tier application
model. The 3-tier model describes a distributed program that is organized into three major parts, each of
which resides on a different computer or network:
v The third tier is the database and related programs that reside on a server, often a different server than
the second tier. This tier provides the information and the access to that information that the other tiers
use to perform work.
v The second tier is the business logic, which typically resides on a different computer, typically a server,
shared on a network.
v The first tier is generally the part of the application that resides on a workstation, including the user
interface.
Tier0 devices are often small, portable, resource-constrained devices, like PDAs and cell phones. Tier0
devices substitute for or complement the functionality of devices on the first tier.
A profile represents a set of APIs built on an existing configuration that target a specific type of device or
operating system. The MIDP, built on the CLDC, provides a standard runtime environment that enables
you to dynamically deploy applications and services to Tier0 devices.
v IBM J9 virtual machine, part of the IBM WebSphere® Everyplace Micro Environment
v MIDP
Related information
You can use any one of a number of development tools created to help you build wireless Java
applications. For a brief list of such tools, see Related information for IBM Toolbox for Java.
To learn more about and to download wireless device simulators and emulators, consult the Web site for
the device or operating system on which you want your application to run.
ToolboxME classes
The com.ibm.as400.micro package provides the classes necessary to write applications that enable your
Tier0 devices to access server data and resources.
Note: To use IBM Toolbox for Java 2 Micro Edition classes, you must separately download and set up the
ToolboxME component.
MEServer class
Use the IBM Toolbox for Java MEServer class to fulfill requests from your Tier0 client application that
uses the IBM Toolbox for Java 2 Micro Edition JAR file. The MEServer creates IBM Toolbox for Java
objects and invokes methods on them on behalf of the client application.
Note: To use ToolboxMe classes, you must separately download and set up the ToolboxME component.
For more information, see Downloading and setting up ToolboxME.
MEServer will not start if another server is already active on the specified port.
Related information:
MEServer Javadoc
“Tier0 devices” on page 350
AS400 class
The AS400 class in the micro package (com.ibm.as400.micro.AS400) provides a modified subset of the
functions available in the AS400 class in the access package (com.ibm.as400.access.AS400). Use the IBM
Toolbox for Java 2 Micro Edition AS400 class to sign on the system from a Tier0 device.
Note: To use ToolboxME classes, you must separately download and set up the ToolboxME component.
For more information, see Downloading and setting up ToolboxME.
The connection to the MEServer is made implicitly. For example, after you create an AS400 object, you
can use the run() method in CommandCall to automatically perform connect(). In other words, you do
not explicitly call the connect() method unless you want to control when the connection is established.
The following example shows how to use the AS400 class to sign on to on the system:
AS400 system = new AS400("mySystem", "myUserid", "myPwd", "myMEServer");
try
{
system.connect();
}
catch (Exception e)
{
// Handle the exception
}
// Done with the system object.
system.disconnect();
AS400 Javadoc
“AS400 class” on page 22
The IBM Toolbox for Java AS400 class manages a set of socket connections to the server jobs on server
and sign-on behavior for the server, including prompting the user for sign-on information, password
caching, and default user management.
“Tier0 devices” on page 350
Note: To use IBM Toolbox for Java 2 Micro Edition classes, you must separately download and set up the
ToolboxME component.
The CommandCall run() method requires a String (the command you want to run) and returns any
messages resulting from running the command as a String. If the command completes but does not
generate any messages, the run() method returns an empty String array.
To read or write entries, you need to supply the name of the server where the data queue resides and the
fully qualified integrated file system path name of the data queue. When no entries are available, reading
an entry returns a null value.
The following example demonstrates how to use the DataQueue class to read entries from and write
entries to an IBM i data queue:
AS400 system = new AS400("mySystem", "myUserid", "myPwd", "myMEServer");
try
{
// Write to the Data Queue.
DataQueue.write(system, "/QSYS.LIB/FRED.LIB/MYDTAQ.DTAQ", "some text");
Note: To use IBM Toolbox for Java 2 Micro Edition classes, you must separately download and set up the
ToolboxME component. For more information, see “ToolboxME requirements” on page 6.
To use the ProgramCall.run() method, you must provide the following parameters:
v The server on which you want to run the program
v The name of the “Program Call Markup Language” on page 377 document
v The name of the program that you want to run
v The hashtable that contains the name of one or more program parameters that you want to set and the
associated values
ProgramCall uses PCML to describe the input and output parameters for the program. The PCML file
must be on the same machine as the MEServer, and you must have an entry for the directory that
contains the PCML file in the CLASSPATH of that machine.
You must register each PCML document with the MEServer. Registering a PCML document is telling the
MEServer which PCML-defined program you want to run. Register the PCML document either during
runtime or when you start the MEServer.
For more information about the hashtable that contains program parameters or how to register a PCML
document, see the ToolboxME ProgramCall Javadoc. For more information about PCML, see “Program
Call Markup Language” on page 377.
The following example shows how to use the ProgramCall class to use your Tier 0 device to run a
program on a server:
// Call programs.
AS400 system = new AS400("mySystem", "myUserid", "myPwd", "myMEServer");
String pcmlName = "qsyrusri.pcml"; // The PCML document describing the program we want to use.
String apiName = "qsyrusri";
try
{
valuesToGet = ProgramCall.run(system, pcmlName, apiName,
parametersToSet, parametersToGet);
JdbcMe classes
The IBM Toolbox for Java 2 Micro Edition classes provide JDBC support, including support for the
java.sql package. The classes are meant to be used in a program that runs on a Tier 0 device.
The following sections discuss accessing and using data and describe what is in JdbcMe.
When using a Tier0 device to access and update data, you want it to work exactly like if you were sitting
at a system in your office. However, much of the development in Tier0 devices focuses on data
synchronization. Using data synchronization, each Tier0 device has a copy of specific data from the main
database. Periodically, users synchronize the data on each device with the main database.
Data synchronization does not work well with data that is dynamic. Working with dynamic data requires
quick access to up-to-date data. Having to wait to access synchronized data is not an option for many
businesses. Plus, the software and hardware demands for the servers and devices to main synchronous
data can be significant.
To help solve the problems inherent in the data synchronization model, the JdbcMe classes in ToolboxME
enable you to perform live updates and access the main database, but still allow offline data storage.
Your application can have access to valuable offline data without sacrificing the ability for to have live
updates immediately become part of the main database. This middle ground approach provides the
benefits of both the synchronous data model and the live data model.
What is in JdbcMe
By definition, a driver of any kind for a Tier0 device must be very small. The JDBC API, however, is very
large. The JdbcMe classes had to be extremely small but still support enough of the JDBC interfaces so
that Tier0 devices might use it to perform meaningful work.
The JdbcMeConnection class provides a subset of functions available in the IBM Toolbox for Java
AS400JDBCConnection class. Use JdbcMeConnection to enable your Tier0 device to access DB2 Universal
Database™ (UDB) databases on the host server.
Note: To use IBM Toolbox for Java 2 Micro Edition classes, you must separately download and set up the
ToolboxME component. For more information, see ToolboxME requirements and installation.
Use JdbcMeDriver.getConnection() to connect to the server database. The getConnection() method takes a
uniform resource locator (URL) string as an argument, the user ID, and password. The JDBC driver
manager on the host server attempts to locate a driver that can connect to the database that is
represented by the URL. JdbcMeDriver uses the following syntax for the URL:
jdbc:as400://server-name/default-schema;meserver=<server>[:port];[other properties];
Note: The previous syntax example is on two lines so you can easily see and print it. Normally, the URL
appears on one line with no breaks or extra spaces.
You must specify a server name, or JdbcMeDriver throws an exception. The default SQL schema is
optional. If you do not specify a port, the JdbcMeDriver uses port 3470. Also, you can set a variety of
JDBC properties within the URL. To set properties, use the following syntax:
name1=value1;name2=value2;...
Example: Connecting to the server database without specifying a default SQL schema, a port, or JDBC
properties
Example: Connecting to the server database when specifying the default SQL schema and JDBC
properties
The example specifies properties (including user ID and password) by using a uniform resource locator
(URL):
The example uses the close() method on the connecting object to disconnect from the server:
c.close();
JdbcMeConnection Javadoc
AS400JDBCConnection Javadoc
“Tier0 devices” on page 350
JdbcMeDriver class:
Use JdbcMeDriver in your Tier0 client application to run simple SQL statements that have no parameters
and obtain ResultSets that the statements produce. The JdbcMeDriver class provides a subset of functions
available in the IBM Toolbox for Java AS400JDBCStatement class.
Note: To use IBM Toolbox for Java 2 Micro Edition classes, you must separately download and set up the
ToolboxME component. For more information, see “Downloading and setting up ToolboxME” on
page 350.
You don't explicitly register the JdbcMeDriver; instead the driver property you specify on the URL in the
JdbcMeConnection.getConnection() method determines the driver. For example, to load the IBM
Developer Kit for Java JDBC driver (called the 'native' driver), use code similar to the following:
Connection c = JdbcMeDriver.getConnection(
"jdbc:as400://mysystem.myworld.com;meserver=myMeSrvr;driver=native;user=auser;password=apassword");
The IBM Toolbox for Java JDBC driver does not require an AS400 object as an input parameter like the
other IBM Toolbox for Java classes that get data from a server. However, an AS400 object is used
internally and you must explicitly provide a user ID and password. Provide the user ID and password
either in the URL or by way of the parameters on the getConnection() method.
Result sets:
The IBM Toolbox for Java 2 Micro Edition result set classes are JdbcMeLiveResultSet,
JdbcMeOfflineResultSet, JdbcMeResultSetMetaData.
Note: To use ToolboxME classes, you must separately download and set up the ToolboxME component.
For more information, see Downloading and setting up ToolboxME.
The JdbcMeLiveResultSet class provides a subset of functions available in the IBM Toolbox for Java
AS400JDBCResultSet class. Use JdbcMeLiveResultSet in your Tier0 client application to access a table of
data that is generated by running a query.
JdbcMeLiveResultSet retrieves the table rows in sequence. Within a row, you can access column values in
any order. JdbcMeLiveResultSet includes methods that enable you to perform the following actions:
v Retrieve data of various types that are stored in the result set
v Move the cursor to the row you specify (previous row, current row, next row, and so on)
v Insert, update, and delete rows
v Update columns (using String and int values)
v Retrieve the ResultSetMetaData object that describes the columns in the result set
A cursor, which is an internal pointer, is used by a result set to point the row in the result set that is
being accessed by the Java program. JDBC 2.0 provides additional methods for accessing specific
positions within a database. These are the available scrollable cursor positions:
v absolute
v first
v last
v moveToCurrentRow
v moveToInsertRow
v previous
v relative
Scrolling capabilities
If a result set is created by executing a statement, you can move (scroll) backward (last-to-first) or
forward (first-to-last) through the rows in a table.
A result set that supports this movement is called a scrollable result set. Scrollable result sets also support
relative and absolute positioning. Relative positioning allows you to move to a row in the result set by
specifying a position that is relative to the current row. Absolute positioning allows you to move directly
to a row by specifying its position in the result set.
With JDBC 2.0, you have two additional scrolling capabilities available to use when working with the
ResultSet class: scroll-insensitive and scroll-sensitive result sets.
A scroll-insensitive result set is not typically sensitive to changes that are made while it is open, while the
scroll-sensitive result set is sensitive to changes. The IBM Toolbox for Java JDBC driver does not support
scroll-insensitive result sets.
In your application, you can use result sets that use either read-only concurrency (no updates can be
made to the data) or updatable concurrency (allows updates to the data and may use database write
locks to control access to the same data item by different transactions). In an updatable result set, rows
can be updated, inserted, and deleted.
See the method summary in the Javadoc for a complete listing of the update methods available in
JdbcMeResultSet.
JdbcMeOfflineResultSet class
The JdbcMeOfflineResultSet class provides a subset of functions available in the IBM Toolbox for Java
AS400JDBCResultSet class. Use JdbcMeOfflineResultSet in in your Tier0 client application to access a table
of data that is generated by running a query.
Use the JdbcMeOfflineResultSet class to work with data that resides on your Tier0 device. The data that
resides on the device might already reside there or you might have put it there by calling
JdbcMeStatement.executeToOfflineData() method. the executeToOfflineData() method downloads and
stores to the device all of the data that satisfies the query. You can then use JdbcMeOfflineResultSet class
to access the stored data.
JdbcMeOfflineResultSet includes methods that enable you to perform the following actions:
v Retrieve data of various types that are stored in the result set
v Move the cursor to the row you specify (previous row, current row, next row, and so on)
v Insert, update, and delete rows
v Update columns (using String and int values)
v Retrieve the ResultSetMetaData object that describes the columns in the result set
JdbcMeResultSetMetaData class
The JdbcMeResultSetMetaData class provides a subset of functions available in the IBM Toolbox for Java
AS400JDBCResultSetMetaData class. Use JdbcMeResultSetMetaData in your Tier0 client application to
determine the types and properties of the columns in a JdbcMeLiveResultSet or JdbcMeOfflineResultSet.
JdbcMeOfflineData class:
The JdbcMeOfflineData class is an offline data repository meant to be used on a Tier0 device. The
repository is generic, regardless of the profile and Java virtual machine that you are using.
Note: To use IBM Toolbox for Java 2 Micro Edition classes, you must separately download and set up the
ToolboxME component. For more information, see Downloading and setting up ToolboxME.
The JdbcMeOfflineData class provides methods that enable you to perform the following functions:
v Create an offline data repository
v Open an existing repository
v Get the number of records in the repository
v Get and delete individual records
v Update records
For an example of using the JdbcMeOfflineData class, see the following example:
“Example: Using ToolboxME, MIDP, and IBM Toolbox for Java” on page 704
Related reference:
“Concepts important for using ToolboxME” on page 350
Before you begin developing IBM Toolbox for Java 2 Micro Edition Java applications, you need to
understand the following concepts and standards that govern such development.
Related information:
JdbcMeOfflineData Javadoc
JdbcMeStatement class:
Use JdbcMeStatement in your Tier0 client application to run simple SQL statements that have no
parameters and obtain ResultSets that the statements produce. The JdbcMeStatement class provides a
subset of functions available in the IBM Toolbox for Java AS400JDBCStatement class.
Note: To use IBM Toolbox for Java 2 Micro Edition classes, you must separately download and set up the
ToolboxME component. For more information, see Downloading and setting up ToolboxME.
The example program uses the K Virtual Machine (KVM) and allows the user to perform any JDBC
query. The user can then perform JDBC actions (next, previous, close, commit, and rollback) against the
result of the query.
Before you begin creating any of the ToolboxME examples, make sure that your environment meets the
ToolboxME requirements.
To create the ToolboxME example program for your Tier0 device, complete the following steps:
1. Copy the Java code for the ToolboxME example, called JdbcDemo.java.
2. In your chosen text or Java editor, change the portions of the code as indicated in the program
comments and save the file with the name JdbcDemo.java.
Note: Consider using a wireless application development tool, which makes it easier to complete the
remaining steps. Some wireless application development tools may compile, preverify, and
build your program in a single step, then automatically run it in an emulator.
3. Compile JdbcDemo.java, making sure you point to the JAR file that contains the KVM classes.
4. Preverify the executable file, either by using your wireless application development tool or by using
the Java preverify command.
5. Build the appropriate type of executable file for the operating system of your Tier0 device. For
example, for the Palm OS, you build a file called JdbcDemo.prc.
6. Test the program. If you have installed an emulator, you can test the program and see what it will
look like by running it in the emulator.
Note: If you test the program on your wireless device and you do not use a wireless application
development tool, make sure that you preinstall your chosen Java virtual machine or MIDP on
the device.
See ToolboxME concepts for related information about concepts, wireless application development tools,
and emulators.
To run the ToolboxME example program on your Tier0 device, complete the following tasks:
v Load the executable file to the device, using the instructions provided by your Tier0 device
manufacturer.
v Start the MEServer
v Run the JdbcDemo program on your Tier0 device by clicking the JdbcDemo icon.
To copy the source code, simply use your mouse to select all the Java code below, then right-click and
select Copy. To paste the code into your editor, create a blank document in the editor, right-click the
blank document and select Paste. Make sure to save the new document with the name JdbcDemo.java.
After you create the .java file, return to the instructions for creating and running the example program.
Note: Read the Code example disclaimer for important legal information.
class DemoConstants
{
// These constants are actually used mainly by the demo
// for the JDBC driver. The Jdbc and JDBC application
// creator IDs ( http://www.palmos.com/dev )
// are reserved at palm computing.
public static final int demoAppID = 0x4a444243; // JDBC
// Make the dbCreator something else so that the
// user can actually see the Palm DB seperately from
// the JdbcDemo application.
public static final int dbCreator = 0x4a444231; // JDB1
public static final int dbType = 0x4a444231; // JDB1
}
/**
* Little configuration dialog box to display the
* current connections/statements, the
* URL being used, user id and password
*/
class ConfigurationDialog extends Dialog implements ActionListener
{
TextField data;
ConfigurationDialog(Frame w)
{
super(w, "Configuration");
// Ok button.
Panel panel = new Panel();
Button button = new Button("Ok");
button.addActionListener(this);
panel.add(button);
add("South", panel);
pack();
}
/**
* Little configuration dialog box to display the
* current connections/statements, the
* URL being used, user id and password
// Ok button.
Panel panel = new Panel();
Button button = new Button("Ok");
button.addActionListener(this);
panel.add(button);
button = new Button("Cancel");
button.addActionListener(this);
panel.add(button);
add("South", panel);
pack();
}
/**
* Determine the action performed.
**/
public void actionPerformed(ActionEvent e)
{
int choice = task.getSelectedIndex();
setVisible(false);
if (e.getActionCommand().equals("Ok"))
{
if (theListener != null)
{
ActionEvent ev = new ActionEvent(this,
ActionEvent.ACTION_PERFORMED,
task.getItem(choice));
theListener.actionPerformed(ev);
}
task = null;
}
else
{
// No-op
}
}
}
/**
* The JdbcPanel is the main panel of the application.
* It displays the current connection and statement
* at the top.
* A text field for entering SQL statements next.
* A Results field for displaying each column of data
* or results.
* An task list and a ’go’ button so that different
* tasks can be tried.
// JDBC objects.
java.sql.Connection connObject = null;
Statement stmtObject = null;
ResultSet rs = null;
ResultSetMetaData rsmd = null;
/**
* Build the GUI.
*/
public JdbcPanel()
{
// The JDBC URL
// Make sure to edit the following line so that it correctly specifies the
// the MEServer and the server to which you want to connect.
url = "jdbc:as400://mySystem;user=myUidl;password=myPwd;meserver=myMEServer;";
setLayout(new BorderLayout());
add("Center", pall);
add("South", p4);
}
/**
* Do a task based on whichever task is
* currently selected in the task list.
*/
public void actionPerformed(ActionEvent e)
{
if (e.getSource() instanceof MultiChoiceDialog)
{
String cmd = e.getActionCommand();
processExtendedCommand(cmd);
return;
}
switch (task.getSelectedIndex())
{
case TASK_EXIT:
System.exit(0);
break;
case TASK_NEW:
JdbcPanel.this.goNewItems();
break;
case TASK_PREV:
JdbcPanel.this.goPrevRow();
break;
JdbcPanel.this.goExecute();
break;
case TASK_CONFIG:
JdbcPanel.this.goConfigure();
break;
case TASK_CLOSE:
JdbcPanel.this.goClose();
break;
case TASK_TOPALMDB:
if (connObject == null || stmtObject == null)
JdbcPanel.this.goNewItems();
JdbcPanel.this.goResultsToPalmDB();
break;
case TASK_FROMPALMDB:
JdbcPanel.this.goQueryFromPalmDB();
break;
case TASK_SETAUTOCOMMIT:
JdbcPanel.this.goSetAutocommit();
break;
case TASK_SETISOLATION:
JdbcPanel.this.goSetIsolation();
break;
case TASK_COMMIT:
JdbcPanel.this.goTransact(true);
break;
case TASK_ROLLBACK:
JdbcPanel.this.goTransact(false);
break;
default :
{
Dialog dialog = new FeedbackDialog(JdbcDemo.mainFrame, "Error", "Task not implemented");
dialog.show();
dialog = null;
}
}
}
/**
* Perform commit or rollback processing.
*/
public void goTransact(boolean commit)
{
if (connObject == null)
{
FeedbackDialog dialog = new FeedbackDialog(JdbcDemo.mainFrame,
"Skip",
"Connection not allocated");
dialog.show();
dialog = null;
return;
}
try
{
if (commit)
connObject.commit();
else
connObject.rollback();
}
catch (Exception e)
{
JdbcDemo.mainFrame.exceptionFeedback(e);
}
}
/**
* Prompt the user for setting the autocommit value
* Real work handled by the actionPerformed method
* calling processExtendedCommand().
*/
public void goSetAutocommit()
{
if (connObject == null)
{
FeedbackDialog dialog = new FeedbackDialog(JdbcDemo.mainFrame,
"Skip",
"Connection not allocated");
dialog.show();
dialog = null;
return;
}
try
{
/**
* Prompt the user for setting the isolation level,
* real work handled by the actionPerformed() method
* calling processExtendedCommand().
*/
public void goSetIsolation()
{
if (connObject == null)
{
FeedbackDialog dialog = new FeedbackDialog(JdbcDemo.mainFrame,
"Skip",
"Connection not allocated");
dialog.show();
dialog = null;
return;
}
try
{
int level = connObject.getTransactionIsolation();
String currentLevel;
switch (level)
{
case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED:
currentLevel = "Now: read uncommitted";
break;
case java.sql.Connection.TRANSACTION_READ_COMMITTED:
currentLevel = "Now: read committed";
break;
case java.sql.Connection.TRANSACTION_REPEATABLE_READ:
currentLevel = "Now: repeatable read";
break;
case java.sql.Connection.TRANSACTION_SERIALIZABLE:
currentLevel = "Now: serializable";
break;
default : {
currentLevel = "error";
}
}
Dialog dialog = new MultiChoiceDialog(JdbcDemo.mainFrame,
"Set Isolation Level",
currentLevel,
new String[]{ "read uncommitted",
"read committed",
"repeatable read",
"serializable"},
this);
dialog.show();
/**
* Create a new connection or statement.
* Only one connection and statement is currently
* supported.
*/
public void goNewItems()
{
if (connObject != null || stmtObject != null)
{
FeedbackDialog dialog = new FeedbackDialog(JdbcDemo.mainFrame,
"Skip",
"Conn/Stmt already allocated");
dialog.show();
dialog = null;
}
if (connObject == null)
{
try
{
connObject = DriverManager.getConnection(url);
//connection.setText(Integer.toString(((JdbcMeConnection)connObject).getId()));
connection.repaint();
}
catch (Exception e)
{
JdbcDemo.mainFrame.exceptionFeedback(e);
return;
}
}
if (stmtObject == null)
{
try
{
try
{
stmtObject = connObject.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
}
catch (Exception e)
{
// Try again... DB2 NT version 6.1 doesn’t support
// Scollable result sets, so we’ll assume other
// JDBC 2.0 databases don’t either. We’ll attempt
// to create another.
try
{
stmtObject = connObject.createStatement();
}
catch (Exception ex)
{
// If the second try failed, rethrow the
// first exception. Its probably
// a more meaninful error.
throw e;
}
FeedbackDialog dialog = new FeedbackDialog(JdbcDemo.mainFrame,
"2nd try worked",
"Non-scrollable result set");
dialog.show();
statement.repaint();
}
catch (Exception e)
{
JdbcDemo.mainFrame.exceptionFeedback(e);
return;
}
}
}
/**
* Close the statement and connection.
**/
public void goClose()
{
// Close the statement.
if (stmtObject != null)
{
if (rs != null)
{
try
{
rs.close();
}
catch (Exception e)
{
}
rs = null;
rsmd = null;
}
try
{
stmtObject.close();
}
catch (Exception e)
{
}
stmtObject = null;
statement.setText("None");
statement.repaint();
}
/**
* Execute the specified query.
**/
public void goExecute()
{
// Get the currently selected statement.
try
{
if (rs != null)
rs.close();
rs = null;
rsmd = null;
boolean results = stmtObject.execute(sql.getText());
if (results)
{
rs = stmtObject.getResultSet();
rsmd = rs.getMetaData();
// Show the first row
goNextRow();
}
else
{
data.removeAll();
data.add(stmtObject.getUpdateCount() + " rows updated");
data.repaint();
}
}
catch (Exception e)
{
JdbcDemo.mainFrame.exceptionFeedback(e);
}
}
/**
* Move to the next row in the result set.
**/
public void goNextRow()
{
try
{
if (rs == null || rsmd == null)
return;
/**
* Move to the previous row in the result set.
**/
public void goPrevRow()
{
try
{
if (rs == null || rsmd == null)
return;
/**
* Perform a query and store the results in the local devices database
**/
public void goResultsToPalmDB()
{
try
{
if (stmtObject == null)
{
FeedbackDialog dialog = new FeedbackDialog(JdbcDemo.mainFrame, "Skip", "No Statement");
dialog.show();
dialog = null;
return;
}
boolean results =
((JdbcMeStatement)stmtObject).executeToOfflineData(sql.getText(),
"JdbcResultSet",
DemoConstants.dbCreator,
DemoConstants.dbType);
if (!results)
{
FeedbackDialog dialog = new FeedbackDialog(JdbcDemo.mainFrame, "No Data", "Not a query");
/**
* Perform a query from the database that resides on the palm device.
**/
public void goQueryFromPalmDB()
{
try
{
if (rs != null)
{
rs.close();
rs = null;
}
rs = new JdbcMeOfflineResultSet ("JdbcResultSet",
DemoConstants.dbCreator,
DemoConstants.dbType);
rsmd = rs.getMetaData();
// If we want to debug some output, this
// method can be used to dump the contents
// of the PalmDB represented by the result set
// (Uses System.out so its mostly useful in
// the Palm emulator when debugging your
// applications.
// ((JdbcMeOfflineResultSet)rs).dumpDB(true);
/**
* Demo Constructor
**/
public JdbcDemo()
{
super("Jdbc Demo");
setLayout(new BorderLayout());
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
setSize(200,300);
pack();
}
/**
* Main method.
**/
public static void main(String args[])
{
try
{
mainFrame = new JdbcDemo();
mainFrame.show();
mainFrame.jdbcPanel.goConfigure();
}
catch (Exception e)
{
System.exit(1);
}
}
}
Use the following links to view selected example source files or to download all the example source files
required to build the working example wireless applications:
For more information about how to build a ToolboxME application, see “Creating and running a
ToolboxME program” on page 362.
For more information about MIDP, see “Mobile Information Device Profile (MIDP)” on page 351.
Before you begin compiling the source and building the executable files for your Tier0 device, see the
following for more information:
v “ToolboxME requirements” on page 6
v “Downloading and setting up ToolboxME” on page 350
PCML is based upon the Extensible Markup Language (XML), a tag syntax you use to describe the input
and output parameters for server programs. PCML enables you to define tags that fully describe server
programs called by your Java application.
Note: If you are interested in or are already using PCML, consider using Extensible Program Call
Markup Language (XPCML). XPCML enhances the functionality and usability of PCML by offering
support for XML schemas. For more information about IBM Toolbox for Java XML components,
including XPCML, see Extensible Markup Language components.
A huge benefit of PCML is that it allows you to write less code. Ordinarily, extra code is needed to
connect, retrieve, and translate data between a server and IBM Toolbox for Java objects. However, by
using PCML, your calls to the server with the IBM Toolbox for Java classes are automatically handled.
PCML class objects are generated from the PCML tags and help minimize the amount of code you need
to write in order to call server programs from your application.
In addition, in order to parse PCML at run-time, the CLASSPATH for the application must include an
XML parser. The XML parser must extend class org.apache.xerces.parsers.SAXParser.
Note: If you preserialize the PCML file, you do not need to include an XML parser in the application
CLASSPATH to run the application.
Related reference:
“Workstation requirements for IBM Toolbox for Java” on page 7
Ensure that your workstation meets the following requirements.
“XML parser and XSLT processor” on page 417
Some IBM Toolbox for Java packages or functions require that, at run-time, you have an Extensible
Markup Language (XML) parser or Extensible Stylesheet Language Transformations (XSLT) processor in
your CLASSPATH environment variable.
Depending on your design process, you must write one or more PCML source files where you describe
the interfaces to the IBM i programs that will be called by your Java application. Refer to PCML syntax
for a detailed description of the language.
Then your Java application interacts with the PCML classes (in this case, the ProgramCallDocument
class). The ProgramCallDocument class uses your PCML source file to pass information between your
Java application and the IBM i programs. Figure 1 illustrates how Java applications interact with the
PCML classes.
After the ProgramCallDocument class has been created, the application program uses the
ProgramCallDocument class's methods to retrieve the necessary information from the server through the
IBM i distributed program call (DPC) server.
To improve run-time performance, the ProgramCallDocument class can be serialized during your product
build time. The ProgramCallDocument is then constructed using the serialized file. In this case, the XML
parser is not used at run-time. Refer to Using serialized PCML files.
Your Java application uses PCML by constructing a ProgramCallDocument object with a reference to the
PCML source file. The ProgramCallDocument object considers the PCML source file to be a Java resource.
The java application finds the PCML source file by using the Java CLASSPATH
The ProgramCallDocument object will look for your PCML source in a file called myPcmlDoc.pcml.
Notice that the .pcml extension is not specified on the constructor.
If you are developing a Java application in a Java package, you can package-qualify the name of the
PCML resource:
To improve run-time performance, you can use a serialized PCML file. A serialized PCML file contains
serialized Java objects representing the PCML. The objects that are serialized are the same objects that are
created when you construct the ProgramCallDocument from a source file as described above.
Using serialized PCML files improves performance because the XML parser is not needed at run-time to
process the PCML tags.
If your PCML is in a source file named myDoc.pcml, the result of serialization is a file named
myDoc.pcml.ser.
The ProgramCallDocument constructor will first try to find a serialized PCML file named
myPcmlDoc.pcml.ser in the com.mycompany.mypackage package in the Java CLASSPATH. If a serialized
PCML file does not exist, the constructor will then try to find a PCML source file named
myPcmlDoc.pcml in the com.mycompany.mypackage package in the Java CLASSPATH. If a PCML source
file does not exist, an exception is thrown.
Qualified names
Your Java application uses ProgramCallDocument.setValue() to set input values for the IBM i program
being called. Likewise, your application uses ProgramCallDocument.getValue() to retrieve output values
from the IBM i program.
When accessing values from the ProgramCallDocument class, you must specify the fully qualified name
of the document element or <data> tag. The qualified name is a concatenation of the names of all the
containing tags with each name separated by a period.
For example, given the following PCML source, the qualified name for the "nbrPolygons" item is
"polytest.parm1.nbrPolygons". The qualified name for accessing the "x" value for one of the points in one
of the polygons is "polytest.parm1.polygon.point.x".
If any one of the elements needed to make the qualified name is unnamed, all descendants of that
element do not have a qualified name. Any elements that do not have a qualified name cannot be
accessed from your Java program.
<pcml version="1.0">
<program name="polytest" path="/QSYS.lib/MYLIB.lib/POLYTEST.pgm">
<!-- Parameter 1 contains a count of polygons along with an array of polygons -->
<struct name="parm1" usage="inputoutput">
Any <data> or <struct> element can be defined as an array using the count attribute. Or, a <data> or
<struct> element can be contained within another <struct> element that is defined as an array.
Furthermore, a <data> or <struct> element can be in a multidimensional array if more than one
containing element has a count attribute specified.
In order for your application to set or get values defined as an array or defined within an array, you
must specify the array index for each dimension of the array. The array indices are passed as an array of
int values. Given the source for the array of polygons shown above, the following Java code can be used
to retrieve the information about the polygons:
ProgramCallDocument polytest; // Initialized elsewhere
Integer nbrPolygons, nbrPoints, pointX, pointY;
nbrPolygons = (Integer) polytest.getValue("polytest.parm1.nbrPolygons");
System.out.println("Number of polygons:" + nbrPolygons);
indices = new int[2];
for (int polygon = 0; polygon < nbrPolygons.intValue(); polygon++)
{
indices[0] = polygon;
nbrPoints = (Integer) polytest.getValue("polytest.parm1.polygon.nbrPoints", indices );
System.out.println(" Number of points:" + nbrPoints);
Debugging
When you use PCML to call programs with complex data structures, it is easy to have errors in your
PCML that result in exceptions from the ProgramCallDocument class. If the errors are related to
incorrectly describing offsets and lengths of data, the exceptions can be difficult to debug.
Use the following method from the Trace class to turn on PCML tracing:
Trace.setTraceOn(true); // Turn on tracing function.
Trace.setTracePCMLOn(true); // Turn on PCML tracing.
Note: All public methods in the PcmlMessageLog class, including tracing, were deprecated in V5R2.
The Trace setFileName() method enables you to send the following types of information to specific log
files or, by default, to System.out:
In the above example, the dump shows the seventh parameter has 10 bytes of data set to "*USRPRF ".
v For output parameters, following the hexadecimal dump is a description of how the data has been
interpreted for the document. (The following example was altered to allow for width restrictions)
/QSYS.lib/QGY.lib/QGYOLOBJ.pgm[2]
Offset : 0....... 4....... 8....... C....... 0....... 4....... 8....... C.......
0...4...8...C...0...4...8...C...
0 : 0000000A 0000000A 00000001 00000068 D7F0F9F9 F0F1F1F5 F1F4F2F6 F2F5F400
*................P09901151426254.*
20 : 00000410 00000001 00000000 00000000 00000000 00000000 00000000 00000000
*................................*
40 : 00000000 00000000 00000000 00000000
*................ *
Reading data -- Offset: 0 Length: 4 Name: "qgyolobj.listInfo.totalRcds"
Byte data: 0000000A
Reading data -- Offset: 4 Length: 4 Name: "qgyolobj.listInfo.rcdsReturned"
Byte data: 0000000A
Reading data -- Offset: 8 Length: 4 Name: "qgyolobj.listInfo.rqsHandle"
Byte data: 00000001
Reading data -- Offset: c Length: 4 Name: "qgyolobj.listInfo.rcdLength"
Byte data: 00000068
Reading data -- Offset: 10 Length: 1 Name: "qgyolobj.listInfo.infoComplete"
Byte data: D7
Reading data -- Offset: 11 Length: 7 Name: "qgyolobj.listInfo.dateCreated"
Byte data: F0F9F9F0F1F1F5
Reading data -- Offset: 18 Length: 6 Name: "qgyolobj.listInfo.timeCreated"
Byte data: F1F4F2F6F2F5
Reading data -- Offset: 1e Length: 1 Name: "qgyolobj.listInfo.listStatus"
Byte data: F4
Reading data -- Offset: 1f Length: 1 Name: "qgyolobj.listInfo.[8]"
Byte data: 00
Reading data -- Offset: 20 Length: 4 Name: "qgyolobj.listInfo.lengthOfInfo"
Byte data: 00000410
Reading data -- Offset: 24 Length: 4 Name: "qgyolobj.listInfo.firstRecord"
Byte data: 00000001
Reading data -- Offset: 28 Length: 40 Name: "qgyolobj.listInfo.[11]"
Byte data: 00000000000000000000000000000000000000000000000000000000000000000000000000000000
The above messages can be very helpful in diagnosing cases where the output data coming from the IBM
i program does not match the PCML source. This can easily occur when you are using dynamic lengths
and offsets.
PCML syntax
PCML consists of the following tags, each of which has its own attribute tags.
v The program tag begins and ends code that describes one program
v The struct tag defines a named structure which can be specified as an argument to a program or as a
field within another named structure. A structure tag contains a data or a structure tag for each field in
the structure.
In the following example the PCML syntax describes one program with one category of data and some
isolated data.
<program>
<struct>
<data> </data>
</struct>
<data> </data>
</program>
The PCML program tag can be expanded with the following elements.
<program name="name"
[ entrypoint="entry-point-name" ]
[ epccsid="ccsid" ]
[ path="path-name" ]
[ parseorder="name-list" ]
[ returnvalue="{ void | integer }" ]
[ threadsafe="{ true | false }" ]>
</program>
The following table lists the program tag attributes. Each entry includes the attribute name, the possible
valid values, and a description of the attribute.
The PCML struct tag can be expanded with the following elements.
<struct name="name"
[ count="{number | data-name }"]
[ maxvrm="version-string" ]
[ minvrm="version-string" ]
[ offset="{number | data-name }" ]
[ offsetfrom="{number | data-name | struct-name }" ]
[ outputsize="{number | data-name }" ]
[ usage="{ inherit | input | output | inputoutput }" ]>
</struct>
The following table lists the struct tag attributes. Each entry includes the attribute name, the possible
valid values, and a description of the attribute.
Specifying offsets
Some programs return information with a fixed structure followed by one or more variable length fields
or structures. In this case, the location of a variable length element is typically specified as an offset or
displacement within the parameter.
An offset is the distance in bytes from a the beginning of the parameters to the beginning of a field or
structure. A displacement is the distance in bytes from the beginning of one structure to the beginning of
another structure.
For displacements, since the distance is from the beginning of another structure, you specify the name of
the structure to which the offset is relative. The following is an example of an displacement from the
beginning of a named structure:
<pcml ="1.0">
<program name="myprog" path="/QSYS.lib/MYLIB.lib/MYPROG.pgm">
<!-- receiver variable contains an object -->
<struct name="receiver" usage="output" >
<data name="objectName" type="char" length="10" />
<data name="libraryName" type="char" length="10" />
<data name="objectType" type="char" length="10" />
<struct name="pathInfo" usage="output" outputsize="2048" >
<data name="pathType" type="int" length="4" />
<data name="offsetToPathName" type="int" length="4" />
<data name="lengthOfPathName" type="int" length="4" />
<data name="pathName" type="char" length="lengthOfPathName"
offset="offsetToPathName" offsetfrom="pathInfo"/>
</struct>
</struct>
</program>
</pcml>
Attributes enclosed in brackets, [], indicate that the attribute is optional. If you specify an optional
attribute, do not include the brackets in your source. Some attribute values are shown as a list of choices
enclosed in braces, {}, with possible choices separated by vertical bars, |. When you specify one of these
attributes, do not include the braces in your source and only specify one of the choices shown.
<data type="{ char | int | packed | zoned | float | byte | struct | date | time | timestamp }"
[ bidistringtype="{ ST4 | ST5 | ST6 | ST7 | ST8 | ST9 | ST10 | ST11 | DEFAULT }"]
[ ccsid="{ number | data-name }" ]
[ chartype="{ onebyte | twobyte }"]
[ count="{ number | data-name }" ]
[ init="string" ]
[ length="{ number | data-name }" ]
[ maxvrm="version-string" ]
[ minvrm="version-string" ]
[ name="name" ]
[ offset="{ number | data-name }" ]
[ offsetfrom="{ number | data-name | struct-name }" ]
[ outputsize="{ number | data-name | struct-name }" ]
[ passby= "{ reference | value }" ]
[ precision="number" ]
[ struct="struct-name" ]
[ trim="{ right | left | both | none }" ]
[ usage="{ inherit | input | output | inputoutput }" ]>
[ dateformat="{ MDY | DMY | YMD | JUL | ISO | USA | EUR| JIS | CYMD | CMDY | CDMY | LONGJUL | MY | YM | MYY | YMM }" ]>
The following table lists the data tag attributes. Each entry includes the attribute name, the possible valid
values, and a description of the attribute.
data-name where data-name defines the If the count attribute is omitted, the
name of a <data> element within the element is not defined as an array,
PCML document that will contain, at although it may be contained within
runtime, the number of elements in another element that is defined as an
the array. The data-name specified can array.
be a fully qualified name or a name
that is relative to the current element.
In either case, the name must
reference a <data> element that is
defined with type="int". See
Resolving Relative Names for more
information about how relative
names are resolved.
Specifying offsets
Some programs return information with a fixed structure followed by one or more variable length fields
or structures. In this case, the location of a variable length element is typically specified as an offset or
displacement within the parameter.
An offset is the distance in bytes from the beginning of the parameters to the beginnings of a field or
structure. A displacement is the distance in bytes from the beginning of one structure to the beginning of
another structure.
For offsets, since the distance is from the beginning of the parameter, you must specify offsetfrom="0".
The following is an example of an offset from the beginning of the parameter:
<pcml version="1.0">
<program name="myprog" path="/QSYS.lib/MYLIB.lib/MYPROG.pgm">
<!-- receiver variable contains a path -->
<struct name="receiver" usage="output" outputsize="2048">
<data name="pathType" type="int" length="4" />
<data name="offsetToPathName" type="int" length="4" />
<data name="lengthOfPathName" type="int" length="4" />
<data name="pathName" type="char" length="lengthOfPathName"
offset="offsetToPathName" offsetfrom="0"/>
</struct>
</program>
</pcml>
For displacements, since the distance is from the beginning of another structure, you specify the name of
the structure to which the offset is relative. The following is an example of an displacement from the
beginning of a named structure:
<pcml version="1.0">
<program name="myprog" path="/QSYS.lib/MYLIB.lib/MYPROG.pgm">
<!-- receiver variable contains an object -->
<struct name="receiver" usage="output" >
<data name="objectName" type="char" length="10" />
<data name="libraryName" type="char" length="10" />
Values for the length and precision attributes are different for different data types.
The following table lists each data type with a description of the possible values for length and precision.
Several attributes allow you to specify the name of another element, or tag, within the document as the
attribute value. The name specified can be a name that is relative to the current tag.
Names are resolved by seeing if the name can be resolved as a child or descendent of the tag containing
the current tag. If the name cannot be resolved at this level, the search continues with the next highest
containing tag. This resolution must eventually result in a match of a tag that is contained by either the
<pcml> tag or the <rfml> tag, in which case the name is considered to be an absolute name, not a
relative name.
You can incorporate the panels into your Java applications, applets, or System i Navigator plug-ins. The
panels may contain data obtained from the system, or data obtained from another source such as a file in
the local file system or a program on the network.
The Resource Script Converter converts Windows resource scripts into an XML representation that is
usable by Java programs. With the Resource Script Converter you can process Windows resource scripts
(RC files) from your existing Windows dialogs and menus. These converted files can then be edited with
the GUI Builder. Property sheets and wizards can be made from RC files using the resource script
converter along with the GUI Builder.
Underlying these two tools is a new technology called the Panel Definition Markup Language, or
PDML. PDML is based on the Extensible Markup Language (XML) and defines a platform-independent
language for describing the layout of user interface elements. Once your panels are defined in PDML,
you can use the runtime API provided by the Graphical Toolbox to display them. The API displays your
panels by interpreting the PDML and rendering your user interface using the Java Foundation Classes.
Note: Using PDML requires that you run version 1.4 or later of the Java Runtime Environment.
The Graphical Toolbox provides you with two tools and, therefore, two ways of automating the creation
of your user interfaces. You can use the GUI Builder to quickly and easily create new panels from scratch,
GUI Builder
Two windows are displayed when you invoke the GUI Builder for the first time, as shown in Figure 1:
Use the File Builder window to create and edit your PDML files.
Use the Properties window to view or change the properties of the currently selected control.
The panel being edited is displayed in the Panel Builder window. Figure 5 shows how the windows work
together:
The Resource Script Converter consists of a two-paned tabbed dialog. On the Convert pane you specify
the name of the Microsoft or VisualAge for Windows RC file that is to be converted to PDML. You can
specify the name of the target PDML file and associated Java resource bundle that will contain the
translated strings for the panels. In addition, you can request that online help skeletons be generated for
the panels, generate Java source code skeletons for the objects that supply data to the panels, and
serialize the panel definitions for improved performance at runtime. The Converter's online help provides
a detailed description of each input field on the Convert pane.
The IBM Toolbox for Java RFML component enables your Java applications to use RFML documents to
specify and manipulate fields within certain kinds of records.
RFML documents, called RFML source files, represent a useful subset of the data description specification
(DDS) data types defined for IBM i physical and logical files. You can use RFML documents to manage
the information in the following:
v File records
v Data queue entries
v User spaces
v Arbitrary data buffers
Note: For more information about using DDS to describe data attributes, see the DDS Reference.
RFML closely resembles Program Call Markup Language (PCML), another XML extension that is
supported by IBM Toolbox for Java. RFML is neither a subset nor a superset of PCML, but rather a kind
of sibling language that adds a few new elements and attributes and omits others.
PCML provides an XML-oriented alternative to using the ProgramCall and ProgramParameter classes.
Similarly, RFML provides a user-friendly, easily maintainable alternative to the Record, RecordFormat,
and FieldDescription classes.
Related information:
Data description specifications
In addition, in order to parse RFML at run time, the CLASSPATH for the application must include an
XML parser. The XML parser must extend class org.apache.xerces.parsers.SAXParser. For more
information, see “XML parser and XSLT processor” on page 417.
Note: RFML has the same parser requirements as PCML. As with PCML, if you preserialize the RFML
file, you do not need to include an XML parser in the application CLASSPATH to run the
application.
Related reference:
“Workstation requirements for IBM Toolbox for Java” on page 7
Ensure that your workstation meets the following requirements.
Example: Using RFML compared to using IBM Toolbox for Java Record classes
This example illustrates the differences between using RFML and using the IBM Toolbox for Java Record
classes.
Using the traditional Record classes, you interweave the data format specifications with the business logic
of your application. Adding, changing, or deleting a field means that you must edit and recompile your
Java code. However, using RFML isolates the data format specifications into RFML source files that are
entirely separate from the business logic. Accommodating field changes means modifying the RFML file,
often without having to change or recompile your Java application.
The example assumes that your application deals with customer records, which you have defined in an
RFML source file and named qcustcdt.rfml. The source file represents the fields that compose each
customer record.
The listing below shows how a Java application might interpret a customer record using the IBM Toolbox
for Java Record, RecordFormat, and FieldDescription classes:
// Buffer containing the binary representation of one record of information.
byte[] bytes;
By comparison, here is how the same record might be interpreted using RFML.
The Java code to interpret the contents of the customer data record using RFML might look like this:
RecordFormatDocument class
The RecordFormatDocument class enables your Java programs to convert between RFML representations
of data and Record and RecordFormat objects for use with other IBM Toolbox for Java components.
RecordFormatDocument class
The RecordFormatDocument class represents an RFML source file, and it provides methods that allow
your Java program to perform the following actions:
v Compose RFML source files from Record objects, RecordFormat objects, and byte arrays
v Generate Record objects, RecordFormat objects, and byte arrays that represent the information that the
RecordFormatDocument object contains
v Get and set the values of different objects and data types
v Generate XML (RFML) that represents the data that the RecordFormatDocument object contains
v Serialize the RFML source file that the RecordFormatDocument object represents
For more information about the available methods, see the Javadoc method summary for the
RecordFormatDocument class.
Using the RecordFormatDocument class with other IBM Toolbox for Java classes
Use the RecordFormatDocument class with the following IBM Toolbox for Java classes:
410 IBM i: Programming IBM Toolbox for Java
v Record-oriented classes, which include the record-level access file classes (AS400File, SequentialFile,
and KeyedFile) that read, manipulate, and write Record objects. This category also includes the
LineDataRecordWriter class.
v Byte-oriented classes, which include certain DataQueue, UserSpace, and IFSFile classes that read and
write a byte-array of data at a time.
Do not use RecordFormatDocument class with the following IBM Toolbox for Java classes, which read
and write data in forms that RecordFormatDocument does not handle:
v The DataArea classes because the read and write methods deal only with String, boolean, and
BigDecimal data types.
v IFSTextFileInputStream and IFSTextFileOutputStream because these read and write methods deal only
with String.
v JDBC classes because RFML focuses only on data described by the IBM i data description specification
(DDS).
Related information:
RecordFormatDocument Javadoc
Because RFML is based on PCML, the syntax is familiar to PCML users. Because RFML is an XML
extension, RFML source files are easy to read and simple to create. For example, you can create an RFML
source file by using a simple text editor. Also, RFML source files reveal the structure of the data in a way
that is easier to understand than in a programming language like Java.
The RFML example Using RFML compared to using IBM Toolbox for Java Record classes includes an
example RFML source file.
RFML DTD
The RFML document type definition (DTD) defines valid RFML elements and syntax. To ensure that an
XML parser can validate your RFML source file at runtime, declare the RFML DTD in the source file:
<!DOCTYPE rfml SYSTEM "rfml.dtd">
RFML syntax
The RFML DTD defines tags, each of which has its own attribute tags. You use the RFML tags to declare
and define the elements in your RFML files.
In the following example, RFML syntax describes one record format and one structure:
<rfml>
<recordformat>
<data> </data>
</recordformat>
<struct>
<data> </data>
</struct>
</rfml>
This is the RFML DTD. Note that the version is 4.0. The RFML DTD resides in the jt400.jar file
(com/ibm/as400/data/rfml.dtd).
<!--
Record Format Markup Language (RFML) Document Type Definition.
<!-- Note: RFML does not support nested struct declarations. -->
<!-- All struct elements are direct children of the root node. -->
<!ELEMENT struct (data)+>
<!ATTLIST struct
name ID #REQUIRED
>
The RFML data tag defines a field within a record format or structure.
Listed below are the attributes for the data tag. Attributes enclosed in brackets, [], indicate that the
attribute is optional. If you specify an optional attribute, do not include the brackets in your source. Some
attribute values are shown as a list of choices enclosed in braces, {}, with possible choices separated by
vertical bars, |. When you specify one of these attributes, do not include the braces in your source and
only specify one of the choices shown.
<data type="{ char | int | packed | zoned | float | byte | struct }" ]
[ bidistringtype="{ ST4 | ST5 | ST6 | ST7 | ST8 | ST9 | ST10 | ST11 | DEFAULT }"]
[ ccsid="{ number | data-name }" ]
[ count="{ number | data-name }" ]
[ init="string" ]
[ length="{ number | data-name }" ]
[ name="name" ]
[ precision="number" ]
[ struct="struct-name" ]>
</data>
The following table lists the data tag attributes. Each entry includes the attribute name, the possible valid
values, and a description of the attribute.
Related information:
BidiStringType Javadoc
The rfml tag begins and ends the RFML source file that describes the data format.
Listed below are the attributes for the rfml tag. Attributes enclosed in brackets, [], indicate that the
attribute is optional. If you specify an optional attribute, do not include the brackets in your source.
<rfml version="version-string"
[ ccsid="number" ]>
</rfml>
The following table lists the rfml tag attributes. Each entry includes the attribute name, the possible valid
values, and a description of the attribute.
The RFML recordformat tag defines a record format, which contains either data elements or references to
structure elements.
Listed below are the attributes for the recordformat tag. Attributes enclosed in brackets, [], indicate that
the attribute is optional. If you specify an optional attribute, do not include the brackets in your source.
<recordformat name="name"
[ description="description" ]>
</recordformat>
The following table lists the recordformat tag attributes. Each entry includes the attribute name, the
possible valid values, and a description of the attribute.
The RFML struct tag defines a named structure that you can reuse within the RFML source file. The
structure contains a data tag for each field in the structure.
Listed below are the attributes for the struct tag. Attributes enclosed in brackets, [], indicate that the
attribute is optional. If you specify an optional attribute, do not include the brackets in your source.
<struct name="name">
</struct>
The following table lists the struct tag attributes. Each entry includes the attribute name, the possible
valid values, and a description of the attribute.
For more information about which IBM Toolbox for Java packages and functions require an XML parser
or XSLT processor, see the following page:
XML parser
If the package or function requires an XML parser, you must include an XML parser in the CLASSPATH
at run-time. The XML parser must meet the following requirements:
v Be JAXP-compliant
v Extend class org.apache.xerces.parsers.SAXParser
v Support full schema validation
Note: The parser only needs to support full schema validation if use intend to use XPCML. If you are
only using PCML, full schema validation is not necessary.
The Java 2 Software Developer Kit (J2SDK), version 1.4, includes a suitable XML parser. If you use a
previous version of J2SDK, use any of the following methods to access a suitable XML parser:
v Use x4j400.jar (an IBM version of the Xerces XML parser from Apache)
v Download the Xerces XML parser from the Apache Web site
v Use any compatible XML parser in the /QIBM/ProdData/OS400/xml/lib directory on your system
Note: Consider using the latest versions of the parsers that reside in /QIBM/ProdData/OS400/xml/lib. For
example, xmlapis11.jar and xerces411.jar are both fully validating parsers.
You can use these parsers on your server or copy them to a workstation.
Note: Any XML parser that meets the requirements for running XPCML can run PCML and RFML. Keep
in mind that XPCML does not support serialization.
XSLT processor
If the package or function requires an XSLT processor, you must include an XSLT processor in the
CLASSPATH at run-time. The XSLT processor must meet the following requirements:
v Be JAXP-compliant
v Contain the class javax.xml.transform.Transformer
The Java 2 Software Developer Kit (J2SDK), version 1.4, includes a suitable XSLT processor. If you use a
previous version of J2SDK, use any of the following methods to access a suitable XSLT processor:
v Use xslparser.jar (an IBM version of the Xalan XSLT processor from Apache)
v Download the Xalan XSLT processor from the Apache Web site
v Use any compatible XSLT processor in the /QIBM/ProdData/OS400/xml/lib directory on your system
You can use these processors on your system or copy them to a workstation.
XPCML uses an XML schema to define program parameter types; PCML uses a data type definition
(DTD). At parse time, the XML parser validates data values entered as parameters against the appropriate
parameters as defined in the schema. Data types exist for parameters of many types: strings, integers,
longs, and so on. This ability to specify and pass values for program parameters is a significant
improvement over PCML. In PCML, you can verify values for parameters only after parsing the PCML
document. Additionally, verifying parameter values in PCML often requires coding your application to
perform the validation.
XPCML also provides the capability to retrieve program call results as XPCML. In PCML, you obtain
program call results by calling one of the getValue methods of the ProgramCallDocument class after you
make the call to the program. In XPCML, you can use the getValue methods, but you can also have your
XPCML call a generateXPCML method, which returns the results of a program call as XPCML.
XPCML is extensible which means you can define new parameter types that extend those specified by the
XPCML schema. Condensing XPCML extends the XPCML schema to create new data type definitions that
simplify and improve the readability and usability of your XPCML documents.
“Workstation requirements for running IBM Toolbox for Java applications” on page 7
In addition, using XPCML includes requirements for the XML schema file, XML parser, and Extensible
Stylesheet Language Transformation (XSLT) processor:
Your XPCML documents must know the location of the file that contains the schema. The default schema
for IBM Toolbox for Java is xpcml.xsd, which resides within the jt400.jar file.
To use the default schema, extract xpcml.xsd from jt400.jar, then place the file in a suitable location. The
following procedure shows one way that you can extract the .xsd file on a workstation.
Note: If you do not run the previous command from the directory that contains jt400.jar, you can specify
a fully qualified path to jt400.jar.
You can place the default schema file (or any schema file) in any directory. The only requirement is that
you specify the location of the schema file by using the xsi:noNamespaceSchemaLocation attribute in the
<xpcml> tag.
You can specify the location of the schema as a file path or as a URL.
Note: Although the following examples use xpcml.xsd as the schema file, you can specify any schema
that extends xpcml.xsd.
v To specify the same directory as the XPCML file, use xsi:noNamespaceSchemaLocation='xpcml.xsd'
v To specify a fully qualified path: xsi:noNamespaceSchemaLocation='c:\myDir\xpcml.xsd'
v To specify a URL: xsi:noNamespaceSchemaLocation='http://myServer/xpcml.xsd'
To see an HTML version of the xpcml.xsd file, see the following page:
At run-time, you must include an XML parser and an XSLT processor in your CLASSPATH environment
variable. For more information, see the following page:
For more information about the XPCML schema and syntax, see the following pages:
XPCML differs from PCML in several ways, but one major difference is that XPCML allows you to
specify the values of input parameters within the XPCML source file.
PCML allows you to use the init attribute of the <data> tag to specify the initial value for a data element
in the PCML source. However, using PCML to specify values has the following limitations:
v You cannot use the init attribute to set array values
v Validation of the init value occurs only after parsing the PCML document
To specify array values in PCML, you must first read in and parse the PCML document, then perform a
series of calls to ProgramCallDocument.setValue().
Using XPCML makes it easier to specify values of single elements and arrays:
v Specify values for both scalar and array elements in the XPCML source file
v Validate the specified array values at parse time
The following simple comparisons indicate ways in which XPCML differs from PCML. Each example
defines a program call for an IBM i program.
The following examples call an IBM i program called prog2 and define parm1 as an array of string
parameters. Note the functionality of XPCML:
v Initializes the value of each element in the array
v Specifies the input values as element content that a fully validating XML parser can verify
You can take advantage of this XPCML functionality without writing any Java code.
PCML cannot match the XPCML performance. PCML cannot initialize the value of each element in the
array. PCML cannot validate the init values at parse time. To match the functionality of XPCML, you
would have to read in and parse the PCML document, then code your Java application to set the value
for each array element. You would also have to write code to validate the parameters.
To make it easier to display and print, some lines of this HTML version of xpcml.xsd wrap to a second
line. The same lines in the source xsd file appear on a single line.
For more information about using the xpcml.xsd file, see Requirements for using XPCML.
Note: Read the Code example disclaimer for important legal information.
<?xml version="1.0" encoding="UTF-8"?>
<!--///////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: xpcml.xsd
//
// The source code contained herein is licensed under the IBM Public License
<xs:schema xmlns:xs=’http://www.w3.org/2001/XMLSchema’>
<xs:annotation>
<xs:documentation>
Schema for xpcml (eXtended Program Call Markup Language).
</xs:documentation>
</xs:annotation>
<xs:element name="xpcml">
<xs:complexType>
<xs:sequence>
<xs:element ref="structOrProgram" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="version" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="4.0"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
<!-- All the different kinds of program parameters that we understand. -->
<xs:group name="programParameter">
<xs:choice>
<xs:element ref="stringParmGroup"/>
<xs:element ref="stringParmArrayGroup"/>
<xs:element ref="intParmGroup"/>
<xs:element ref="intParmArrayGroup"/>
<xs:element ref="unsignedIntParmGroup"/>
<xs:element ref="unsignedIntParmArrayGroup"/>
<xs:element ref="shortParmGroup"/>
<xs:element ref="shortParmArrayGroup"/>
<xs:element ref="unsignedShortParmGroup"/>
<xs:element ref="unsignedShortParmArrayGroup"/>
<xs:element ref="longParmGroup"/>
<xs:element ref="longParmArrayGroup"/>
<xs:element ref="zonedDecimalParmGroup"/>
<xs:element ref="zonedDecimalParmArrayGroup"/>
<xs:element ref="packedDecimalParmGroup"/>
<xs:element ref="packedDecimalParmArrayGroup"/>
<xs:element ref="floatParmGroup"/>
<xs:element ref="floatParmArrayGroup"/>
<xs:element ref="doubleParmGroup"/>
<xs:element ref="doubleParmArrayGroup"/>
<xs:element ref="hexBinaryParmGroup"/>
<xs:element ref="hexBinaryParmArrayGroup"/>
<xs:element ref="structParmGroup"/>
<xs:element ref="structParmArrayGroup"/>
<xs:element ref="structArrayGroup"/>
<xs:element ref="struct"/>
</xs:choice>
</xs:group>
<xs:complexType name="stringElementType">
<xs:simpleContent>
<xs:extension base="xs:string">
<!-- The index into the array. -->
<xs:attribute name="index" type="xs:nonNegativeInteger" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="intElementType">
<xs:simpleContent>
<xs:extension base="xs:int">
<xs:attribute name="index" type="xs:nonNegativeInteger" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="unsignedIntElementType">
<xs:simpleContent>
<xs:extension base="xs:unsignedInt">
<xs:attribute name="index" type="xs:nonNegativeInteger" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="shortElementType">
<xs:simpleContent>
<xs:extension base="xs:short">
<xs:attribute name="index" type="xs:nonNegativeInteger" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="unsignedShortElementType">
<xs:simpleContent>
<xs:extension base="xs:unsignedShort">
<xs:attribute name="index" type="xs:nonNegativeInteger" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="zonedDecimalElementType">
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="index" type="xs:nonNegativeInteger" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="packedDecimalElementType">
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="index" type="xs:nonNegativeInteger" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="floatElementType">
<xs:simpleContent>
<xs:extension base="xs:float">
<xs:attribute name="index" type="xs:nonNegativeInteger" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="doubleElementType">
<xs:simpleContent>
<xs:extension base="xs:double">
<xs:attribute name="index" type="xs:nonNegativeInteger" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="hexBinaryElementType">
<xs:simpleContent>
<xs:extension base="xs:hexBinary">
<xs:attribute name="index" type="xs:nonNegativeInteger" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="structElementType">
<xs:complexContent>
<xs:extension base="structureParmArray">
<xs:attribute name="index" type="xs:nonNegativeInteger" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!-- Attributes that are common to all data field types. -->
<xs:attributeGroup name="commonParmAttrs">
<!-- Specifies whether this is an input, output, or input-output parameter (’usage’ in PCML). -->
<!-- The default value if none is specified is ’inherit’. -->
<xs:attribute name="passDirection" type="passDirectionType"/>
<!-- Specifies whether the parameter is passed by reference or value (’passby’ in PCML). -->
<!-- The default value if none is specified is ’reference’. -->
<xs:attribute name="passMode" type="passModeType" />
<!-- The offset to the element within an output parameter. -->
<!-- The default value if none is specified is 0. -->
<xs:attribute name="offset" type="xs:string" />
<!-- The base location from which the ’offset’ attribute is relative. -->
<xs:attribute name="offsetFrom" type="xs:string" />
<!-- The number of bytes to reserve for output data for the element. -->
<xs:attribute name="outputSize" type="xs:string" />
<!-- The lowest version of IBM i to which this field applies. -->
<!-- If not specified, we assume this field applies to all versions. -->
<xs:attribute name="minvrm" type="string10" />
<!-- The highest version of IBM i to which this field applies. -->
<xs:simpleType name="passDirectionType">
<xs:restriction base="xs:string">
<xs:enumeration value="in"/>
<xs:enumeration value="inout"/>
<xs:enumeration value="out"/>
<xs:enumeration value="inherit"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="passModeType">
<xs:restriction base="xs:string">
<xs:enumeration value="value"/>
<xs:enumeration value="reference"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="charType">
<xs:restriction base="xs:string">
<xs:enumeration value="onebyte"/>
<xs:enumeration value="twobyte"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="trimType">
<xs:restriction base="xs:string">
<xs:enumeration value="none"/>
<xs:enumeration value="left"/>
<xs:enumeration value="right"/>
<xs:enumeration value="both"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="returnValueType">
<xs:restriction base="xs:string">
<xs:enumeration value="void"/>
<xs:enumeration value="integer"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="structureParmArray">
<xs:sequence>
<xs:group ref="structureParm" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="string50"/>
<xs:attribute name="passDirection" type="passDirectionType"/>
<xs:attribute name="offset" type="xs:string" />
<xs:attribute name="offsetFrom" type="xs:string" />
<xs:complexType name="zonedDecimal">
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="totalDigits" type="xs:positiveInteger" />
<xs:attribute name="fractionDigits" type="xs:nonNegativeInteger" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="packedDecimal">
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="totalDigits" type="xs:positiveInteger" />
<xs:attribute name="fractionDigits" type="xs:nonNegativeInteger" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="structureFieldArray">
<!-- Attributes that are common to all data field types. -->
<xs:attributeGroup name="commonFieldAttrs">
<xs:attribute name="name" type="string50"/>
<xs:attribute name="columnHeading1" type="string20"/>
<xs:attribute name="columnHeading2" type="string20"/>
<xs:attribute name="columnHeading3" type="string20"/>
<xs:attribute name="description" type="string50"/>
<xs:attribute name="defaultValue" type="xs:string"/><!-- Max length of string is 65535 characters. -->
<xs:attribute name="nullable" type="xs:boolean"/>
<xs:attribute name="isEmptyString" type="xs:boolean"/><!-- Indicate this is an empty string. -->
</xs:attributeGroup>
<xs:simpleType name="ccsidType">
<xs:restriction base="xs:nonNegativeInteger">
<xs:maxInclusive value="65535"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="string10">
<xs:restriction base="xs:string">
<xs:maxLength value="10"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="string20">
<xs:restriction base="xs:string">
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="string50">
<xs:restriction base="xs:string">
<xs:maxLength value="50"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
XPCML syntax:
The XPCML schema defines several element tags, and each element tag contains attribute tags.
The following table lists the different elements that you can declare and define in your XPCML source
files. Each entry in the first column links to the appropriate section of the XPCML schema.
The XPCML schema defines several element tags, and each element tag contains attribute tags. The
following table lists and describes the different attributes for each element.
For more specific and detailed information about XPCML tags and their attributes, see XPCML schema.
Using XPCML
Using XPCML is similar to using PCML. The following steps serve as a general outline for the actions
that you need to perform to use XPCML.
1. Use XPCML to describe the specification for the program call
2. Create a ProgramCallDocument object
3. Use ProgramCallDocument.callProgram() to run the program
Despite the similarities to using PCML, using XPCML offers enhanced functionality:
v Have the parser automatically validate parameter values
v Specify and pass values for program parameters
v Retrieve the results of a program call to your server in XPCML
v Transform an existing PCML document into the equivalent XPCML document
v Extend the XPCML schema to define new simple and complex elements and attributes
For example, IBM Toolbox for Java enables you to extend the XPCML schema to create new parameter
and data types. You can use this XPCML capability to condense your XPCML source files, which makes
the files easier to read and code easier to use.
For more information about using XPCML, see the following pages:
The ProgramCallDocument class contains the transformPCMLToXPCML method that enables you to
transform existing PCML documents to equivalent XPCML documents.
XPCML has comparable definitions for all of the elements and attributes that you can define in PCML.
Using transformPCMLToXPCML() converts the PCML representation of the elements and attributes to the
equivalent XPCML.
The method takes the existing PCML document, which you pass to it as an InputStream object, and
generates the equivalent XPCML as an OutputStream object. Because transformPCMLToXPCML() is a
static method, you can call it without first creating a ProgramCallDocument object.
The following example shows how to convert a PCML document (named myPCML.pcml) to an XPCML
document (named myXPCML.xpcml).
Note: You must specify .xpcml as the file extension for XPCML files. Using .xpcml as the file extension
ensures that the ProgramCallDocument class recognizes the file as XPCML. If you do not specify
an extension, ProgramCallDocument assumes that the file is PCML.
For more information about transformPCMLToXPCML() and the ProgramCallDocument class, see the
following page:
After you create your XPCML file, you need to create a ProgramCallDocument object that can use the
XPCML specifications and data values to call a program on your IBM i server.
In order to parse and validate the XPCML document, make sure that your CLASSPATH includes a fully
validating XML parser. For more information about requirements to run XPCML, see the following page:
The following example shows how to create a ProgramCallDocument object for the XPCML file,
myXPCML.xpcml.
system = new AS400();
// Create a ProgramCallDocument into which to parse the file.
ProgramCallDocument xpcmlDoc =
new ProgramCallDocument(system, "myXPCML.xpcml");
Note: You must specify .xpcml as the file extension for XPCML files. Using .xpcml as the file extension
ensures that the ProgramCallDocument class recognizes the file as XPCML. If you do not specify
an extension, ProgramCallDocument assumes that the file is PCML.
After you create the ProgramCallDocument object, use any of the methods of the ProgramCallDocument
class to work with your XPCML document. For example, call an IBM i program by using
ProgramCallDocument.callProgram() or change the value for an XPCML input parameter before calling
the server program by using the appropriate ProgramCallDocument.setValue method.
The following example shows how to create a ProgramCallDocument object for an XPCML file (named
myXPCML.xpcml). After creating the ProgramCallDocument object, the example calls a program (PROG1)
that is specified in the XPCML document. In this case, the only difference between using XPCML and
PCML is that the example passes an XPCML file to the ProgramCallDocument constructor.
After your application reads and parses an XPCML document, the XPCML document functions just like a
PCML document. At this point, XPCML can use any of the existing methods that PCML uses.
system = new AS400();
// Call PROG1
boolean rc = xpcmlDoc.callProgram("PROG1");
After you call a server program, you can use ProgramCallDocument.getValue methods to retrieve the
Java objects that represent program parameter values.
Additionally, the following generateXPCML methods enable ProgramCallDocument to return the results
of a program call as XPCML:
v generateXPCML(String fileName): Generates results in XPCML for the entire XPCML source file that
you used to construct the ProgramCallDocument object. Stores the XPCML in a file with the specified
file name.
For more information about the ProgramCallDocument class, see the ProgramCallDocument Javadoc
information.
The following example shows how you can construct an XPCML ProgramCallDocument, call an IBM i
program, and retrieve the results of the program call as XPCML.
You can set the values for program parameters in the XPCML source file and pass in the parameter
values as XPCML.
When the ProgramCallDocument object reads in and parses the XPCML document, it automatically calls
the appropriate setValue method for each parameter specified in the XPCML.
Using XPCML to pass in parameter values relieves you from writing Java code that sets the values of
complicated structures and arrays.
The following examples show different ways to construct arrays and pass in parameter values as XPCML:
Because XPCML is extensible, you can define new parameter types that extend those specified by the
XPCML schema. Condensing XPCML extends the XPCML schema to create new data type definitions that
simplify and improve the readability and usability of your XPCML documents.
The following discussion assumes that you understand the XPCML schema. For more information about
the XPCML schema, see the following page:
To condense existing XPCML source, you use the ProgramCallDocument.condenseXPCML method, which
generates the following:
v An extended schema that contains new type definitions for each parameter in the existing XPCML
source
v New XPCML source that uses the type definitions provided in the extended schema
For more information about condensing your XPCML, see the following pages:
Condensing existing XPCML documents results in more readable and usable XPCML source. To create
condensed XPCML, use the ProgramCallDocument.condenseXPCML method.
For more information about condenseXPCML() and the ProgramCallDocument class, see the
ProgramCallDocument Javadoc information.
Examples
The first example is simple and includes original XPCML source, the resulting condensed XPCML, and
the extended schema. The second example is longer and more complex, so it includes the Java code that
calls condenseXPCML() and only a few of the newly generated type definitions in the extended schema:
“Example: Condensing an existing XPCML document, including Java code” on page 753
Related information:
ProgramCallDocument Javadoc
When validating XPCML schema documents, a fully validating XML parser may generate warnings,
non-fatal parse errors, and fatal parse errors.
Warnings and non-fatal parse errors do not cause the parse to fail. You might want to examine warnings
and non-fatal errors to help you determine problems with your XPCML source. Fatal parse errors cause
the parse to terminate with an exception.
To display warnings and non-fatal parser errors when parsing an XPCML document, turn tracing on in
your application and set the trace category to PCML.
Example
A fully validating XML parser generates an error for any numeric parameter type that does not have a
value. The following example shows sample XPCML source and the resulting non-fatal parse error:
XPCML source
Resulting error
Tue Mar 25 15:21:44 CST 2003 [Error]: cvc-complex-type.2.2: Element
’intParm’ must have no element [children], and the value must be valid.
To prevent logging this kind of error, add the nil=true attribute to the intParm element. The nil=true
atttribute signals to the parser that you have deliberately left the element empty.. Here is the previous
XPCML source with the nil=true atttribute added:
<program name="prog1"/>
<parameterList>
<intParm xsi:nil="true" name="parm1"/>
</parameterList>
</program>
v IBM Toolbox for Java FAQ : Find answers to many types of questions, including improving
performance, using IBM i, performing troubleshooting, and more.
v IBM Toolbox for Java JDBC FAQ : Find answers to questions about using JDBC with IBM Toolbox
for Java.
Note: Avoid using System.exit(0) with servlets because doing so shuts down the entire Java virtual
machine.
IBM Toolbox for Java connects to the server with user threads. Because of this, a failure to issue
System.exit(0) may keep your Java program from properly shutting down.
Using System.exit(0) is not a requirement, but a precaution. There are times that you must use this
command to exit a Java program and it is not problematic to use System.exit(0) when it is not necessary.
Follow these conditions when determining and specifying the integrated file system name:
v The forward slash (/) is the path separator character.
v The root-level directory, called QSYS.LIB, contains the server library structure.
v Objects that reside in the server library QSYS have the following format:
/QSYS.LIB/object.type
v Objects that reside in other libraries have the following format:
/QSYS.LIB/library.LIB/object.type
v The object type extension is the server abbreviation used for that type of object.
To see a list of these types, enter a CL command that has object type as a parameter and press F4
(Prompt) for the type. For example, the Work with Objects (WRKOBJ) command has an object type
parameter.
The following table is a list of some commonly used object types and the abbreviation for each type:
Use the following descriptions to help you determine how to specify integrated file system path names:
Various IBM Toolbox for Java classes recognize special values in integrated file system path names. The
traditional format for these special values (as used on an IBM i command line) begins with an asterisk
(*ALL). However, in a Java program that uses IBM Toolbox for Java classes, the format for these special
values begins and ends with percent signs (%ALL%).
The following table shows which of these special values the IBM Toolbox for Java classes recognize for
particular path name components. The table also shows how the traditional format for these special
values differ from the format used in IBM Toolbox for Java classes.
Path name component Traditional format IBM Toolbox for Java format
Library name *ALL %ALL%
*ALLUSR %ALLUSR%
*CURLIB %CURLIB%
*LIBL %LIBL%
*USRLIBL %USRLIBL%
Object name *ALL %ALL%
Member name *ALL %ALL%
*FILE %FILE%
*FIRST %FIRST%
*LAST %LAST%
See the QSYSObjectPathName class for information about building and parsing integrated file system
names.
For more information about integrated file system concepts, see Integrated file system concepts.
Note: When you create Enterprise JavaBeans (EJB), comply with the EJB specification that does not allow
threads during your connection. Although turning off IBM Toolbox for Java thread support may
slow your application, it is required to comply with the EJB specification.
Every connection to each server has its own job on the system. A different server supports each of the
following:
v JDBC
v Program call and command call
v Integrated file system
v Print
v Data queue
v Record-level access
Note:
v The print classes use one socket connection per AS400 object if the application does not try to do
two things that require the network print server at the same time.
v A print class creates additional socket connections to the network print server if needed. The
extra conversations are disconnected if they are not used for 5 minutes.
The Java program can control the number of connections to the system. To optimize communications
performance, a Java program can create multiple AS400 objects for the same server as shown in Figure 1.
This creates multiple socket connections to the system.
Figure 1: Java program creating multiple AS400 objects and socket connections for the same system
To conserve server resources, create only one AS400 object as shown in Figure 2. This approach reduces
the number of connections, which reduces the amount of resource used on the server.
Figure 2: Java program creating a single AS400 object and socket connection for the same system
You can also choose to use a connection pool to manage connections as shown in Figure 3. This approach
reduces the amount of time it takes to connect by reusing a connection previously established for the
user.
The following examples show how to create and use AS400 objects:
Example 1: In the following example, two CommandCall objects are created that send commands to the
same server. Because the CommandCall objects use the same AS400 object, only one connection to the
server is created.
// Create an AS400 object.
AS400 sys = new AS400("mySystem.myCompany.com");
Example 2: In the following example, two CommandCall objects are created that send commands to the
same system. Because the CommandCall objects use different AS400 objects, two connections to the server
are created.
// Create two AS400 objects to the same server.
AS400 sys1 = new AS400("mySystem.myCompany.com");
AS400 sys2 = new AS400("mySystem.myCompany.com");
Example 3: In the following example, a CommandCall object and an IFSFileInputStream object are
created using the same AS400 object. Because the CommandCall object and the IFSFileInput Stream object
use different services on the server, two connections are created.
// Create an AS400 object.
AS400 newConn1 = new AS400("mySystem.myCompany.com");
Example 4: In the following example, an AS400ConnectionPool is used to get an IBM i connection. This
example (like Example 3 above) does not specify a service, so the connection to the command service is
made when the command is run.
// Create an AS400ConnectionPool.
AS400ConnectionPool testPool1 = new AS400ConnectionPool();
// Create a connection.
AS400 newConn1 = testPool1.getConnection("myAS400", "myUserID", "myPassword");
Example 5: The following example uses AS400ConnectionPool to connect to a particular service when
requesting the connection from the pool. This eliminates the time required to connect to the service when
// Create a connection to the AS400.COMMAND service. (Use the service number constants
// defined in the AS400 class (FILE, PRINT, COMMAND, DATAQUEUE, and so on.))
AS400 newConn1 = testPool1.getConnection("myAS400", "myUserID", "myPassword", AS400.COMMAND);
// Get another connection to command service. In this case, it will return the same
// connection as above, meaning no extra connection time will be needed either now or
// when the command service is used.
AS400 newConn2 = testPool1.getConnection("myAS400", "myUserID", "myPassword", AS400.COMMAND);
The Java program can control when a connection is started and ended. By default, a connection is started
when information is needed from the server. You can control exactly when the connection is made by
calling the connectService() method on the AS400 object to preconnect to the server.
Using an AS400ConnectionPool, you can create a connection preconnected to a service without calling the
connectService() method, as in Example 5 above.
The following examples show Java programs connecting to and disconnecting from the system.
Example 2: Once a connection is started, the Java program is responsible for disconnecting, which is done
either implicitly by the AS400 object, or explicitly by the Java program. A Java program disconnects by
calling the disconnectService() method on the AS400 object. To improve performance, the Java program
must disconnect only when the program is finished with a service. If the Java program disconnects before
it is finished with a service, the AS400 object reconnects, if it is possible to reconnect, when data is
needed from the service.
Figure 4 shows how disconnecting the connection for the first integrated file system object connection
ends only that single instance of the AS400 object connection, not all of the integrated file system object
connections.
Figure 4: Single object using its own service for an instance of an AS400 object is disconnected
Example 3: Multiple objects that use the same service and share the same AS400 object share a
connection. Disconnecting ends the connection for all objects that are using the same service for each
instance of an AS400 object as is shown in Figure 5.
Figure 5: All objects using the same service for an instance of an AS400 object are disconnected
For example, two CommandCall objects use the same AS400 object. When disconnectService() is called,
the connection is ended for both CommandCall objects. When the run() method for the second
CommandCall object is called, the AS400 object must reconnect to the service:
Example 4: Not all IBM Toolbox for Java classes automatically reconnect. Some method calls in the
integrated file system classes do not reconnect because the file may have changed. While the file was
disconnected, some other process may have deleted the file or changed its contents. In the following
example, two file objects use the same AS400 object. When disconnectService() is called, the connection is
ended for both file objects. The read() for the second IFSFileInputStream object fails because it no longer
has a connection to the server.
// Create an AS400 object.
AS400 sys = new AS400("mySystem.myCompany.com");
For more information about IBM i support for different Java platforms, see Support for multiple JDKs.
Comparing the IBM i Java virtual machine and the IBM Toolbox for Java classes
You always have at least two ways to access a server resource when your Java program is running on the
IBM Developer Kit for Java (IBM i) Java virtual machine (JVM).
Command call
Two common ways to call a command are to use one of the following:
v The IBM Toolbox for Java CommandCall class
v The java.lang.Runtime.exec method
The CommandCall class generates a list of messages that are available to the Java program once the
command completes. This list of messages is not available through java.lang.Runtime.exec().
The java.lang.Runtime.exec method is portable across many platforms, so if your program must access
files on different types of servers, java.lang.Runtime.exec() is a better solution.
The IBM Toolbox for Java integrated file system classes have the advantage of providing more function
than the java.io classes. The IBM Toolbox for Java classes also work in applets, and they do not need a
method of redirection (such as IBM i Access for Windows) to get from a workstation to the server.
The java.io classes are portable across many platforms, which is an advantage. If your program must
access files on different types of servers, java.io is a better solution.
If you use java.io classes on a client, you need a method of redirection (such as the IBM i Access for
Windows) to get to the server file system.
JDBC
Two IBM-supplied JDBC drivers are available to programs running on the IBM i JVM:
v The IBM Toolbox for Java JDBC driver
v The IBM Developer Kit for Java JDBC driver
The IBM Toolbox for Java JDBC driver is best to use when the program is running in a client/server
environment.
The IBM Developer Kit for Java JDBC driver is best to use when the program is running on the server.
If the same program runs on both the workstation and the server, you should load the correct driver
through a system property instead of coding the driver name into your program.
Program call
The IBM Toolbox for Java ProgramCall class has the advantage that it can call any server program.
Setting system name, user ID, and password with an AS400 object in the IBM i
Java virtual machine
The AS400 object allows special values for system name, user ID, and password when the Java program
is running on the IBM Toolbox for Java (IBM i) Java virtual machine (JVM).
When you run a program on the IBM i JVM, be aware of some special values and other considerations:
v User ID and password prompting is disabled when the program runs on the server. For more
information about user ID and password values in the server environment, see Summary of user ID
and password values on an AS400 object.
v If system name, user ID, or password is not set on the AS400 object, the AS400 object connects to the
current server by using the user ID and password of the job that started the Java program. When
connecting to a v4r4 or later machine, it can extend the signed-on user's password like the rest of the
IBM Toolbox for Java components.
v The special value, localhost, can be used as the system name. In this case, the AS400 object connects to
the current server.
v The special value, *current, can be used as the user ID or password on the AS400 object. In this case,
the user ID or password (or both) of the job that started the Java program is used.
v The special value, *current, can be used as the user ID or password on the AS400 object when the Java
program is running on the IBM i JVM of one server, and the program is accessing resources on another
IBM i server. In this case, the user ID and password of the job that started the Java program on the
source system are used when connecting to the target system.
Examples
The following examples show how to use the AS400 object with the IBM i JVM.
Example: Creating an AS400 object when the IBM i JVM is running a Java program
When a Java program is running in the IBM i JVM, the program does not need to supply a system name,
user ID, or password.
If these values are not supplied, the AS400 object connects to the local system by using the user ID and
password of the job that started the Java program.
When the program is running on the IBM i JVM, setting the system name to localhost is the same as not
setting the system name. The following example shows how to connect to the current server:
// Create two AS400 objects. If the Java program is running in the
// IBM i JVM, the behavior of the two objects is the same.
// They will connect to the current server using the user ID and
// password of the job that started the Java program.
AS400 sys = new AS400()
AS400 sys2 = new AS400("localhost")
Example: Connecting to the current server with a different user ID and password from the program
that started the job The Java program can set a user ID and password even when the program is running
on the IBM i JVM. These values override the user ID and password of the job that started the Java
program.
In the following example, the Java program connects to the current server, but the program uses a user
ID and password that differs from those of the job that started the Java program.
Example: Connecting to a different server by using the user ID and password of the job that started
the Java program
A Java program that is running on one server can connect to and use the resources of other systems.
If *current is used for user ID and password, the user ID and password of the job that started the Java
program is used when the Java program connects to the target server.
In the following example, the Java program is running on one server, but uses resources from another
server. The user ID and password of the job that started the Java program are used when the program
connects to the second server.
// Create an AS400 object. This program will run on one server
// but will connect to a second server (called "target").
// Because *current is used for user ID and password, the user
// ID and password of the job that started the program will be
// used when connecting to the second server.
AS400 target = new AS400("target", "*current", "*current")
The following table summarizes how the user ID and password values on an AS400 object are handled
by a Java program running on a server compared to a Java program running on a client.
Values on AS400 object Java program running on a server Java program running on a client
System name, user ID, and password Connect to the current server using Prompt for system, user ID, and
not set the user ID and password of the job password
that started the program
System name = localhost
System name = localhost User ID = Connect to the current server using
Error: localhost is not valid when the
*current the user ID and password of the job
Java program is running on a client
that started the program
System name = localhost User ID =
*current Password ID = *current
System name = "sys" Connect to server "sys" using the Prompt for user ID and password
user ID and password of the job that
started the program. "sys" can be the
current server or another server
System name = localhost User ID = Connect to the current server using Error: localhost is not valid when the
"UID" Password ID = "PWD" the user ID and password specified Java program is not running on a
by the Java program instead of the client
user ID and password of the job that
started the program
You can use the "database name" JDBC property or the setDatabaseName() method from the
AS400JDBCDataSource class to specify the ASP to which you want to connect.
All other IBM Toolbox for Java classes (IFSFile, Print, DataQueues, and so on) use the Independent ASP
specified by the job description of the user profile that connects to the server.
Exceptions
The IBM Toolbox for Java access classes throw exceptions when device errors, physical limitations,
programming errors, or user input errors occur. The exception classes are based upon the type of error
that occurs instead of the location where the error originates.
The following example shows how to catch a thrown exception, retrieve the return code, and display the
exception text:
Note: Read the Code example disclaimer for important legal information.
// All the setup work to delete a file on the server through the
// IFSFile class is done. Now try deleting the file.
try
{
aFile.delete();
// Get the return code out of the exception and display additional
// information based on the return code.
int rc = e.getReturnCode()
switch (rc)
{
case ExtendedIOException.FILE_IN_USE:
System.out.println("Delete failed, file is in use "):
break;
case ExtendedIOException.PATH_NOT_FOUND:
System.out.println("Delete failed, path not found ");
break;
default:
System.out.println("Delete failed, rc = ");
System.out.println(rc);
}
}
Error events
In most cases, the IBM Toolbox for Java GUI components fire error events instead of throw exceptions.
You can provide an error listener that handles all error events that are fired by a particular graphical user
interface component. Whenever an exception is thrown, the listener is called, and it can provide
appropriate error reporting. By default, no action takes place when error events are fired.
The IBM Toolbox for Java provides a graphical user interface component called ErrorDialogAdapter,
which automatically displays a dialog to the user whenever an error event is fired.
Examples
The following examples show how you can handle errors and define a simple error listener.
The following example shows how you can handle error events by displaying a dialog:
// All the setup work to lay out a graphical user interface component
// is done. Now add an ErrorDialogAdapter as a listener to the component.
// This will report all error events fired by that component through
// displaying a dialog.
You can write a custom error listener to handle errors in a different way. Use the ErrorListener interface
to accomplish this.
The following example shows how to define an simple error listener that only prints errors to System.out:
class MyErrorHandler
implements ErrorListener
{
// This method is invoked whenever an error event is fired.
public void errorOccurred(ErrorEvent event)
{
Exception e = event.getException ();
System.out.println ("Error: " + e.getMessage ());
}
}
The following example shows how to handle error events for a graphical user interface component using
this customized handler:
MyErrorHandler errorHandler = new MyErrorHandler ();
component.addErrorListener (errorHandler);
Trace class
The Trace class allows the Java program to log trace points and diagnostic messages. This information
helps reproduce and diagnose problems.
Note: You can also set tracing by using the trace system properties.
The IBM Toolbox for Java classes also use the trace categories. When a Java program enables logging,
IBM Toolbox for Java information is included with the information that is recorded by the application.
You can enable the trace for a single category or a set of categories. Once the categories are selected, use
the setTraceOn method to turn tracing on and off. Data is written to the log using the log method.
You can send trace data for different components to separate logs. Trace data, by default, is written to
the default log. Use component tracing to write application-specific trace data to a separate log or
standard output. By using component tracing, you can easily separate trace data for a specific application
from other data.
The default is to write log information to standard out. To redirect the log to a file, call the
setFileName() method from your Java application. In general, this works only for Java applications
because most browsers do not give applets access to write to the local file system.
Logging is off by default. Java programs provide a way for the user to turn on logging so that it is easy
to enable logging. For example, the application can parse for a command line parameter that indicates
which category of data is logged. The user can set this parameter when log information is needed.
Examples
Note: Read the Code example disclaimer for important legal information.
Example Using setTraceOn() and writing data to a log by using the log method
// Enable diagnostic, information, and warning logging.
Trace.setTraceDiagnosticOn(true);
Trace.setTraceInformationOn(true);
Trace.setTraceWarningOn(true);
// Send IBM Toolbox for Java and the component trace data each to separate files.
// The trace will contain all trace information, while each
// Trace.setFileName("c:\\bit.bucket");
// Trace.setFileName(myComponent1, "c:\\Component1.log");
// Trace.setFileName(myComponent2, "c:\\Component2.log");
// Log component specific trace data or general IBM Toolbox for Java
// trace data.
Trace.setFileName("c:\\bit.bucket");
Trace.setFileName(myComponent1, "c:\\Component1.log");
Related information:
Trace Javadoc
IBM i optimization
There exists two versions of the IBM Toolbox for Java software, one that is optimized when running on
the IBM i JVM, and another that runs the same way no matter where the IBM Toolbox for Java is run.
Sign-on behavior and performance are improved when using the optimized version of the IBM Toolbox
for Java software and running on the IBM i JVM and connecting to the same server.
| IBM Toolbox for Java is shipped as part of Licensed Program 5770-SS1 (option 3) in two directories:
| v The /QIBM/ProdData/http/public/jt400/lib contains the version of the IBM Toolbox for Java that does
| not include IBM i optimizations. Use these files if you want behavior consistent with running the IBM
| Toolbox for Java on a client.
| v The /QIBM/ProdData/OS400/jt400/lib contains the version of the IBM Toolbox for Java that does
| include IBM i optimizations when running on the IBM i JVM.
| For more information see Note 1 in the information about JAR files.
Sign-on considerations
The version of the IBM Toolbox for Java that contains optimizations adds additional options for
providing server (system) name, user ID and password information to the IBM Toolbox for Java.
When accessing an IBM i resource, the IBM Toolbox for Java classes must have a system name, user ID
and password.
v When running on a client, the system name, user ID and password are provided by the Java program,
or the IBM Toolbox for Java retrieves these values from the user through a sign-on dialog.
v When running within the IBM i Java virtual machine, the IBM Toolbox for Java has one more option.
It can send requests to the current (local) server using the user ID and password of the job that started
the Java program.
The Java program can only set the password to "*current" if you are using record-level access V4R4 or
later. Otherwise, when you use record-level access, "localhost" is valid for system name and "*current" is
valid for user ID; however, the Java program must supply the password.
A Java program sets system name, user ID, and password values in the AS400 object.
To use the user ID and password of the job, the Java program can use "*current" as user ID and
password, or it can use the constructor that does not have user ID and password parameters.
To use the current server, the Java program can use "localhost" as the system name or use the default
constructor. That is,
AS400 system = new AS400();
is the same as
AS400 system = new AS400("localhost", "*current", "*current");
Examples
The following examples show how to sign on to a server by using optimized classes.
Two AS400 objects are created in the following example. The two objects have the same behavior: they
both run a command to the current server using the user ID and password of the job. One object uses the
special value for the user ID and password, while the other uses the default constructor and does not set
user ID or password.
// Create an AS400 object. Since the default
// constructor is used and system, user ID and
// password are never set, the AS400 object sends
// requests to the local server using the job’s
// user ID and password. If this program were run
// on a client, the user would be prompted for
// system, user ID and password.
AS400 sys1 = new AS400();
// Create two command call objects that use the AS400 objects.
CommandCall cmd1 = new CommandCall(sys1,"myCommand1");
CommandCall cmd2 = new CommandCall(sys2,"myCommand2");
Example: Signing on by using the user ID and password of the current job
In the following example an AS400 object is created that represents a second IBM i server. Since "*current"
is used, the job's user ID and password from the server running the Java program are used on the second
(target) server.
Performance improvements
With the additional classes provided by IBM i, Java programs running on the Java virtual machine for
IBM i experience improved performance. Performance is improved in some cases because less
communication function is used, and in other cases, an API is used instead of calling the server program.
In order to download the minimum number of IBM Toolbox for Java class files, use the proxy server in
combination with the AS400ToolboxJarMaker tool.
Faster communication
For all IBM Toolbox for Java functions except JDBC and integrated file system access, Java programs
running on the Java virtual machine for IBM i will run faster. The programs run faster because less
communication code is used when communicating between the Java program and the server program on
the server that does the request.
JDBC and integrated file system access were not optimized because facilities already exist that make these
functions run faster. When running on the IBM i server, you can use the JDBC driver for IBM i instead of
the JDBC driver that comes with the IBM Toolbox for Java. To access files on the server, you can use
java.io instead of the integrated file system access classes that come with the IBM Toolbox for Java.
Performance of the following classes of the IBM Toolbox for Java is improved because these classes
directly call IBM i APIs instead of calling a server program to carry out the request:
v AS400Certificate classes
v CommandCall
v DataQueue
v ProgramCall
v Record-level database access classes
v ServiceProgramCall
v UserSpace
APIs are directly called only if the user ID and password match the user ID and password of the job
running the Java program. To get the performance improvement, the user ID and password must match
the user ID and password of the job that starts the Java program. For best results, use "localhost" for
system name, "*current" for user ID, and "*current" for password.
For the port mapping improvement, a few methods have been added to AS400 class:
v getServicePort
v setServicePort
v setServicePortsToDefault
Language-specific string files are now shipped within the IBM Toolbox for Java program as class files
instead of property files. The server finds messages in class files faster than in property files.
ResourceBundle.getString() now runs faster because the files are stored in the first place that the
computer searches. Another advantage of changing to class files is that the server can find the translated
version of a string faster.
Converters
Two classes allow faster, more efficient conversion between Java and the system:
v Binary Converter: Converts between Java byte arrays and Java simple types.
v Character Converter: Converts between Java String objects and IBM i code pages.
Also, the IBM Toolbox for Java now incorporates its own conversion tables for over 100 commonly used
CCSIDs. Previously, the IBM Toolbox for Java either deferred to Java for nearly all text conversion. If Java
did not possess the correct conversion table, IBM Toolbox for Java downloaded the conversion table from
the server.
The IBM Toolbox for Java performs all text conversion for any CCSID of which it is aware. When it
encounters an unknown CCSID, it attempts to let Java handle the conversion. At no point does the IBM
Toolbox for Java attempt to download a conversion table from the server. This technique greatly reduces
the amount of time it takes for an IBM Toolbox for Java application to perform text conversion. No action
is required by the user to take advantage of this new text conversion; the performance gains all occur in
the underlying converter tables.
Related information:
AS400 Javadoc
BinaryConverter Javadoc
Character Converter Javadoc
Because program temporary fixes (PTFs) are applied to this location, Java programs that access these
classes directly on the server automatically receive these updates. But, accessing the classes from the
server does not always work, specifically for the following situations:
v If a low-speed communication link connects server and the client, the performance of loading the
classes from the server may be unacceptable.
v If Java applications use the CLASSPATH environment variable to access the classes on the client file
system, you need IBM i Access for Windows to redirect file system calls to the server. It may not be
possible for IBM i Access for Windows to reside on the client.
AS400ToolboxJarMaker
While the JAR file format was designed to speed up the downloading of Java program files, the
AS400ToolboxJarMaker generates an even faster loading IBM Toolbox for Java JAR file through its ability
to create a smaller JAR file from a larger one.
Also, the AS400ToolboxJarMaker class can unzip a JAR file for you to gain access to the individual
content files for basic use.
Flexibility of AS400ToolboxJarMaker
All of the AS400ToolboxJarMaker functions are performed with the JarMaker class and the
AS400ToolboxJarMaker subclass:
v The generic JarMaker tool operates on any JAR or Zip file; it splits a JAR file or reduces the size of a
JAR file by removing classes that are not used.
v The AS400ToolboxJarMaker customizes and extends JarMaker functions for easier use with IBM
Toolbox for Java JAR files.
According to your needs, you can invoke the AS400ToolboxJarMaker methods from within your own Java
program or from a command line. Call AS400ToolboxJarMaker from the command line by using the
following syntax:
java utilities.JarMaker [options]
where
v options = one or more of the available options
For a complete set of options available to run at a command line prompt, see the following in the
Javadoc:
v Options for the JarMaker base class
v Extended options for the AS00ToolboxJarMaker subclass
Using AS400ToolboxJarMaker
You can use AS400ToolboxJarMaker to work with JAR files in several ways:
v Uncompress one file bundled within a JAR file
v Split a large JAR file into smaller JAR files
v Exclude any IBM Toolbox for Java files that your application does not need to run
Suppose you wanted to uncompress just one file bundled within a JAR file. AS400ToolboxJarMaker
allows you to expand the file into one of the following:
v Current directory (extract(jarFile))
v Another directory (extract(jarFile, outputDirectory))
For example, with the following code, you are extracting AS400.class and all of its dependent classes from
jt400.jar:
java utilities.AS400ToolboxJarMaker -source jt400.jar
-extract outputDir
-requiredFile com/ibm/as400/access/AS400.class
In the following code, jt400.jar is split into a set of smaller JAR files, none larger than 300KB:
java utilities.AS400ToolboxJarMaker -split 300
With AS400ToolboxJarMaker, you can exclude any IBM Toolbox for Java files not needed by your
application by selecting only the IBM Toolbox for Java components, languages, and CCSIDs that you
need to make your application run. AS400ToolboxJarMaker also provides you with the option of
including or excluding the JavaBean files associated with the components you select.
For example, the following command creates a JAR file that contains only those IBM Toolbox for Java
classes needed to make the CommandCall and ProgramCall components of the IBM Toolbox for Java
work:
java utilities.AS400ToolboxJarMaker -component CommandCall,ProgramCall
Additionally, if it is unnecessary to convert text strings between Unicode and the double byte character
set (DBCS) conversion tables, you can create a 400KB byte smaller JAR file by omitting the unneeded
conversion tables with the -ccsid option:
java utilities.AS400ToolboxJarMaker -component CommandCall,ProgramCall -ccsid 61952
Note: Conversion classes are not included with the program call classes. When including program call
classes, you must also explicitly include the conversion classes used by your program by using the
-ccsid option.
JarMaker Javadoc
AS400ToolboxJarMaker Javadoc
When a mismatch between languages occurs, for example, if you are running on a local workstation that
is using a language that is not supported by Java, the IBM Toolbox for Java licensed program may issue
some error messages in English.
IBM Toolbox for Java troubleshooting information Use this information to help you resolve
problems when using IBM Toolbox for Java.
JTOpen/IBM Toolbox for Java forum Join the community of Java programmers who use IBM
Toolbox for Java. This forum is an effective way to get assistance and advice from other Java
programmers and sometimes from the IBM Toolbox for Java developers themselves
Server support Use the IBM Server support Web site to find out about the tools and resources
that help you streamline the technical planning and support for your system.
Software support Use the IBM Software Support Services Web site to find out about the wide
array of software support services offered by IBM.
Resolving IBM Toolbox for Java program defects is supported under program services and voice support,
while resolving application programming and debugging issues is supported under consulting services.
IBM Toolbox for Java application program interface (API) calls are supported under consulting services
unless any of the following are true:
v It is clearly a Java API defect, as demonstrated by re-creation in a relatively simple program.
v It is a question asking for documentation clarification.
v It is a question about the location of samples or documentation.
All programming assistance is supported under consulting services including those program samples
provided in the IBM Toolbox for Java licensed program. Additional samples may be made available on
the Internet at the IBM i home page on an unsupported basis.
Problem solving information is provided with the IBM Toolbox for Java Licensed Program Product. If you
believe there is a potential defect in the IBM Toolbox for Java API, a simple program that demonstrates
the error will be required.
Code examples
The following list provides links to entry points for many of the examples used throughout the IBM
Toolbox for Java information.
IBM grants you a nonexclusive copyright license to use all programming code examples from which you
can generate similar function tailored to your own specific needs.
AS400JPing
v Example: Using AS400JPing within a Java program
BidiTransform
v Example: Using the AS400BidiTransform class to transform bidirectional text
CommandCall
v Example: Using CommandCall to run a command on the server
v Example: Using CommandCall to prompt for the name of the server, command to run, and print the
result
ConnectionPool
v Example: Using AS400ConnectionPool to create connections to the server
DataArea
v Example: Creating and writing to a decimal data area
DataQueue
v Example: How to create a DataQueue object, read data, and disconnect
v Example: Putting data on a queue
v Example: Reading data from a queue
v Example: Using KeyedDataQueue to put items on a queue
v Example: Using KeyedDataQueue to take items off a queue
Digital certificate
v Example: Listing digital certificates that belong to a user
EnvironmentVariable
v Example: Creating, setting, and getting environment variables
Exceptions
v Example: Catching a thrown exception, retrieving the return code, and displaying the exception text
FTP
v Example: Using the FTP class to Copy a set of files from a server directory
v Example: Using the AS400FTP class to copy a set of files from a directory
JavaApplicationCall
v Example: Running a program on the server from the client that outputs "Hello World!"
JDBC
v Example: Using the JDBC driver to create and populate a table
v Example: Using the JDBC driver to query a table and output its contents
Jobs
v Example: Retrieving and changing job information using the cache
v Example: Listing all active jobs
v Example: Printing all of the messages in the job log for a specific user
v Example: Listing the job identification information for a specific user
v Example: Getting a list of jobs on the server and listing the job status and the job identifier
v Example: Displaying messages in the job log for a job that belongs to the current user
Message queue
v Example: How to use the message queue object
v Example: Printing the contents of the message queue
v Example: Retrieving and printing a message
v Example: Listing the contents of the message queue
v Example: Using AS400Message with CommandCall
v Example: Using AS400Message with ProgramCall
NetServer
v Example: Using a NetServer object to change the name of the NetServer
Print
v Example: Asynchronously listing all spooled files using the PrintObjectListListener interface
v Example: Asynchronously listing all spooled files without using the PrintObjectListListener interface
v Example: Copying a spooled file using SpooledFile.copy()
v Example: Creating a spooled file from an input stream
v Example: Generating an SCS data stream using the SCS3812Writer class
v Example: Reading an existing spooled file
v Example: Reading and transforming spooled files
v Example: Synchronously listing all spooled files
Permission
v Example: Set the authority of an AS400 object
QSYSObjectPathName
v Example: Building an integrated file system name
v Example: Using QSYSObjectPathName.toPath() to build an AS400 object name
v Example: Using QSYSObjectPathName to parse the integrated file system path name
Record-level access
v Example: Sequentially accessing a file
v Example: Using the record-level access classes to read a file
v Example: Using the record-level access classes to read records by key
v Example: Using the LineDataRecordWriter class
SystemStatus
v Example: Use caching with the SystemStatus class
SystemPool
v Example: Setting the maximum faults size for SystemPool
SystemValue
v Example: Using SystemValue and SystemValueList
Trace
v Example: Using the Trace.setTraceOn() method
v Example: Preferred way to use Trace
v Example: Using component tracing
UserGroup
v Example: Retrieving a list of users
v Example: Listing all the users of a group
UserSpace
v Example: How to create a user space
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// Command call example. This program prompts the user
// for the name of the server and the command to run, then
// prints the result of the command.
//
// This source is an example of "CommandCall"
//
//////////////////////////////////////////////////////////////////////////////////
import java.io.*;
import java.util.*;
import com.ibm.as400.access.*;
// Declare variables to hold the system name and the command to run
String systemString = null;
String commandString = null;
// Get the system name and the command to run from the user
try
{
System.out.print("System name: ");
systemString = inputStream.readLine();
System.out.print("Command: ");
commandString = inputStream.readLine();
}
catch (Exception e) {};
try
{
// Run the command.
if (command.run(commandString))
System.out.print( "Command successful" );
else
System.out.print( "Command failed" );
if (messagelist.length > 0)
{
System.out.println( ", messages from the command:" );
System.out.println( " " );
}
System.exit(0);
}
}
Note: Read the Code example disclaimer for important legal information.
////////////////////////////////////////////////////////////
//
// AS400ConnectionPooling example. This program uses an
// AS400ConnectionPool to create connections to an
// IBM i system.
// Command syntax:
// AS400ConnectionPooling system myUserId myPassword
//
// For example,
// AS400ConnectionPooling MySystem MyUserId MyPassword
//
////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
try
{
// Create an AS400ConnectionPool.
AS400ConnectionPool testPool = new AS400ConnectionPool();
System.out.println();
System.out.println("getConnection gives out an existing connection to user");
System.out.println("Number of active connections: "
+ testPool.getActiveConnectionCount(system, userId));
System.out.println("Number of available connections for use: "
+ testPool.getAvailableConnectionCount(system, userId));
System.out.println();
System.out.println("Returned a connection to pool");
System.out.println("Number of active connections: "
+ testPool.getActiveConnectionCount(system, userId));
System.out.println("Number of available connections for reuse: "
+ testPool.getAvailableConnectionCount(system, userId));
System.out.println();
System.out.println("getConnection gives out an existing connection to user");
System.out.println("Number of active connections: "
+ testPool.getActiveConnectionCount(system, userId));
System.out.println("Number of available connections for reuse: "
+ testPool.getAvailableConnectionCount(system, userId));
System.out.println();
System.out.println("getConnection creates a new connection because there are no
connections available");
System.out.println("Number of active connections: "
+ testPool.getActiveConnectionCount(system, userId));
System.out.println("Number of available connections for reuse: "
+ testPool.getAvailableConnectionCount(system, userId));
Note: By using the code examples, you agree to the terms of the “Code license and disclaimer
information” on page 760.
Example 1
This brief example shows the basic use of the AS400JDBCManagedConnectionPoolDataSource class.
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import com.ibm.as400.access.AS400JDBCManagedConnectionPoolDataSource;
import com.ibm.as400.access.AS400JDBCManagedDataSource;
// Set general datasource properties. Note that both connection pool datasource (CPDS) and managed
// datasource (MDS) have these properties, and they might have different values.
cpds0.setServerName(host);
cpds0.setSavePasswordWhenSerialized(true);
Connection c = dataSource_.getConnection();
Example 2
This example shows more details about how to use the AS400JDBCManagedConnectionPoolDataSource
class.
import java.awt.TextArea;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Vector;
import java.util.Properties;
import java.sql.Connection;
import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.naming.*;
import java.util.Date;
import java.util.ArrayList;
import java.util.Random;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400JDBCManagedConnectionPoolDataSource;
import com.ibm.as400.access.AS400JDBCManagedDataSource;
import com.ibm.as400.access.Trace;
// If you turn this flag on, be sure to also turn on the following flag:
// AS400JDBCConnection.TESTING_THREAD_SAFETY.
private static final boolean TESTING_THREAD_SAFETY = false;
// Note: For consistency, all time values are stored units of milliseconds.
private int initialPoolSize_; // initial # of connections in pool
private int minPoolSize_; // max # of connections in pool
private int maxPoolSize_; // max # of connections in pool
private long maxLifetime_; // max lifetime (msecs) of connections in pool
private long maxIdleTime_; // max idle time (msecs) of available connections in pool
private long propertyCycle_; // pool maintenance frequency (msecs)
private boolean keepDaemonsAlive_ = true; // When this is false, the daemons shut down.
static
{
try {
Class.forName("com.ibm.as400.access.AS400JDBCDriver");
}
catch(Exception e){
System.out.println("Unable to register JDBC driver.");
System.exit(0);
}
}
cptest.setup();
cptest.runTest();
}
if (TESTING_THREAD_SAFETY)
{
// Adjust values for performing thread-intensive stress testing.
// NOTE: This assumes that the AS400JDBCConnection class has also been modified to
// not make actual connections to an actual server.
// To do this, edit AS400JDBCConnection.java, changing its TESTING_THREAD_SAFETY
// flag to ’false’, and recompile.
minPoolSize_ = 100;
maxPoolSize_ = 190;
if (DEBUG)
System.out.println("setup: Constructing "
+ "AS400JDBCManagedConnectionPoolDataSource (cpds0)");
AS400JDBCManagedConnectionPoolDataSource cpds0 =
new AS400JDBCManagedConnectionPoolDataSource();
// Set datasource properties. Note that both CPDS and MDS have these
// properties, and they might have different values.
cpds0.setServerName(host);
cpds0.setDatabaseName(host);//iasp can be here
cpds0.setUser(userid);
cpds0.setPassword(password);
cpds0.setSavePasswordWhenSerialized(true);
ctx.rebind("mydatasource", cpds0);
// We can now do lookups on cpds, by the name"mydatasource".
if (DEBUG)
System.out.println("setup: lookup(\"mydatasource\"" + ")");
// AS400JDBCManagedConnectionPoolDataSource cpds1 =
// (AS400JDBCManagedConnectionPoolDataSource)ctx.lookup("mydatasource");
// if (DEBUG) System.out.println("setup: cpds1.getUser() == |" + cpds1.getUser() + "|");
if (DEBUG)
System.out.println("setup: Constructing AS400JDBCManagedDataSource (mds0)");
AS400JDBCManagedDataSource mds0 = new AS400JDBCManagedDataSource();
mds0.setDescription("DataSource supporting connection pooling");
mds0.setDataSourceName("mydatasource");
if (DEBUG)
System.out.println("setup: lookup(\"ConnectionPoolingDataSource\"" + ")");
dataSource_ = (DataSource)ctx.lookup("ConnectionPoolingDataSource");
//dataSource_.setLogWriter(output_);
if (DEBUG)
System.out.println("setup: dataSource_.getUser() == |" +
((AS400JDBCManagedDataSource)dataSource_).getUser() + "|");
mds_ = (AS400JDBCManagedDataSource)dataSource_;
}
catch (Exception e)
{
e.printStackTrace();
System.out.println("Setup error during Trace file creation.");
}
}
/**
* Gets and returns connections from and to a connection pool for a while.
**/
public void runTest()
{
boolean ok = true;
try
{
System.out.println("Started test run at " + new Date());
if (DEBUG)
System.out.println("Checking health just after datasource creation "
+ "(we expect that the pool does not exist yet) ...");
if (mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool exists prior to first getConnection().");
}
mds_.setAccess("read only");
if (!mds_.getAccess().equals("read only")) {
ok = false;
System.out.println("\nERROR: getAccess() returned unexpected value: "
+ "|" + mds_.getAccess()+"|");
}
oldBool = mds_.isKeepAlive();
oldInt = mds_.getReceiveBufferSize();
newInt = (oldInt == 256 ? 512 : 256);
mds_.setReceiveBufferSize(newInt);
if (mds_.getReceiveBufferSize() != newInt) {
ok = false;
System.out.println("\nERROR: getReceiveBufferSize() returned unexpected value: "
+ "|"+mds_.getReceiveBufferSize()+"|");
}
mds_.setReceiveBufferSize(oldInt);
System.out.println("CONNECTION 1");
Object o = dataSource_.getConnection();
System.out.println(o.getClass());
System.out.println("******LOOK ABOVE*******");
Connection c1 = dataSource_.getConnection();
if (DEBUG)
displayConnectionType(c1, true);
if (DEBUG)
System.out.println("Checking health after first getConnection() ...");
if (!mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool is not healthy after first getConnection().");
}
if (!TESTING_THREAD_SAFETY)
{
try
{
c1.setAutoCommit(false);
if (DEBUG)
System.out.println("SELECT * FROM QIWS.QCUSTCDT");
Statement s = c1.createStatement();
ResultSet rs = s.executeQuery("SELECT * FROM QIWS.QCUSTCDT");
while(rs.next()){
if (DEBUG)
System.out.println(rs.getString(2));
}
rs.close();
s.close();
}
catch (Exception e) {
e.printStackTrace();
if (DEBUG)
System.out.println("Checking health after fatal connection error ...");
if (!mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool is not healthy after fatal connection "
+ "error.");
}
}
}
System.out.println("CONNECTION 2");
Connection c2 = dataSource_.getConnection(userid, password);
if (DEBUG)
displayConnectionType(c2, false);
System.out.println("CONNECTION 3");
Connection c3 = dataSource_.getConnection();
if (DEBUG)
displayConnectionType(c3, true);
c1.close();
if (DEBUG)
System.out.println("Checking health after first close() ...");
if (!mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool is not healthy after first close().");
System.out.println("CONNECTION 4");
Connection c4 = dataSource_.getConnection();
if (DEBUG) displayConnectionType(c4, true);
// Run the test daemons for a while; check pool health periodically.
if (DEBUG)
System.out.println("Checking health after connectionGetter daemons have run...");
if (!mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool is not healthy after test daemons stopped.");
}
if (!TESTING_THREAD_SAFETY)
{
System.out.println("CONNECTION 5");
Connection c = dataSource_.getConnection();
if (DEBUG) displayConnectionType(c, true);
c.setAutoCommit(false);
if (DEBUG) System.out.println("SELECT * FROM QIWS.QCUSTCDT");
Statement s = c.createStatement();
ResultSet rs = s.executeQuery("SELECT * FROM QIWS.QCUSTCDT");
while(rs.next()){
if (DEBUG) System.out.println(rs.getString(2));
}
rs.close();
s.close();
c.close();
}
if (DEBUG)
System.out.println("Checking health after pool closed ...");
Trace.setTraceJDBCOn(true); // make sure the final stats get printed out
Trace.setTraceOn(true);
if (!mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool is not healthy after pool closed.");
}
void startThreads()
{
// Create a bunch of threads that call getConnection().
Thread[] threads = new Thread[numDaemons_];
for (int i=0; i<numDaemons_; i++)
{
ConnectionGetter getter;
// Flip a coin to see if this daemon will specify the default uid, or unique uid.
if (random_.nextBoolean())
{
getter = new ConnectionGetter(userid,password);
if (TESTING_THREAD_SAFETY) { // we can use fictional userid
getter = new ConnectionGetter("Thread"+i, "Pwd"+i);
}
else { // must use a real userid
getter = new ConnectionGetter(userid,password);
}
}
else
getter = new ConnectionGetter(null, null);
void stopThreads()
{
// Tell the threads to stop.
keepDaemonsAlive_ = false;
synchronized (daemonSleepLock_) {
daemonSleepLock_.notifyAll();
}
// ConnectionGetter --------------------------------------------------------------------
/**
Helper class. This daemon wakes up at random intervals and either
gets another connection from the connection pool or returns a
previously-gotten connection to the pool.
**/
private final class ConnectionGetter implements Runnable
{
private String uid_;
private String pwd_;
private boolean useDefaultUid_;
private long maxSleepTime_;
private String threadName_;
private boolean firstConnection_ = true;
try
{
while (keepDaemonsAlive_)
{
try
{
// Pick a random sleep-time, between min and max values.
long sleepTime = Math.max((long)(maxSleepTime_ * random_.nextFloat()),
daemonMinSleepTime_);
// Note: Must never call wait(0), because that waits forever.
synchronized (daemonSleepLock_) {
try {
daemonSleepLock_.wait(sleepTime);
System.out.print(".");
}
catch (InterruptedException ie) {}
}
if (!keepDaemonsAlive_) break;
if (conn == null) {
System.out.println("ConnectionGetter("+threadName_+") ERROR: "
+ "getConnection() returned null");
}
else
{
// Occasionally "forget" that we own a connection, and neglect to
// close it.
// Orphaned connections should eventually exceed their maximum
// lifetime and get "reaped" by the connection manager.
float val = random_.nextFloat();
if (firstConnection_ || val < 0.1) {
// ’orphan’ a few gotten connections
firstConnection_ = false;
}
else {
connections_.add(conn);
}
if (DEBUG) displayConnectionType(conn, useDefaultUid_);
if (conn instanceof com.ibm.as400.access.AS400JDBCConnectionHandle)
{ // We got a pooled connection. Try speeding up our cycle time.
if (maxSleepTime_ > 100)
maxSleepTime_--;
else
maxSleepTime_ = 100;
}
}
Note: Read the Code example disclaimer for important legal information.
You can use the FieldDescription classes can to describe the different types of data that make up an entry
on a data queue. These examples assume the following format for entries on the data queue:
Message number Sender Time sent Message text Reply required
| | | | |
bin(4) char(50) char(8) char(1024) char(1)
You can use the RecordFormat class to describe the data that makes up the data queue entry.
// Get a record based on the format of the entries on the data queue
Record rec = entryFormat.getNewRecord();
The following example defines the record format statically, which allows many programs to use the
format without coding the record format multiple times.
public class MessageEntryFormat extends RecordFormat
{
// The field descriptions are contained in the class
static BinaryFieldDescription msgNumber = new BinaryFieldDescription(new AS400Bin4(),
"msgnum");
static CharacterFieldDescription sender = new CharacterFieldDescription(new AS400Text(50),
"sender");
static CharacterFieldDescription timeSent = new CharacterFieldDescription(new AS400Text(8),
"timesent");
static CharacterFieldDescription msgText = new CharacterFieldDescription(new AS400Text(1024),
"msgtext");
static CharacterFieldDescription replyRequired = new CharacterFieldDescription(new AS400Text(1),
"replyreq");
public MessageEntryFormat()
{
// We will name this format for posterity
super("MessageEntryFormat");
// Add the field descriptions
addFieldDescription(msgNumber);
addFieldDescription(sender);
addFieldDescription(timeSent);
addFieldDescription(msgText);
addFieldDescription(replyRequired);
}
}
The following example shows how a Java program can use a statically defined RecordFormat:
MessageEntryFormat entryFormat = new MessageEntryFormat();
// Get a record based on the format of the entries on the data queue
Record rec = entryFormat.getNewRecord();
You can use the Record class to access individual fields of data queue entries.
// Read an entry
DataQueueEntry dqEntry = null;
try
// Get a record object from our record format, initializing it with the data from the entry we
// just read.
Record rec = entryFormat.getNewRecord(dqEntry.getData());
// Output the complete entry as a String. The contents of the record are converted to Java Objects
// based on the record format of the entry.
System.out.println(rec.toString());
// Get the contents of the individual fields of the entry. Each field’s contents are converted to
// a Java Object.
Integer num = (Integer)rec.getField(0); // Retrieve contents by index
String s = (String)rec.getField("sender");// Retrieve contents by field name
String text = (String)rec.getField(3); // Retrieve the message text
// Output the data
System.out.println(num + " " + s + " " + text);
You can also statically define and use a Record specific to the format of this data queue, which allows
you to provide get() and set() methods for the fields that are more meaningfully named than getField()
and setField(). Also, by using the statically defined specific Record, you can return basic Java types
instead of objects, and you can identify the return type for your user.
Note that this example must explicitly cast the correct Java object.
public class MessageEntryRecord extends Record
{
static private RecordFormat format = new MessageEntryFormat();
public MessageEntryRecord()
{
super(format);
}
We need to override the getNewRecord() method in the MessageEntryFormat class (in the example
above) in order to return a new MessageEntryRecord. To override the method, add the following to the
MessageEntryFormat class:
public Record getNewRecord(byte[] data)
{
Record r = new MessageEntryRecord();
r.setContents(data);
return r;
}
After adding the new getNewRecord() method, you can use the MessageEntryRecord to interpret the data
queue entry:
// Get a record object from our record format, initializing it with the data from the entry we
// just read. Note the use of the new overridden method getNewRecord().
MessageEntryRecord rec = (MessageEntryRecord)entryFormat.getNewRecord(dqEntry.getData());
// Output the complete entry as a String. The contents of the record are converted to Java Objects
// based on the record format of the entry.
System.out.println(rec.toString());
// Get the contents of the individual fields of the entry. Each field’s contents are converted to
// a Java Object.
int num = rec.getMessageNumber(); // Retrieve the message number as an int
String s = rec.getSender(); // Retrieve the sender
String text = rec.getMessageText(); // Retrieve the message text
// Output the data
System.out.println(num + " " + s + " " + text);
Note: Read the Code example disclaimer for important legal information.
///////////////////////////////////////////////////////////////////////////////
//
// Data Queue example. This program uses the DataQueue class to put
// records on a data queue.
//
// This example uses the Record and Record format classes to put data
// on the queue. String data is converted from Unicode to ebcdic
// and numbers are converted from Java to the server format. Because data
// is converted, entries can be read by a server program,
// an Access for Windows program, or another Java program.
//
// This is the producer side of the producer/consumer example. It puts work
// items on the queue for the consumer to process.
//
// Command syntax:
// DQProducerExample system
//
///////////////////////////////////////////////////////////////////////////////
import java.io.*;
import java.util.*;
// if the system name was not specified, display help text and exit.
if (parameters.length >= 1)
{
try
{
// The first parameter is the system that contains the data queue.
String system = parameters[0];
// Create an AS400 object for the server that has the data queue.
AS400 as400 = new AS400(system);
// Build a record format for the format of the data queue entry.
// This format matches the format in the DQConsumer class. A
// record consists of:
// - a four byte number -- the customer number
// - a four byte number -- the part number
// - a 20 character string -- the part description
// - a four byte number -- the number of parts in this order
// First create the base data types.
BinaryFieldDescription customerNumber =
new BinaryFieldDescription(new AS400Bin4(), "CUSTOMER_NUMBER");
BinaryFieldDescription partNumber =
new BinaryFieldDescription(new AS400Bin4(), "PART_NUMBER");
CharacterFieldDescription partName =
new CharacterFieldDescription(new AS400Text(20, as400), "PART_NAME");
BinaryFieldDescription quantity =
new BinaryFieldDescription(new AS400Bin4(), "QUANTITY");
// Build a record format and fill it with the base data types.
RecordFormat dataFormat = new RecordFormat();
dataFormat.addFieldDescription(customerNumber);
dataFormat.addFieldDescription(partNumber);
dataFormat.addFieldDescription(partName);
dataFormat.addFieldDescription(quantity);
// Create the data queue just in case this is the first time this
// program has run. The queue already exists exception is caught
// and ignored.
try
{
dq.create(96);
}
catch (Exception e) {};
// Set the values we received from the user into the record.
data.setField("CUSTOMER_NUMBER", new Integer(customer));
data.setField("PART_NUMBER", new Integer(part));
data.setField("QUANTITY", new Integer(quantityToOrder));
data.setField("PART_NAME", description);
System.out.println("");
System.out.println("Writing record to the server ...");
System.out.println("");
System.exit(0);
}
// This is the subroutine that gets a character string from the user
// and converts it into an int.
static int getInt()
{
int i = 0;
boolean Continue = true;
while (Continue)
{
try
{
String s = inputStream.readLine();
i = (new Integer(s)).intValue();
Continue = false;
}
catch (Exception e)
{
System.out.println(e);
System.out.print("Please enter a number ==>");
}
}
return i;
}
}
Note: Read the Code example disclaimer for important legal information.
///////////////////////////////////////////////////////////////////////////////
//
// Data Queue example. This program uses the Data Queue classes to read
// entries off a data queue on the server. The entries were put on the
// queue with the DQProducer example program.
//
// This is the consumer side of the producer/consumer example. It reads
// entries off the queue and process them.
//
// Command syntax:
// DQConsumerExample system
//
///////////////////////////////////////////////////////////////////////////////
import java.io.*;
import java.util.*;
import java.net.*;
import com.ibm.as400.access.*;
// if a system name was not specified, display help text and exit.
if (parameters.length >= 1)
{
try
{
// The first parameter is the system that contains the data queue.
String system = parameters[0];
// Create an AS400 object for the server that has the data queue.
AS400 as400 = new AS400(system);
// Build a record format for the format of the data queue entry.
// This format matches the format in the DQProducer class. A
// record consists of:
// - a four byte number -- the customer number
// - a four byte number -- the part number
// - a 20 character string -- the part description
// - a four byte number -- the number of parts in this order
BinaryFieldDescription partNumber =
new BinaryFieldDescription(new AS400Bin4(), "PART_NUMBER");
CharacterFieldDescription partName =
new CharacterFieldDescription(new AS400Text(20, as400), "PART_NAME"
BinaryFieldDescription quantity =
new BinaryFieldDescription(new AS400Bin4(), "QUANTITY"
// Build a record format and fill it with the base data types.
RecordFormat dataFormat = new RecordFormat();
dataFormat.addFieldDescription(customerNumber);
dataFormat.addFieldDescription(partNumber);
dataFormat.addFieldDescription(partName);
dataFormat.addFieldDescription(quantity);
// Create the data queue object that represents the data queue on
// the server.
DataQueue dq = new DataQueue(as400, "/QSYS.LIB/JAVADEMO.LIB/PRODCONS.DTAQ");
// Read the first entry off the queue. The timeout value is
// set to -1 so this program will wait forever for an entry.
System.out.println("*** Waiting for an entry for process ***");
while (Continue)
{
// We just read an entry off the queue. Put the data into
// a record object so the program can access the fields of
// the data by name. The Record object will also convert
// the data from server format to Java format.
Record data = dataFormat.getNewRecord(DQData.getData());
System.exit(0);
}
}
Note: Read the Code example disclaimer for important legal information.
The following example shows how to use AS400DataType classes by using ProgramCall to call the system
API, QUSRMBRD "Retrieve Member Description". The QUSRMBRD API retrieves the description of a
specific member in a database file. The tables following the example list the required QUSRMBRD
parameters and the types of information that the example retrieves.
// Create a ProgramCall object. We will set the program name and
// parameter list later.
ProgramCall qusrmbrd = new ProgramCall(new AS400());
// For the output parameter we need only specify how many bytes will
// be returned
parms[0] = new ProgramParameter(135);
parms[1] = new ProgramParameter(bin4.toBytes(new Integer(135)));
parms[2] = new ProgramParameter(char8Converter.toBytes("MBRD0100"));
parms[3] = new ProgramParameter(char20Converter.toBytes("MYFILE MYLIB "));
parms[4] = new ProgramParameter(char10COnverter.toBytes("MYMEMBER "));
parms[5] = new ProgramParameter(char1Converter.toBytes("0"));
// Get the information retrieved. Note that this is raw server data.
byte[] receiverVar = parms[0].getOutputData();
The following table lists the required parameters for the QUSRMBRD API as used in the preceding
example.
The following table lists the type of information that the example retrieves (based on format MBRD0100,
as specified in the preceding example):
Note: Read the Code example disclaimer for important legal information.
///////////////////////////////////////////////////////////////////////////////
//
// Data Queue example. This program uses the KeyedDataQueue class to put
// records on a data queue.
//
// The key is a number and the data is a Unicode string. This program
// shows one way to convert on int into a byte array and how to convert
// a Java string into a byte array so it can be written to the queue.
//
// This is the producer side of the producer/consumer example. It puts work
// items on the queue for the consumer to process.
//
// Command syntax:
// DQKeyedProducer system
//
///////////////////////////////////////////////////////////////////////////////
import java.io.*;
import java.util.*;
import java.net.*;
import com.ibm.as400.access.*;
// if the system name was not specified, display help text and exit.
if (parameters.length >= 1)
{
// The first parameter is the system that contains the data queue.
try
{
// Create an AS400 object for the server that has the data queue.
// Create the data queue just in case this is the first time this
// program has run. The queue already exists exception is caught
// and ignored. The length of the key is four bytes, the length
// of an entry is 96 bytes.
try
{
dq.create(4, 96);
}
catch (Exception e) {};
System.out.println("");
System.out.println("Writing record to the server...");
System.out.println("");
dq.write(byteKey, byteData);
else
{
System.out.println("");
System.out.println("");
System.out.println("");
System.out.println("Parameters are not correct. Command syntax is:");
System.out.println("");
System.out.println(" DQKeyedProducter system");
System.out.println("");
System.out.println("Where");
System.out.println("");
System.out.println(" system = server that has the data queue");
System.out.println("");
System.out.println("For example:");
System.out.println("");
System.out.println(" DQKeyedProducer mySystem");
System.out.println("");
System.out.println("");
}
System.exit(0);
}
// This is the subroutine that gets a character string from the user
// and converts it into an int.
while (Continue)
{
try
{
String s = inputStream.readLine();
i = (new Integer(s)).intValue();
Continue = false;
}
catch (Exception e)
{
System.out.println(e);
System.out.print("Please enter a number ==>");
}
}
return i;
}
}
Note: Read the Code example disclaimer for important legal information.
///////////////////////////////////////////////////////////////////////////////
//
// Keyed Data Queue example. This program uses the KeyedDataQueue classes to
// read entries off a data queue on the server. The entries were put on the
import java.io.*;
import java.util.*;
import java.net.*;
import com.ibm.as400.access.*;
// if a system name was not specified, display help text and exit.
if (parameters.length >= 1)
{
// The first parameter is the system that contains the data queue.
String system = parameters[0];
try
{
// Create an AS400 object for the server that has the data queue.
AS400 as400 = new AS400(system);
// Create the data queue object that represents the data queue
// on the server.
try
{
boolean Continue = true;
if (DQData != null)
{
processEntry(DQData);
}
if (DQData != null)
{
processEntry(DQData);
}
if (DQData != null)
{
processEntry(DQData);
}
else
{
System.out.println("Nothing to process, will check again in 30 seconds");
Thread.sleep(30000);
}
}
}
}
}
catch (Exception e)
{
// If any of the above operations failed say the data queue
// operation failed and output the exception.
System.out.println("Could not read from the data queue.");
System.out.println(e);
};
}
catch (Exception e)
{
// If any of the above operations failed say the data queue
// operation failed and output the exception.
System.exit(0);
}
// The key is a byte array. Get the key out of the data queue entry
// and convert it into a number.
byte [] keyData = DQData.getKey();
}
catch (Exception e)
{
// If any of the above operations failed say the data queue operation
// failed and output the exception.
Note: Read the Code example disclaimer for important legal information.
When an error occurs, the IFSFile class throws the ExtendedIOException exception. This exception
contains a return code that indicates the cause of the failure. The IFSFile class throws the exception even
when the java.io class that IFSFile duplicates does not. For example, the delete method from java.io.File
returns a boolean to indicate success or failure. The delete method in IFSFile returns a boolean, but if the
delete fails, an ExtendedIOException is thrown. The ExtendedIOException provides the Java program
with detailed information about why the delete failed.
// Create an AS400 object.
AS400 sys = new AS400("mySystem.myCompany.com");
switch (rc)
case ExtendedIOException.PATH_NOT_FOUND:
System.out.println("Delete failed, path not found ");
break;
default:
System.out.println("Delete failed, rc = ");
System.out.println(rc);
}
}
The Java program can optionally specify match criteria when listing files in the directory. Match criteria
reduce the number of files that are returned by the server to the IFSFile object, which improves
performance. The following example shows how to list files with extension .txt:
// Create the AS400 object.
AS400 system = new AS400("mySystem.myCompany.com");
Example: Using the IFSFile listFiles() method to list the contents of a directory
This example program uses the IBM Toolbox for Java IFS classes to list the contents of a directory on the
server.
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// IFSListFiles example. This program uses the integrated file system
// classes to list the contents of a directory on the server.
//
// Command syntax:
// IFSListFiles system directory
//
// For example,
// IFSListFiles MySystem /path1
//
//////////////////////////////////////////////////////////////////////////////////
import java.io.*;
import java.util.*;
import com.ibm.as400.access.*;
// if both parameters were not specified, display help text and exit.
if (parameters.length >= 2)
{
system = parameters[0];
directoryName = parameters[1];
try
{
// Create an AS400 object for the server that holds the files.
if (directoryFiles == null)
{
System.out.println("The directory does not exist");
return;
}
else if (directoryFiles.length == 0)
{
System.out.println("The directory is empty");
return;
}
System.out.print(directoryFiles[i].getName());
System.out.print(" ");
if (directoryFiles[i].isDirectory())
System.out.println("");
else
System.out.println(directoryFiles[i].length());
}
}
catch (Exception e)
{
// If any of the above operations failed say the list failed
// and output the exception.
System.out.println("List failed");
System.out.println(e);
}
}
else
{
System.out.println("");
System.out.println("");
System.out.println("");
System.out.println("Parameters are not correct. Command syntax is:");
System.out.println("");
System.out.println(" IFSListFiles as400 directory");
System.out.println("");
System.out.println("Where");
System.out.println("");
System.out.println(" as400 = system that contains the files");
System.out.println(" directory = directory to be listed");
System.out.println("");
System.out.println("For example:");
System.out.println("");
System.out.println(" IFSListFiles mySystem /dir1/dir2");
System.out.println("");
System.out.println("");
}
System.exit(0);
}
}
////////////////////////////////////////////////////////////////////////////
//
// The directory filter class prints information from the file object.
//
return true;
}
catch (Exception e)
{
return false;
}
}
}
Example: Using IFS classes to copy a file from one directory to another
This program uses the installable file system classes to copy a file from one directory to another on the
server.
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// IFSCopyFile example. This program uses the installable file system classes
// to copy a file from one directory to another on the server.
//
// Command syntax:
// IFSCopyFile system sourceName TargetName
//
// For example,
// IFSCopyFile MySystem /path1/path2/file.ext /path3/path4/path5/file.ext
//
//////////////////////////////////////////////////////////////////////////////////
import java.io.*;
import java.util.*;
import com.ibm.as400.access.*;
if (parameters.length > 2)
{
system = parameters[0];
sourceName = parameters[1];
targetName = parameters[2];
try
{
// Create an AS400 object for the server that holds the files.
// While there is data in the source file copy the data from
// the source file to the target file.
source.close();
target.close();
// Get the last changed date/time from the source file and
// set it on the target file.
}
catch (Exception e)
{
// If any of the above operations failed say the copy failed
// and output the exception.
System.out.println("Copy failed");
System.out.println(e);
}
}
else
{
System.out.println("");
System.out.println("");
System.out.println("");
System.out.println("Parameters are not correct. Command syntax is:");
System.out.println("");
System.out.println(" IFSCopyFile as400 source target");
System.out.println("");
System.out.println("Where");
System.out.println("");
System.out.println(" as400 = system that contains the files");
System.out.println(" source = source file in /path/path/name format");
System.out.println(" target = target file in /path/path/name format");
System.out.println("");
System.out.println("For example:");
System.out.println("");
System.out.println(" IFSCopyFile myAS400 /dir1/dir2/a.txt /dir3/b.txt");
System.out.println("");
System.out.println("");
}
System.exit(0);
}
}
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// IFSListFile example. This program uses the integrated file system classes
// to list the contents of a directory on the server.
//
// Command syntax:
// IFSList system directory
//
// For example,
// IFSList MySystem /path1
//
//////////////////////////////////////////////////////////////////////////////////
import java.io.*;
// if both parameters were not specified, display help text and exit.
if (parameters.length >= 2)
{
system = parameters[0];
directoryName = parameters[1];
try
{
// Create an AS400 object for the server that holds the files.
if (directoryNames == null)
System.out.println("The directory does not exist");
else if (directoryNames.length == 0)
System.out.println("The directory is empty");
}
catch (Exception e)
{
// If any of the above operations failed say the list failed
// and output the exception.
System.out.println("List failed");
System.out.println(e);
}
}
else
{
System.out.println("");
System.out.println("");
System.out.println("");
System.out.println("Parameters are not correct. Command syntax is:");
System.out.println("");
System.out.println(" IFSList as400 directory");
System.out.println("");
System.out.println("Where");
System.out.println("");
System.out.println(" as400 = system that contains the files");
System.out.println(" directory = directory to be listed");
System.out.println("");
System.out.println("For example:");
System.out.println("");
System.out.println(" IFSCopyFile mySystem /dir1/dir2");
System.out.println("");
System.out.println("");
}
System.exit(0);
}
}
////////////////////////////////////////////////////////////////////////////
//
// The directory filter class prints information from the file object.
//
// Another way to use the filter is to simply return true or false
// based on information in the file object. This lets the mainline
// function decide what to do with the list of files that meet the
// search criteria.
//
////////////////////////////////////////////////////////////////////////////
System.out.print(file.getName());
System.out.print(" ");
if (file.isDirectory())
System.out.println("<DIR>");
else
System.out.println(file.length());
return true;
}
catch (Exception e)
{
return false;
}
}
}
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// JDBCPopulate example. This program uses the IBM Toolbox for Java JDBC driver to
// create and populate a table.
//
// Command syntax:
// JDBCPopulate system collectionName tableName
//
// For example,
// JDBCPopulate MySystem MyLibrary MyTable
//
//////////////////////////////////////////////////////////////////////////////////
import java.sql.*;
try {
finally {
// Clean up.
try {
if (connection != null)
connection.close ();
}
catch (SQLException e) {
// Ignore.
}
}
System.exit (0);
}
Note: By using the code examples, you agree to the terms of the “Code license and disclaimer
information” on page 760.
Example 1
This brief example shows the basic use of the AS400JDBCManagedConnectionPoolDataSource class.
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import com.ibm.as400.access.AS400JDBCManagedConnectionPoolDataSource;
import com.ibm.as400.access.AS400JDBCManagedDataSource;
// Set general datasource properties. Note that both connection pool datasource (CPDS) and managed
// datasource (MDS) have these properties, and they might have different values.
cpds0.setServerName(host);
cpds0.setDatabaseName(host);//iasp can be here
cpds0.setUser(userid);
cpds0.setPassword(password);
cpds0.setSavePasswordWhenSerialized(true);
Connection c = dataSource_.getConnection();
Example 2
This example shows more details about how to use the AS400JDBCManagedConnectionPoolDataSource
class.
import java.awt.TextArea;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Vector;
import java.util.Properties;
import java.sql.Connection;
import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.naming.*;
import java.util.Date;
import java.util.ArrayList;
import java.util.Random;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400JDBCManagedConnectionPoolDataSource;
import com.ibm.as400.access.AS400JDBCManagedDataSource;
import com.ibm.as400.access.Trace;
// If you turn this flag on, be sure to also turn on the following flag:
// AS400JDBCConnection.TESTING_THREAD_SAFETY.
private static final boolean TESTING_THREAD_SAFETY = false;
// Note: For consistency, all time values are stored units of milliseconds.
private int initialPoolSize_; // initial # of connections in pool
private boolean keepDaemonsAlive_ = true; // When this is false, the daemons shut down.
static
{
try {
Class.forName("com.ibm.as400.access.AS400JDBCDriver");
}
catch(Exception e){
System.out.println("Unable to register JDBC driver.");
System.exit(0);
}
}
cptest.setup();
cptest.runTest();
}
if (TESTING_THREAD_SAFETY)
{
// Adjust values for performing thread-intensive stress testing.
// NOTE: This assumes that the AS400JDBCConnection class has also been modified to
// not make actual connections to an actual server.
// To do this, edit AS400JDBCConnection.java, changing its TESTING_THREAD_SAFETY
// flag to ’false’, and recompile.
minPoolSize_ = 100;
maxPoolSize_ = 190;
initialPoolSize_ = 150; // this should get reset to maxPoolSize_
numDaemons_ = 75;
if (timeToRunDaemons_ == 0) {
timeToRunDaemons_ = 180*1000; // 180 seconds == 3 minutes
}
}
else
{ // Set more conservative values, as we’ll be making actual connections to an
// actual server, and we don’t want to monopolize the server.
minPoolSize_ = 5;
maxPoolSize_ = 15;
initialPoolSize_ = 9;
numDaemons_ = 4;
if (timeToRunDaemons_ == 0) {
timeToRunDaemons_ = 15*1000; // 15 seconds
}
}
if (DEBUG)
System.out.println("setup: Constructing "
+ "AS400JDBCManagedConnectionPoolDataSource (cpds0)");
AS400JDBCManagedConnectionPoolDataSource cpds0 =
new AS400JDBCManagedConnectionPoolDataSource();
// Set datasource properties. Note that both CPDS and MDS have these
// properties, and they might have different values.
cpds0.setServerName(host);
cpds0.setDatabaseName(host);//iasp can be here
cpds0.setUser(userid);
cpds0.setPassword(password);
cpds0.setSavePasswordWhenSerialized(true);
ctx.rebind("mydatasource", cpds0);
// We can now do lookups on cpds, by the name"mydatasource".
if (DEBUG)
System.out.println("setup: lookup(\"mydatasource\"" + ")");
// AS400JDBCManagedConnectionPoolDataSource cpds1 =
// (AS400JDBCManagedConnectionPoolDataSource)ctx.lookup("mydatasource");
// if (DEBUG) System.out.println("setup: cpds1.getUser() == |" + cpds1.getUser() + "|");
if (DEBUG)
System.out.println("setup: Constructing AS400JDBCManagedDataSource (mds0)");
AS400JDBCManagedDataSource mds0 = new AS400JDBCManagedDataSource();
mds0.setDescription("DataSource supporting connection pooling");
mds0.setDataSourceName("mydatasource");
ctx.rebind("ConnectionPoolingDataSource", mds0);
if (DEBUG)
System.out.println("setup: lookup(\"ConnectionPoolingDataSource\"" + ")");
dataSource_ = (DataSource)ctx.lookup("ConnectionPoolingDataSource");
//dataSource_.setLogWriter(output_);
if (DEBUG)
System.out.println("setup: dataSource_.getUser() == |" +
((AS400JDBCManagedDataSource)dataSource_).getUser() + "|");
mds_ = (AS400JDBCManagedDataSource)dataSource_;
}
catch (Exception e)
{
e.printStackTrace();
System.out.println("Setup error during Trace file creation.");
}
/**
* Gets and returns connections from and to a connection pool for a while.
**/
public void runTest()
{
boolean ok = true;
try
{
System.out.println("Started test run at " + new Date());
if (DEBUG)
System.out.println("Checking health just after datasource creation "
+ "(we expect that the pool does not exist yet) ...");
if (mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool exists prior to first getConnection().");
}
mds_.setAccess("read only");
if (!mds_.getAccess().equals("read only")) {
ok = false;
System.out.println("\nERROR: getAccess() returned unexpected value: "
+ "|" + mds_.getAccess()+"|");
}
oldBool = mds_.isKeepAlive();
newBool = (oldBool ? false : true);
mds_.setKeepAlive(newBool);
if (mds_.isKeepAlive() != newBool) {
ok = false;
System.out.println("\nERROR: isKeepAlive() returned unexpected value: "
+ "|"+mds_.isKeepAlive()+"|");
}
mds_.setKeepAlive(oldBool);
oldInt = mds_.getReceiveBufferSize();
newInt = (oldInt == 256 ? 512 : 256);
mds_.setReceiveBufferSize(newInt);
if (mds_.getReceiveBufferSize() != newInt) {
ok = false;
System.out.println("\nERROR: getReceiveBufferSize() returned unexpected value: "
+ "|"+mds_.getReceiveBufferSize()+"|");
}
System.out.println("CONNECTION 1");
Object o = dataSource_.getConnection();
System.out.println(o.getClass());
System.out.println("******LOOK ABOVE*******");
Connection c1 = dataSource_.getConnection();
if (DEBUG)
displayConnectionType(c1, true);
if (DEBUG)
System.out.println("Checking health after first getConnection() ...");
if (!mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool is not healthy after first getConnection().");
}
if (!TESTING_THREAD_SAFETY)
{
try
{
c1.setAutoCommit(false);
if (DEBUG)
System.out.println("SELECT * FROM QIWS.QCUSTCDT");
Statement s = c1.createStatement();
ResultSet rs = s.executeQuery("SELECT * FROM QIWS.QCUSTCDT");
while(rs.next()){
if (DEBUG)
System.out.println(rs.getString(2));
}
rs.close();
s.close();
}
catch (Exception e) {
e.printStackTrace();
if (DEBUG)
System.out.println("Checking health after fatal connection error ...");
if (!mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool is not healthy after fatal connection "
+ "error.");
}
}
}
System.out.println("CONNECTION 2");
Connection c2 = dataSource_.getConnection(userid, password);
if (DEBUG)
displayConnectionType(c2, false);
System.out.println("CONNECTION 3");
Connection c3 = dataSource_.getConnection();
if (DEBUG)
displayConnectionType(c3, true);
c1.close();
if (DEBUG)
System.out.println("Checking health after first close() ...");
if (!mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool is not healthy after first close().");
}
System.out.println("CONNECTION 4");
Connection c4 = dataSource_.getConnection();
if (DEBUG) displayConnectionType(c4, true);
// Run the test daemons for a while; check pool health periodically.
if (DEBUG)
System.out.println("Checking health after connectionGetter daemons have run...");
if (!mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool is not healthy after test daemons stopped.");
}
if (!TESTING_THREAD_SAFETY)
{
System.out.println("CONNECTION 5");
Connection c = dataSource_.getConnection();
if (DEBUG) displayConnectionType(c, true);
c.setAutoCommit(false);
if (DEBUG) System.out.println("SELECT * FROM QIWS.QCUSTCDT");
Statement s = c.createStatement();
ResultSet rs = s.executeQuery("SELECT * FROM QIWS.QCUSTCDT");
while(rs.next()){
if (DEBUG) System.out.println(rs.getString(2));
}
rs.close();
s.close();
c.close();
}
if (DEBUG)
System.out.println("Checking health after pool closed ...");
Trace.setTraceJDBCOn(true); // make sure the final stats get printed out
Trace.setTraceOn(true);
if (!mds_.checkPoolHealth(true)) {
ok = false;
System.out.println("\nERROR: Pool is not healthy after pool closed.");
}
System.out.println();
if(ok==true)
System.out.println("test ran ok");
else
System.out.println("test failed");
}
catch (Exception e)
{
System.out.println(e);
e.printStackTrace();
}
finally {
System.out.println("Ended test at " + new Date());
}
}
void startThreads()
void stopThreads()
{
// Tell the threads to stop.
keepDaemonsAlive_ = false;
synchronized (daemonSleepLock_) {
daemonSleepLock_.notifyAll();
}
// ConnectionGetter --------------------------------------------------------------------
/**
Helper class. This daemon wakes up at random intervals and either
gets another connection from the connection pool or returns a
previously-gotten connection to the pool.
**/
private final class ConnectionGetter implements Runnable
{
private String uid_;
private String pwd_;
private boolean useDefaultUid_;
private long maxSleepTime_;
private String threadName_;
private boolean firstConnection_ = true;
ArrayList connections_ = new ArrayList();
// list of connections that this getter currently ’owns’.
try
if (conn == null) {
System.out.println("ConnectionGetter("+threadName_+") ERROR: "
+ "getConnection() returned null");
}
else
{
// Occasionally "forget" that we own a connection, and neglect to
// close it.
// Orphaned connections should eventually exceed their maximum
// lifetime and get "reaped" by the connection manager.
float val = random_.nextFloat();
if (firstConnection_ || val < 0.1) {
// ’orphan’ a few gotten connections
firstConnection_ = false;
}
else {
connections_.add(conn);
}
if (DEBUG) displayConnectionType(conn, useDefaultUid_);
if (conn instanceof com.ibm.as400.access.AS400JDBCConnectionHandle)
{ // We got a pooled connection. Try speeding up our cycle time.
if (maxSleepTime_ > 100)
maxSleepTime_--;
else
maxSleepTime_ = 100;
}
else
{ // We didn’t get a pooled connection. That means that the pool
// must be at capacity. Slow down our cycle time a bit.
maxSleepTime_ = maxSleepTime_ + 50;
}
}
}
else { // Close a connection that we currently own.
if (connections_.size() != 0) {
conn = (Connection)connections_.remove(0);
conn.close();
}
}
} // inner try
catch (Exception e)
{
}
}
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// JDBCQuery example. This program uses the IBM Toolbox for Java JDBC driver to
// query a table and output its contents.
//
// Command syntax:
// JDBCQuery system collectionName tableName
//
// For example,
// JDBCQuery MySystem qiws qcustcdt
//
//////////////////////////////////////////////////////////////////////////////////
import java.sql.*;
return formattedString;
}
try {
catch (Exception e) {
System.out.println ();
System.out.println ("ERROR: " + e.getMessage());
}
finally {
// Clean up.
try {
if (connection != null)
connection.close ();
}
catch (SQLException e) {
// Ignore.
}
}
System.exit (0);
}
Note: Read the Code example disclaimer for important legal information.
///////////////////////////////////////////////////////////////////////////
//
// This program is an example of the Job support in the IBM Toolbox
// for Java. It lists job identification information for a specific
// user on the system.
//
// Command syntax:
// listJobs2 system userID password
//
/////////////////////////////////////////////////////////////////////////
import java.io.*;
import java.lang.*;
import java.util.*;
import com.ibm.as400.access.*;
System.exit(0);
}
if (parameters.length > 1)
userID = parameters[1].toUpperCase();
if (parameters.length >= 2)
password = parameters[2].toUpperCase();
System.out.println(" ");
try
{
if (userID != null)
as400.setUserId(userID);
if (password != null)
as400.setPassword(password);
if (userID != null)
{
if (j.getUser().trim().equalsIgnoreCase(userID))
{
System.out.println(j.getName().trim() + "." +
j.getUser().trim() + "." +
j.getNumber());
}
}
else
System.out.println(j.getName().trim() + "." +
j.getUser().trim() + "." +
j.getNumber());
}
}
catch (Exception e)
{
System.out.println("Unexpected error");
e.printStackTrace();
}
}
Note: Read the Code example disclaimer for important legal information.
///////////////////////////////////////////////////////////////////////////
//
// This program is an example of the "job" classes in the
// IBM Toolbox for Java. It gets a list of jobs on the server
// and outputs the job’s status followed by job identifier.
import java.io.*;
import java.util.*;
import com.ibm.as400.access.*;
System.exit(0);
}
// Set up AS400 object parms. The first is the system name and must
// be specified by the user. The second and third are optional. They
// are the userid and password. Convert the userid and password
// to uppercase before setting them on the AS400 object.
String userID = null;
String password = null;
if (parameters.length > 1)
userID = parameters[1].toUpperCase();
if (parameters.length >= 2)
password = parameters[2].toUpperCase();
System.out.println(" ");
try
{
// Create an AS400 object using the system name specified by the user.
AS400 as400 = new AS400(parameters[0]);
if (password != null)
as400.setPassword(password);
// Create a job list object. Input parm is the AS400 we want job
// information from.
JobList jobList = new JobList(as400);
// For each job in the list print information about the job.
while (listOfJobs.hasMoreElements())
{
printJobInfo((Job) listOfJobs.nextElement(), as400);
}
}
catch (Exception e)
{
System.out.println("Unexpected error");
System.out.println(e);
}
}
// The second parm is the size of our output data buffer (1K).
Integer iStatusLength = new Integer( 1024 );
byte[] statusLength = bin4Converter.toBytes( iStatusLength );
parmlist[1] = new ProgramParameter( statusLength );
// The fourth parm is the job name is format "name user number".
// Name must be 10 characters, user must be 10 characters and
// number must be 6 characters. We will use a text converter
// to do the conversion and padding.
byte[] jobName = text26Converter.toBytes(job.getName());
int i = text10Converter.toBytes(job.getUser(),
jobName,
10);
System.out.println(job.getName().trim() + "." +
job.getUser().trim() + "." +
job.getNumber() + " ");
}
}
catch (Exception e)
{
System.out.println(e);
}
Note: Read the Code example disclaimer for important legal information.
///////////////////////////////////////////////////////////////////////////
//
// This program is an example of the job log fuction of the
// IBM Toolbox for Java. It will display the messages in the job
// log for a job that belongs to the current user.
//
// Command syntax:
// jobLogExample system userID password
//
// (Password is optional)
//
/////////////////////////////////////////////////////////////////////////
import java.lang.*;
import java.util.*;
import com.ibm.as400.access.*;
try
{
// Create an AS400 object. The system name was passed
// as the first command line argument. If a userid
// and password were passed on the command line,
// set those as well.
AS400 system = new AS400 (args[0]);
if (args.length > 1)
{
userID = args[1];
system.setUserId(userID);
}
if (args.length > 2)
system.setPassword(args[2]);
if (j.getUser().trim().equalsIgnoreCase(userID))
{
// A job matching the current user was found. Create
// a job log object for this job.
JobLog jlog = new JobLog(system, j.getName(), j.getUser(), j.getNumber());
while (messageList.hasMoreElements())
{
AS400Message message = (AS400Message) messageList.nextElement();
System.out.println(message.getText());
}
System.exit(0);
}
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// Example that shows creating a spooled file on a server from an input stream.
//
/////////////////////////////////////////////////////////////////////////
import java.io.*;
import java.util.*;
import com.ibm.as400.access.*;
class NPExampleCreateSplf
{
// method to create the spooled file on the specified server, in the specified
// output queue from the given input stream.
public SpooledFile createSpooledFile(AS400 system, OutputQueue outputQueue, InputStream in)
{
SpooledFile spooledFile = null;
try
{
byte[] buf = new byte[2048];
int bytesRead;
SpooledFileOutputStream out;
PrintParameterList parms = new PrintParameterList();
// read from the inputstream in until end of stream, passing all data
// to the spooled file output stream.
do
{
bytesRead = in.read(buf);
if (bytesRead != -1)
{
out.write(buf, 0, bytesRead);
}
} while (bytesRead != -1);
}
catch (Exception e)
{
//...handle exception...
}
return spooledFile;
}
This application can take the following arguments, or it can use the defined defaults:
v Name of the server to receive the spooled file.
v Name of the outqueue on the server to receive the spooled file.
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// This source is an example of IBM Toolbox for Java "SCS3812Writer".
//
/////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
class NPExampleCreateSCSSplf
{
private static final String DEFAULT_SYSTEM = new String("RCHAS1");
private static final String DEFAULT_OUTQ = new String("/QSYS.LIB/QUSRSYS.LIB/PRT01.OUTQ");
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// Example that reads an existing server spooled file.
//
// This source is an example of IBM Toolbox for Java "PrintObjectInputStream".
//
/////////////////////////////////////////////////////////////////////////
try{
byte[] buf = new byte[2048];
int bytesRead;
AS400 sys = new AS400();
SpooledFile splf = new SpooledFile( sys, // AS400
"MICR", // splf name
17, // splf number
"QPRTJOB", // job name
"QUSER", // job user
"020791" ); // job number
// open the spooled file for reading and get the input stream to
// read from it.
InputStream in = splf.getInputStream(null);
do
{
// read up to buf.length bytes of raw spool data into
// our buffer. The actual bytes read will be returned.
// The data will be a binary printer data stream that is the
// contents of the spooled file.
bytesRead = in.read( buf );
if( bytesRead != -1 )
{
// process the spooled file data.
System.out.println( "Read " + bytesRead + " bytes" );
}
} while( bytesRead != -1 );
in.close();
}
Example of PrintObjectPageInputStream
Note: Read the Code example disclaimer for important legal information.
The following example shows how to create a PrintObjectPageInputStream object for reading pages of
data formatted as GIF images. In this case, each page from the spooled file will be transformed into a GIF
image. A GIF workstation customization object is used to specify the data transform.
// Create a spooled file
SpooledFile splF = createSpooledFile();
Example of PrintObjectTransformedInputStream
Note: Read the Code example disclaimer for important legal information.
The following example shows how to create a PrintObjectTransformedInputStream object for reading data
formatted as TIFF. A TIFF (G4 compression) workstation customization object is used to specify the data
transform.
// Create a spooled file
SpooledFile splF = createSpooledFile();
Note: Read the Code example disclaimer for important legal information.
The following example shows how to create a PrintObjectTransformedInputStream object for reading data
formatted for output to an ASCII printer. A manufacturer type and model of *HP4 is used to specify the
data transform.
// Create a spooled file
SpooledFile splF = createSpooledFile();
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// Example that shows listing all spooled files on a server asynchronously using
// the PrintObjectListListener interface to get feedback as the list is being built.
// Listing asynchronously allows the caller to start processing the list objects
// before the entire list is built for a faster perceived response time
// for the user.
//
/////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.SpooledFileList;
import com.ibm.as400.access.SpooledFile;
import com.ibm.as400.access.ExtendedIllegalStateException;
import com.ibm.as400.access.PrintObjectListListener;
import com.ibm.as400.access.PrintObjectListEvent;
try
{
String strSpooledFileName;
boolean fCompleted = false;
int listed = 0, size;
do
{
// wait for the list to have at least 25 objects or to be done
waitForWakeUp();
fCompleted = splfList.isCompleted();
size = splfList.size();
if (fListClosed)
{
System.out.println(" The list was closed before it completed!");
break;
}
} while (!fCompleted);
catch( ExtendedIllegalStateException e )
{
System.out.println(" The list was closed before it completed!");
}
catch( Exception e )
{
// ...handle any other exceptions...
e.printStackTrace();
}
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// This example lists all spooled files on a system asynchronously without
// using the PrintObjectListListener interface. After opening the list the caller
// can do some additional work before waiting for the list to complete.
//
/////////////////////////////////////////////////////////////////////////
//
// This source is an example of IBM Toolbox for Java "PrintObjectList".
//
/////////////////////////////////////////////////////////////////////////
import java.util.Enumeration;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.SpooledFileList;
import com.ibm.as400.access.SpooledFile;
System.out.println(
"Now receiving all spooled files Asynchronously without using a listener");
catch( Exception e )
{
// ...handle any exceptions...
e.printStackTrace();
}
}
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// Example that shows listing all spooled files on a server synchronously.
// Listing synchronously does not return to the caller until the complete list
// is built. The user perceives a slower response time then listing asynchronously.
//
/////////////////////////////////////////////////////////////////////////
//
// This source is an example of IBM Toolbox for Java "PrintObjectList".
//
/////////////////////////////////////////////////////////////////////////
import java.util.Enumeration;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.SpooledFileList;
import com.ibm.as400.access.SpooledFile;
while( enum.hasMoreElements() )
{
SpooledFile splf = (SpooledFile)enum.nextElement();
if ( splf != null )
{
// output this spooled file’s name
strSpooledFileName = splf.getStringAttribute(SpooledFile.ATTR_SPOOLFILE);
System.out.println(" spooled file = " + strSpooledFileName);
}
}
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// Program call example. This program calls the QWCRSSTS server program
// to retrieve the status of the system.
//
// Command syntax:
// PCSystemStatusExample system
//
// This source is an example of IBM Toolbox for Java "ProgramCall".
//
/////////////////////////////////////////////////////////////////////////
import java.io.*;
import java.util.*;
import java.math.*;
import java.lang.Thread.*;
import com.ibm.as400.access.*;
if (parameters.length >= 1)
{
try
{
// Create an AS400 object for the server that contains the
// program. Assume the first parameter is the system name.
// Create the program call object. Assocate the object with the
// AS400 object that represents the server we get status from.
// Set the program to call and the parameter list to the program
// call object.
getSystemStatus.setProgram(programName.getPath(), parmlist );
// Run the program then sleep. We run the program twice because
// the first set of results are inflated. If we discard the first
// set of results and run the command again five seconds later the
// number will be more accurate.
getSystemStatus.run();
Thread.sleep(5000);
if (getSystemStatus.run()!=true)
{
// If the program did not run get the list of error messages
// from the program object and display the messages. The error
// would be something like program-not-found or not-authorized
// to the program.
else
{
as400.disconnectService(AS400.COMMAND);
}
catch (Exception e)
{
// If any of the above operations failed say the program failed
// and output the exception.
else
{
System.out.println("");
System.out.println("");
System.out.println("");
System.out.println("Parameters are not correct. Command syntax is:");
System.out.println("");
System.out.println(" PCSystemStatusExample myServer");
System.out.println("");
System.out.println("Where");
System.out.println("");
System.out.println(" myServer = get status of this server ");
System.out.println("");
System.out.println("For example:");
System.out.println("");
System.out.println(" PCSystemStatusExample mySystem");
System.out.println("");
System.out.println("");
}
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// Record level access example. This program will prompt the user
// for the name of the server and the file to display. The file must exist
// and contain records. Each record in the file will be displayed
// to System.out.
//
// Calling syntax: java RLSequentialAccessExample
//
// This source is an example of IBM Toolbox for Java "RecordLevelAccess"
//
//////////////////////////////////////////////////////////////////////////////////
import java.io.*;
import java.util.*;
import com.ibm.as400.access.*;
// Declare variables to hold the system name, library, file and member names
String systemName = "";
String library = "";
String file = "";
String member = "";
// Get the system name and and file to display from the user
System.out.println();
try
{
System.out.print("System name: ");
systemName = inputStream.readLine();
System.out.println();
}
catch (Exception e)
{
// Create AS400 object and connect for the record level access service.
AS400 system = new AS400(systemName);
try
{
system.connectService(AS400.RECORDACCESS);
}
catch(Exception e)
{
System.out.println("Unable to connect for record level access.");
System.out.println("Check the readme file for special instructions regarding record
level access");
e.printStackTrace();
System.exit(0);
}
// Create a QSYSObjectPathName object to obtain the integrated file system path name form
// of the file to be displayed.
QSYSObjectPathName filePathName = new QSYSObjectPathName(library, file, member, "MBR");
// Open the file for reading. Read 100 records at a time if possible.
theFile.open(AS400File.READ_ONLY, 100, AS400File.COMMIT_LOCK_LEVEL_NONE);
try
{
// Close the file
theFile.close();
// Make sure that the application ends; see readme for details
System.exit(0);
}
}
Note: Read the Code example disclaimer for important legal information.
///////////////////////////////////////////////////////////////////////////////
//
// Record-Level Access example. This program uses the record-level
// access classes to read records from a file on the server.
//
// Command syntax:
// java RLReadFile system
//
// This program reads the records from CA/400’s sample database file
// (QCUSTCDT in library QIWS). If you change this example to update
// records, make a copy of QCUSTCDT and update the copy.
//
// This source is an example of IBM Toolbox for Java "Record-level access".
//
///////////////////////////////////////////////////////////////////////////////
import java.io.*;
import java.util.*;
import java.math.*;
import com.ibm.as400.access.*;
if (parameters.length >= 1)
{
try
{
system = parameters[0];
// Create an AS400 object for the server that has the file.
ZonedDecimalFieldDescription customerNumber =
new ZonedDecimalFieldDescription(new AS400ZonedDecimal(6,0),
"CUSNUM");
CharacterFieldDescription lastName =
new CharacterFieldDescription(new AS400Text(8, as400), "LSTNAM");
CharacterFieldDescription initials =
new CharacterFieldDescription(new AS400Text(3, as400), "INIT");
CharacterFieldDescription street =
new CharacterFieldDescription(new AS400Text(13, as400), "STREET");
CharacterFieldDescription city =
new CharacterFieldDescription(new AS400Text(6, as400), "CITY");
CharacterFieldDescription state =
new CharacterFieldDescription(new AS400Text(2, as400), "STATE");
ZonedDecimalFieldDescription zipCode =
new ZonedDecimalFieldDescription(new AS400ZonedDecimal(5,0),
"ZIPCOD");
ZonedDecimalFieldDescription creditLimit =
new ZonedDecimalFieldDescription(new AS400ZonedDecimal(4,0),
"CDTLMT");
ZonedDecimalFieldDescription chargeCode =
new ZonedDecimalFieldDescription(new AS400ZonedDecimal(1,0),
"CHGCOD");
ZonedDecimalFieldDescription balanceDue =
new ZonedDecimalFieldDescription(new AS400ZonedDecimal(6,2),
"BALDUE");
ZonedDecimalFieldDescription creditDue =
new ZonedDecimalFieldDescription(new AS400ZonedDecimal(6,2),
"CDTDUE");
qcustcdt.addFieldDescription(customerNumber);
qcustcdt.addFieldDescription(lastName);
qcustcdt.addFieldDescription(initials);
qcustcdt.addFieldDescription(street);
qcustcdt.addFieldDescription(city);
qcustcdt.addFieldDescription(state);
qcustcdt.addFieldDescription(zipCode);
qcustcdt.addFieldDescription(creditLimit);
qcustcdt.addFieldDescription(chargeCode);
qcustcdt.addFieldDescription(balanceDue);
qcustcdt.addFieldDescription(creditDue);
file.open(SequentialFile.READ_ONLY,
10,
SequentialFile.COMMIT_LOCK_LEVEL_NONE);
// Loop while there are records in the file (while we have not
// reached end-of-file).
data = file.readNext();
}
// When there are no more records to read, disconnect from the server.
as400.disconnectAllServices();
}
catch (Exception e)
{
else
{
System.out.println("");
System.exit(0);
}
}
Note: Read the Code example disclaimer for important legal information.
///////////////////////////////////////////////////////////////////////////////
//
// Record-Level Access example. This program uses the record-level
// access classes to read records by key from a file on the server.
// The user will be prompted for the server name to which to run and
// the library in which to create file QCUSTCDTKY.
//
// Command syntax:
// java RLKeyedFileExample
//
// This program will copy the records from the IBM i Access for Windows sample
// database file (QCUSTCDT in library QIWS) to file QCUSTCDTKY which has
// the same format as QIWS/QCUSTCDT but has set the CUSNUM field as the key
// for the file.
//
// This source is an example of IBM Toolbox for Java "Record-level access".
//
///////////////////////////////////////////////////////////////////////////////
import java.io.*;
import java.util.*;
import java.math.*;
import com.ibm.as400.access.*;
// Declare variables to hold the system name, library, file and member names
// Create AS400 object and connect for the record level access service.
AS400 system = new AS400(systemName);
try
{
system.connectService(AS400.RECORDACCESS);
}
catch(Exception e)
{
System.out.println("Unable to connect for record level access.");
System.out.println("Check the readme file for special instructions regarding record
level access");
e.printStackTrace();
System.exit(0);
}
// There is only one record format for the file, so take the first (and only) element
// of the RecordFormat array returned as the RecordFormat for the file.
System.out.println("Retrieving record format of QIWS/QCUSTCDT...");
qcustcdtFormat = recordDescription.retrieveRecordFormat()[0];
// Indicate that CUSNUM is a key field
qcustcdtFormat.addKeyFieldDescription("CUSNUM");
}
catch(Exception e)
{
System.out.println("Unable to retrieve record format from QIWS/QCUSTCDT");
e.printStackTrace();
System.exit(0);
}
// Create the key for reading the records. The key for a KeyedFile
// is specified with an Object[]
Object[] key = new Object[1];
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// User list example. This program lists all of the users in a given
// group.
//
// Command syntax:
// UserListExample system group
//
// This source is an example of IBM Toolbox for Java "UserList".
//
/////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import java.util.Enumeration;
try
{
// Create an AS400 object. The system name was passed
// as the first command line argument.
AS400 system = new AS400 (args[0]);
}
catch (Exception e)
{
System.out.println ("Error: " + e.getMessage ());
}
System.exit (0);
}
Examples: JavaBeans
This section lists the code examples that are provided throughout the IBM Toolbox for Java bean
information.
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// Beans example. This program uses the JavaBeans support in the
// IBM Toolbox for Java classes.
//
// Command syntax:
// BeanExample
//
//////////////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.CommandCall;
import com.ibm.as400.access.ConnectionListener;
import com.ibm.as400.access.ConnectionEvent;
import com.ibm.as400.access.ActionCompletedListener;
import com.ibm.as400.access.ActionCompletedEvent;
class BeanExample
{
AS400 as400_ = new AS400();
CommandCall cmd_ = new CommandCall( as400_ );
BeanExample()
{
// Whenever the system is connected or disconnected print a
// comment. Do this by adding a listener to the AS400 object.
// When a system is connected or disconnected, the AS400 object
// will call this code.
as400_.addConnectionListener
(new ConnectionListener()
{
public void connected(ConnectionEvent event)
{
System.out.println( "System connected." );
}
public void disconnected(ConnectionEvent event)
{
System.out.println( "System disconnected." );
}
}
);
cmd_.addActionCompletedListener(
new ActionCompletedListener()
{
void runCommand()
{
try
{
// Run a command. The listeners will print comments when the
// system is connected and when the command has run to
// completion.
cmd_.run( "TESTCMD PARMS" );
}
catch (Exception ex)
{
System.out.println( ex );
}
}
be.runCommand();
System.exit(0);
}
}
v Connect the AS400 bean to the CommandCall bean. The method you use to do this varies between
bean builders. For this example, do the following:
– Select the CommandCall bean and then click the right mouse button
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
The following examples show you how the GUI Builder can help you to create a variety of GUI elements:
v Panels: Creating a sample panel and the data bean code that runs the panel
v Deckpanes: Creating a deckpane and what a final deckpane may look like
v Property sheets: Creating a property sheet and what a final property sheet may look like
v Split panes: Creating a split pane and what a final split pane may look like
v Tabbed panes: Creating a tabbed pane and what a final tabbed pane may look like
v Wizards: Creating a wizard and what the final product may look like
v Toolbars: Creating a tool bar and what a final tool bar may look like
v Menu bars: Creating a menu bar and what a final menu bar may look like
v Help: Generating a Help Document and split the Help Document into topic pages. Also, see Editing
Help Documents generated by GUI builder
v Sample: Shows what a whole PDML program may look like, including panels, a property sheet, a
wizard, select/deselect, and menu options.
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
After showing you how to construct a panel, the example goes on to show you how to build a small Java
application that displays the panel. In this example, the user enters data in a text field and clicks on the
Close button. The application then echos the data to the Java console.
When you start the GUI Builder, the Properties and GUI Builder windows appear. Create a new file
named "MyGUI.pdml". For this example, insert a new panel. Click the "Insert Panel" icon in File Builder
window. Its name is "PANEL1". Change the title by modifying information in the Properties window;
type "Simple Example" in the "Title" field. Remove the three default buttons by selecting them with your
mouse and pressing "Delete". Using the buttons in the Panel Builder window, add the three elements
shown in Figure 1: a label, a text field, and a pushbutton.
Note: Read the Code example disclaimer for important legal information.
Text field
The text field will contain data and, therefore, you can set several properties that will allow the GUI
Builder to perform some additional work. For this example, you set the Data Class property to the name
of a bean class named SampleBean. This databean will supply the data for this text field.
Following the above steps binds the UserData property to this text field. At run-time, the Graphical
Toolbox obtains the initial value for this field by calling SampleBean.getUserData. The modified value is
then sent back to the application when the panel closes by calling SampleBean.setUserData.
Figure 5: GUI Builder windows: Setting the maximum length of the text field
Indicate that the context-sensitive help for the text field will be the help topic associated with the label
"Enter some data".
Figure 6: GUI Builder windows: Setting context-sensitive help for the text field
Button
Figure 7: GUI Builder windows: Setting the Style property to give the button default emphasis
Before you save the panel, set properties at the level of the PDML file to generate both the online help
skeleton and the Java bean. Then you save the file by clicking on the icon in the GUI Builder
window. When prompted, specify a file name of MyGUI.pdml.
Figure 9: GUI Builder windows: Setting properties to generate the online help skeleton and the Java
bean
After you save the panel definition, you can look at the files produced by the GUI Builder. PDML file
Here is the content of MyGUI.pdml to give you an idea of how the Panel Definition Markup Language
works. Because you use PDML only through the tools provided by the Graphical Toolbox, it is not
necessary to understand the format of this file in detail:
<!-- Generated by GUI Builder -->
<PDML version="2.0" source="JAVA" basescreensize="1280x1024">
<PANEL name="PANEL1">
<TITLE>PANEL1<TITLE>
<SIZE>351,162<</SIZE>
<LABEL name="LABEL1"">
<TITLE>PANEL1.LABEL1</TITLE>
<LOCATION>18,36</LOCATION>
<SIZE>94,18</SIZE>
<HELPLINK>PANEL1.LABEL1</HELPLINK>
</LABEL>
<TEXTFIELD name="TEXTFIELD1">
<TITLE>PANEL1.TEXTFIELD1</TITLE>
<LOCATION>125,31</LOCATION>
<SIZE>191,26</SIZE>
<DATACLASS>SampleBean</DATACLASS>
<ATTRIBUTE>UserData</ATTRIBUTE>
<STRING minlength="0" maxlength="15"/>
<HELPALIAS>LABEL1</HELPALIAS>
</TEXTFIELD>
<BUTTON name="BUTTON1">
<TITLE>PANEL1.BUTTON1</TITLE>
<LOCATION>125,100</LOCATION>
<SIZE>100,26</SIZE>
<STYLE>DEFAULT<</STYLE>
<ACTION>COMMIT</ACTION>
<HELPLINK>PANEL1.BUTTON1</HELPLINK>
</BUTTON>
</PANEL>
</PDML>
Resource bundle
Associated with every PDML file is a resource bundle. In this example, the translatable resources were
saved in a PROPERTIES file, which is called MyGUI.properties. Notice that the PROPERTIES file also
contains customization data for the GUI Builder.
##Generated by GUI Builder
BUTTON_1=Close
TEXT_1=
@GenerateHelp=1
@Serialize=0
@GenerateBeans=1
LABEL_1=Enter some data:
PANEL_1.Margins=18,18,18,18,18,18
PANEL_1=Simple Example
JavaBean
The example also generated a Java source code skeleton for the JavaBean object. Here is the content of
SampleBean.java:
import com.ibm.as400.ui.framework.java.*;
Note that the skeleton already contains an implementation of the gettor and settor methods for the
UserData property. The other methods are defined by the DataBean interface and, therefore, are required.
The GUI Builder has already invoked the Java compiler for the skeleton and produced the corresponding
class file. For the purposes of this simple example, you do not need to modify the bean
implementation. In a real Java application you would typically modify the load and save methods to
transfer data from an external data source. The default implementation of the other two methods is
often sufficient. For more information, see the documentation on the DataBean interface in the Javadocs
for the PDML runtime framework.
Help file
The GUI Builder also creates an HTML framework called a Help Document. Help writers can easily
manage help information by editing this file. For more information, see the following topics:
v Creating the Help Document
v Editing Help Documents generated by GUI builder
Once the panel definition and the generated files have been saved, you are ready to construct the
application. All you need is a new Java source file that will contain the main entry point for the
application. For this example, the file is called SampleApplication.java. It contains the following code:
import com.ibm.as400.ui.framework.java.*;
import java.awt.Frame;
PanelManager pm = null;
try { pm = new PanelManager("MyGUI", "PANEL_1", beans, new Frame()); }
catch (DisplayManagerException e)
{
// Something didn’t work, so display a message and exit
e.displayUserMessage(null);
System.exit(1);
}
It is the responsibility of the calling program to initialize the bean object or objects by calling load. If the
data for a panel is supplied by multiple bean objects, then each of the objects must be initialized before
passing them to the Graphical Toolbox environment.
Because a Frame object is supplied on the constructor, the window will behave as a modal dialog. In a
real Java application, this object might be obtained from a suitable parent window for the dialog.
Because the window is modal, control does not return to the application until the user closes the
window. At that point, the application simply echoes the modified user data and exits.
Here is what the window looks like when the application is compiled and run:
You can edit the HTML and add actual help content for the help topics shown.
If the data in the text field is not valid (for example, if the user clicked on the Close button without
supplying a value), the Graphical Toolbox will display an error message and return focus to the field so
that data can be entered.
For information about how to run this sample as an applet, see Using the Graphical Toolbox in a
Browser.
Related information:
Package com.ibm.as400.ui.framework.java summary
Editable Comboboxes
When the bean generator creates a gettor and settor for an Editable ComboBox, by default it returns a
String on the settor and takes a string parameter on the gettor. It can be useful to change the settor to
take an Object class and the gettor to return an Object type. This allows you to determine the user
selection using ChoiceDescriptors.
If a type of Object is detected for the gettor and settor, the system will expect either a ChoiceDescriptor
or a type Object instead of a formatted string.
The following example assumes that Editable is an editable ComboBox that has either a Double value,
uses a system value, or is not set.
public Object getEditable()
{
if (m_setting == SYSTEMVALUE)
{
return new ChoiceDescriptor("choice1","System Value");
}
else if (m_setting == NOTSET)
{
return new ChoiceDescriptor("choice2","Value not set");
}
else
{
return m_doubleValue;
}
}
Similarly, when a type of Object is detected for the gettor and settor, the system will return an Object
which is either a ChoiceDescriptor containing the selected choice or a type Object.
public void setEditable(Object item)
{
if (ChoiceDescriptor.class.isAssignableForm(obj.getClass()))
{
if (((ChoiceDescriptor)obj).getName().equalsIgnoreCase("choice1"))
m_setting = SYSTEMVALUE;
else
m_setting = NOTSET;
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// RecordListFormPane example. This program presents a form that contains
// the contents of a file on the server.
//
// Command syntax:
// RecordListFormPaneExample system fileName
//
// This source is an example of IBM Toolbox for Java "RecordListFormPane".
//
/////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
try
{
// Create an AS400 object. The system name was passed
// as the first command line argument.
AS400 system = new AS400 (args[0]);
// Create a frame.
JFrame f = new JFrame ("RecordListFormPane example");
To create a menu, from the menu bar on the main GUI Builder window, select File > New File.
From the menu bar on the GUI Builder File window, click the Insert New Panel icon to display a
panel builder where you can insert the components for your panel. The toolbar buttons on the Panel
window represent various components that you can add to the panel. Select the component you want
and then click on the place you want to position it.
The following picture shows a panel that has been created with several of the options available to you.
The sample panel in Figure 1 uses the following DataBean code to bring together the various
components:
import com.ibm.as400.ui.framework.java.*;
The panel is the most simple component available within the GUI Builder, but from a simple panel you
can build great UI applications.
From the menu bar on the GUI Builder window, select File > New File.
After you create the deck pane, click the Preview tool button to preview it. A deck pane looks plain
until you select the View menu.
GUI Builder makes creating a property sheet simple. From the menu bar on the main GUI Builder
window, select File --> New File.
From the menu bar on the GUI Builder File window, click the Insert Property Sheet icon to display
a panel builder where you can insert the components for your property sheet.
After you create the property sheet, use the icon to preview it. For this example, you can choose
from three tabs.
From the menu bar on the main GUI Builder window, select File --> New File.
From the menu bar on the GUI Builder File window, click the Insert Split Pane tool button to
display a panel builder where you can insert the components you want in your split pane. In the
following example, two components are added.
After you create the split pane, click the Preview tool button icon to preview it, as shown in Figure
2.
From the menu bar on the main GUI Builder window, select File > New File.
From the menu bar on the GUI Builder File window, click the Insert Tabbed Pane icon to display a
panel builder where you can insert the components for your tabbed pane. In the following example, two
components are added.
After you create the tabbed pane, click the Preview tool button to preview it.
GUI Builder makes creating a wizard interface simple. From the menu bar on the GUI Builder window,
select File --> New File.
From the menu bar on the GUI Builder File window, click the Insert Wizard toolbar button
to display a panel builder where you can add panels to the wizard.
After you have create the wizard, use the Preview tool button
to preview it. Figure 2 shows the panel that first displays for this example.
Figure 2 shows the second panel that displays when the user selects Rock and clicks Next.
Clicking Next on the second wizard panel displays the final wizard panel, as shown in Figure 4.
From the menu bar on the GUI Builder window, select File > New File.
From the menu bar on the GUI Builder File window, click the Insert Tool Bar tool button to display a
panel builder where you can insert the components for your toolbar.
After you create the toolbar, click the Preview tool button to preview it. For this example, you can
use the toolbar to display either a property sheet or wizard.
GUI Builder makes creating a menu bar simple. From the menu bar on the GUI Builder window, select
File --> New File.
From the tool bar on the GUI Builder File window, click the Insert Menu tool button to create a panel
builder where you can insert the components for your menu.
After you create the menu, use the Preview tool button to preview it. For this example, from the
newly created Launch menu you can select either Property Sheet or Wizard. The following figures
illustrate what you see when you select these menu items.
Creating help files with GUI Builder is simple. On the properties panel for the file you are working with,
set "Generate help" to true.
Figure 1: Setting the Generate Help property on the GUI Builder Properties panel
The GUI Builder creates an HTML framework called a Help Document, which you can edit.
In order to be used at runtime, the topics within the PDML file need to be separated into individual
HTML files. When you run Help Document to HTML Processing, the topics are broken into individual
files and put into a subdirectory named after the Help Document and PDML file. The runtime
environment expects the individual HTML files to be in a subdirectory with the same name as the Help
Document and PDML file. The Help Document to HTML Processing dialog gathers the information
needed and calls the HelpDocSplitter program to do the processing:
The Help Document to HTML Processing is started from a command prompt by typing:
jre com.ibm.as400.ui.tools.hdoc2htmViewer
To use the Help Document to HTML Processing, you first select the Help Document that has the same
name as the PDML file. Next, you specify a subdirectory with the same name as the Help Document and
PDML file for output. Select "Process" to complete the processing.
You can split up the help document from the command line with the following command:
jre com.ibm.as400.ui.tools.HelpDocSplitter "helpdocument.htm" [output directory]
This command runs the processing that breaks up the file. You provide the name of the Help Document
as input along with an optional output directory. By default, a subdirectory of the same name as the Help
Document is created and the resulting files are put in that directory.
Figure 1 shows the first panel that displays when you run this example.
You can launch the property sheet by clicking the Property Sheet toolbar button or by using the Launch
menu. Being able to choose between the toolbar and the menu illustrates linking menu items. Figure 4
shows Property Sheet being selected from Launch menu on the GUI Builder example main window.
You can launch the wizard by clicking the Wizard toolbar button or by using the Launch menu. Being
able to choose between the toolbar and the menu illustrates linking menu items.
Figure 9 shows how the first wizard dialog gives you many options.
In the first wizard dialog, select Rock and click Next to display the second wizard dialog as shown in
Figure 10.
However, this example has been programmed to have a loop. Select Country in the first wizard dialog
(Figure 12), then click Next to display the second wizard dialog (Figure 13). Clicking Next in the second
wizard dialog loops back to display the first dialog again (Figure 14) instead of the final wizard dialog.
In other words, the programmer has determined that nobody can select country as their favorite form of
music.
From the GUI Builder example main window, you can also select other functions from the left pane
below the toolbar. Figure 15 shows how selecting Panel in the left pane displays the Panel sample in the
right pane.
The Panel sample also illustrates the drop-down list box option, as shown in Figure 17.
Figure 17: Selecting an item from the Favorite Food list in the right pane
Figure 18 shows how selecting Tabbed Pane in the left pane of the GUI Builder example main window
displays the Tabbed Pane sample in the right pane.
Figure 19: Selecting the Panel Sample tab in the right pane
Select Tab 1 again (in the right pane), then click Disable Age Field on Tab 2 to deselect it.
Figure 20: Selecting Disable Age Field on Tab 2 in the right pane
Selecting Table Pane in the left pane of the GUI Builder example main window illustrates the use of a
table panel with a custom renderer and a custom cell editor, as shown in Figure 22.
You can also use the HTML and servlet classes together, like in this example.
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
You can also view a sample output from running this code. The HTML classes used in the "showHTML"
method are bold.
Note: Read the Code example disclaimer for important legal information.
///////////////////////////////////////////////////////////////////////////////
//
// This source is an example of using the HTML
// package classes, which allow you to easily build HTML Forms.
//
///////////////////////////////////////////////////////////////////////////////
package customer;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.ibm.as400.access.*;
import com.ibm.as400.util.html.*;
try
{
super.init(config);
}
catch(Exception e)
{
e.printStackTrace();
}
/**
* Process the GET request.
* @param req The request.
* @param res The response.
**/
public void doGet (HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
res.setContentType("text/html");
ServletOutputStream out = res.getOutputStream();
res.setContentType("text/html");
try
{
//Create the registration.txt file
FileWriter f = new FileWriter(regPath, true);
BufferedWriter output = new BufferedWriter(f);
}
else // read the next line
line = in.readLine();
//------------------------------------------------------------
//Getting "USE" checkbox from form
data = req.getParameter("use");
if(data != null)
{
output.write("Currently Using Toolbox: " + data);
output.newLine();
}
//------------------------------------------------------------
//------------------------------------------------------------
//Getting "More Information" checkbox from form
data = req.getParameter("contact");
if (data != null)
{
output.write("Requested More Information: " + data);
output.newLine();
}
//------------------------------------------------------------
//------------------------------------------------------------
//Getting "AS400 Version" from form
data = req.getParameter("version");
if (data != null)
{
if (data.equals("multiple versions"))
{
data = req.getParameter("MultiList");
output.write("Multiple Versions: " + data);
}
else
output.write("AS400 Version: " + data);
output.newLine();
}
//------------------------------------------------------------
//------------------------------------------------------------
//Getting "Current Projects" from form
data = req.getParameter("interest");
if (data != null)
{
output.write("Using Java or Interested In: " + data);
output.newLine();
}
//------------------------------------------------------------
//------------------------------------------------------------
//Getting "Platforms" from form
data = req.getParameter("platform");
if (data != null)
{
output.write("Platforms: " + data);
output.newLine();
if (data.indexOf("Other") >= 0)
{
//------------------------------------------------------------
//Getting "Number of IBM i servers" from form
data = req.getParameter("list1");
if (data != null)
{
output.write("Number of IBM i servers: " + data);
output.newLine();
}
//------------------------------------------------------------
//------------------------------------------------------------
//Getting "Comments" from form
data = req.getParameter("comments");
if (data != null && data.length() > 0)
{
output.write("Comments: " + data);
output.newLine();
}
//------------------------------------------------------------
//------------------------------------------------------------
//Getting "Attachment"
data = req.getParameter("myAttachment");
if (data != null && data.length() > 0)
{
output.write("Attachment File: " + data);
output.newLine();
}
//------------------------------------------------------------
//------------------------------------------------------------
//Getting Hidden "Copyright" infomation
data = req.getParameter("copyright");
if (data != null)
{
output.write(data);
output.newLine();
}
//------------------------------------------------------------
output.flush();
output.close();
e.printStackTrace();
}
}
else
{
// Output a message to the customer saying customer name &
// e-mail not entered. Please try again
out.println ("<HTML> " +
"<TITLE>Invalid Registration Form</TITLE> " +
"<META HTTP-EQUIV=\"pragma\" content=\"no-cache\"> " +
"<BODY BGCOLOR=\"blanchedalmond\" TEXT=\"black\"> " );
// Build the beginning of the HTML Page and add it to the String Buffer
try
{
//--------------------------------------------------------------------
// Create page title using HTML Text
txt = new HTMLText("Product Registration");
txt.setSize(5);
txt.setBold(true);
txt.setColor(new Color(199, 21, 133));
txt.setAlignment(HTMLConstants.CENTER);
//--------------------------------------------------------------------
// Create a Line Layout
LineLayoutFormPanel line = new LineLayoutFormPanel();
txt = new HTMLText("Enter your name and e-mail address:");
txt.setSize(4);
line.addElement(txt);
//--------------------------------------------------------------------
// Set the HTML Form METHOD
form.setMethod(HTMLForm.METHOD_POST);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Create a Text input for the name.
TextFormInput user = new TextFormInput("name");
user.setSize(25);
user.setMaxLength(40);
// Create a ImageFormInput
ImageFormInput img =
new ImageFormInput("Submit Form", "..\\images\\myPiimages/c.gif");
img.setAlignment(HTMLConstants.RIGHT);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Create a LineLayoutFormPanel object for the name & e-mail address
LineLayoutFormPanel line2 = new LineLayoutFormPanel();
//--------------------------------------------------------------------
// Create Questions line layout
LineLayoutFormPanel line3 = new LineLayoutFormPanel();
//--------------------------------------------------------------------
// Create Version Radio Group
RadioFormInputGroup group = new RadioFormInputGroup("version");
//--------------------------------------------------------------------
// Create Grid Layout for interests
GridLayoutFormPanel grid2 = new GridLayoutFormPanel(1);
txt = new HTMLText("Current Projects or Area of Interest: " +
//--------------------------------------------------------------------
// Create Line Layout for platforms
LineLayoutFormPanel line4 = new LineLayoutFormPanel();
txt = new HTMLText("Client Platforms Used: " +
"(check all that apply)");
txt.setSize(4);
line4.addElement(other);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Create a Grid Layout for Product Comments
GridLayoutFormPanel grid4 = new GridLayoutFormPanel(1);
txt = new HTMLText("Product Comments:");
txt.setSize(4);
//--------------------------------------------------------------------
// Create a Grid Layout
GridLayoutFormPanel grid5 = new GridLayoutFormPanel(2);
txt = new HTMLText("Would you like to sign on to a server?");
txt.setSize(4);
// Add the Text inputs, password inputs, and Labels to the grid
grid5.addElement(sysLabel);
grid5.addElement(sys);
grid5.addElement(uidLabel);
grid5.addElement(uid);
grid5.addElement(pwdLabel);
grid5.addElement(pwd);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Add the various panels created to the HTML Form
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Note: Read the Code example disclaimer for important legal information.
///////////////////////////////////////////////////////////////////////////////
//
// This source is an example of using the IBM Toolbox for Java HTML
// package classes, which allow you to easily build HTML and File Trees.
//
///////////////////////////////////////////////////////////////////////////////
import java.io.File;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.Vector;
import java.util.Properties;
import javax.servlet.*;
import javax.servlet.http.*;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.Trace;
import com.ibm.as400.access.IFSJavaFile;
/**
* An example of using the HTMLTree and FileTreeElement classes in a servlet.
**/
public class TreeNav extends HttpServlet
{
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
HTMLTreeElement.setExpandedGif("/images/expanded.gif");
HTMLTreeElement.setCollapsedGif("/images/collapsed.gif");
HTMLTreeElement.setDocGif("/images/bullet.gif");
}
/**
* Process the GET request.
* @param req The request.
* @param res The response.
**/
public void doGet (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
HttpSession session = req.getSession(true);
HTMLTree fileTree = (HTMLTree)session.getValue("filetree");
resp.setContentType("text/html");
out.println("</body>\n");
out.println("</html>\n");
out.close();
// Set the session tree value, so when entering this servlet for
/**
* Process the POST request.
* @param req The request.
* @param res The response.
**/
public void doPost (HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
res.setContentType("text/html");
ServletOutputStream out = res.getOutputStream();
}
/**
* This method will create the initial HTMLTree.
**/
private HTMLTree createTree(HttpServletRequest req, HttpServletResponse resp, String uri)
{
// Create an HTMLTree object.
HTMLTree tree = new HTMLTree(req);
try
{
// Create a URLParser object.
URLParser urlParser = new URLParser(uri);
return tree;
}
Example: Creating a traversable integrated file system tree (File one of three)
This IBM Toolbox for Java example code, in conjunction with the code in the other two example files,
displays an HTMLTree and FileListElement in a servlet.
Note: Read the Code example disclaimer for important legal information.
///////////////////////////////////////////////////////////////////////////////
//
// This source is an example of using the HTML package
// classes, which allow you to easily build HTML and File Trees.
//
///////////////////////////////////////////////////////////////////////////////
import java.io.PrintWriter;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
import com.ibm.as400.util.html.HTMLMeta;
/**
* Process the GET request.
* @param req The request.
* @param res The response.
**/
/**
* Process the POST request.
* @param req The request.
* @param res The response.
**/
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// This source is an example of using the IBM Toolbox for Java HTML
// package classes, which allow you to easily build HTML and File Trees.
//
//////////////////////////////////////////////////////////////////////////////////
import java.io.File;
import java.io.PrintWriter;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.IFSJavaFile;
import com.ibm.as400.util.html.HTMLMeta;
import com.ibm.as400.util.html.HTMLTree;
import com.ibm.as400.util.html.HTMLTreeElement;
import com.ibm.as400.util.html.URLParser;
import com.ibm.as400.util.html.DirFilter;
import com.ibm.as400.util.html.FileTreeElement;
import com.ibm.as400.util.servlet.ServletHyperlink;
//
// An example of using the HTMLTree and FileTreeElement classes
// in a servlet.
//
// IBM Toolbox for Java uses a set of default icons to represents expanded,
// collapsed, and documents within the HTMLTree. To enhance those icons,
// IBM Toolbox for Java ships three gifs (expanded.gif, collapsed.gif, bullet.gif)
// in the jt400Servlet.jar file. Browsers do not have the ability to find
// gifs in a JAR or zip file, so you need to extract those images from the
// JAR file and place them in the appropriate webserver directory (by default
// it is the /html directory). Then change the following lines of code to
// specify the correct location in the set methods. The location can be
// absolute or relative.
HTMLTreeElement.setExpandedGif("http://myServer/expanded.gif");
HTMLTreeElement.setCollapsedGif("http://myServer/collapsed.gif");
HTMLTreeElement.setDocGif("http://myServer/bullet.gif");
/**
* Process the GET request.
* @param req The request.
* @param res The response.
**/
resp.setContentType("text/html");
out.println("</body>\n");
out.println("</html>\n");
out.close();
// Set the session tree value, so when entering this servlet for
// the second time, the FileTree object will be reused.
session.putValue("filetree", fileTree);
}
/**
* Process the POST request.
* @param req The request.
* @param res The response.
**/
/**
* This method will create the initial HTMLTree.
**/
try
{
// Create a Filter.
DirFilter filter = new DirFilter();
sys_.disconnectAllServices();
}
catch (Exception e)
{
e.printStackTrace();
}
return tree;
Note: Read the Code example disclaimer for important legal information.
////////////////////////////////////////////////////////////////////////////////
//
// This source is an example of using the IBM Toolbox for Java HTML
// package classes, which allow you to easily build HTML and File Lists.
//
////////////////////////////////////////////////////////////////////////////////
import java.io.PrintWriter;
import java.io.IOException;
import java.io.File;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.Trace;
import com.ibm.as400.access.IFSJavaFile;
import com.ibm.as400.util.html.HTMLMeta;
import com.ibm.as400.util.html.HTMLHeading;
import com.ibm.as400.util.html.HTMLConstants;
import com.ibm.as400.util.html.FileListElement;
import com.ibm.as400.util.html.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* An example of using the FileListElement class in a servlet.
**/
public class TreeList extends HttpServlet
{
/**
* Process the GET request.
* @param req The request.
* @param res The response.
**/
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
resp.setContentType("text/html");
// If the path parameter is not null, then the user has selected an
// element from the FileTreeElement list in the navigation frame.
if (req.getPathInfo() != null)
{
// Create a FileListElement passing in an AS400 system object and
// the Http servlet request. The request will contain the necessary
// path information to list out the contents of the FileTreeElement
// (directory) selected.
FileListElement fileList = new FileListElement(sys_, req);
out.println(heading.getTag());
}
out.println("</body>\n");
out.println("</html>\n");
out.close();
}
catch (Exception e)
{
e.printStackTrace();
}
/**
* Process the POST request.
* @param req The request.
* @param res The response.
**/
public void doPost (HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
res.setContentType("text/html");
ServletOutputStream out = res.getOutputStream();
table.addColumnHeader(account_header);
table.addColumnHeader(name_header);
table.addColumnHeader(balance_header);
// Add rows to the table. Each customer record represents a row in the table.
int numCols = 3;
for (int rowIndex=0; rowIndex< numCustomers; rowIndex++)
{
HTMLTableRow row = new HTMLTableRow();
row.setHorizontalAlignment(HTMLTableRow.CENTER);
row.addColumn(new HTMLTableCell(account));
row.addColumn(new HTMLTableCell(name));
row.addColumn(new HTMLTableCell(balance));
The Java code example above generates the following HTML code:
<table align="center" border="1">
<caption>Customer Account Balances - January 1, 2000</caption>
<tr>
<th>ACCOUNT</th>
<th>NAME</th>
<th>BALANCE</th>
</tr>
<tr align="center">
<td>0000001</td>
<td>Customer1</td>
<td>100.00</td>
</tr>
<tr align="center">
The following table shows how the HTML code above displays in a Web browser.
Table 3. Customer Account Balances - January 1, 2000
ACCOUNT NAME BALANCE
0000001 Customer1 100.00
0000002 Customer2 200.00
0000003 Customer3 550.00
Note: The proper authority for each example varies but may include specific object authorities and
special authorities. In order to run these examples, you must sign on with a user profile that has
authority to perform the following actions:
v Call the IBM i API in the example
v Access the information being requested
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
Note: Read the Code example disclaimer for important legal information.
<!-- PCML source for calling "Retrieve user Information" (QSYRUSRI) API -->
<!-- Program QSYRUSRI and its parameter list for retrieving USRI0100 format -->
<program name="qsyrusri" path="/QSYS.lib/QSYRUSRI.pgm">
<data name="receiver" type="struct" struct="usri0100" usage="output"/>
<data name="receiverLength" type="int" length="4" usage="input" />
<data name="format" type="char" length="8" usage="input" init="USRI0100"/>
<data name="profileName" type="char" length="10" usage="input" init="*CURRENT"/>
<data name="errorCode" type="int" length="4" usage="input" init="0"/>
</program>
</pcml>
public qsyrusri() {
}
System.setErr(System.out);
try
{
// Uncomment the following to get debugging information
//com.ibm.as400.data.PcmlMessageLog.setTraceEnabled(true);
// Construct ProgramCallDocument
// First parameter is system to connect to
// Second parameter is pcml resource name. In this example,
// serialized PCML file "qsyrusri.pcml.ser" or
// PCML source file "qsyrusri.pcml" must be found in the classpath.
pcml = new ProgramCallDocument(as400System, "qsyrusri");
System.exit(0);
} // End main()
<!-- PCML source for calling "Open List of Authorized Users" (QGYOLAUS) API -->
<!-- List information structure (common for "Open List" type APIs) -->
<struct name="listInfo">
<data name="totalRcds" type="int" length="4" />
<data name="rcdsReturned" type="int" length="4" />
<data name="rqsHandle" type="byte" length="4" />
<data name="rcdLength" type="int" length="4" />
<data name="infoComplete" type="char" length="1" />
<data name="dateCreated" type="char" length="7" />
<data name="timeCreated" type="char" length="6" />
<data name="listStatus" type="char" length="1" />
<data type="byte" length="1" />
<data name="lengthOfInfo" type="int" length="4" />
<data name="firstRecord" type="int" length="4" />
<data type="byte" length="40" />
</struct>
<!-- Program QGYOLAUS and its parameter list for retrieving AUTU0150 format -->
<program name="qgyolaus" path="/QSYS.lib/QGY.lib/QGYOLAUS.pgm" parseorder="listInfo receiver">
<data name="receiver" type="struct" struct="autu0150" usage="output"
count="listInfo.rcdsReturned" outputsize="receiverLength" />
<data name="receiverLength" type="int" length="4" usage="input" init="16384" />
<data name="listInfo" type="struct" struct="listInfo" usage="output" />
<data name="rcdsToReturn" type="int" length="4" usage="input" init="264" />
<data name="format" type="char" length="10" usage="input" init="AUTU0150" />
<data name="selection" type="char" length="10" usage="input" init="*USER" />
<data name="member" type="char" length="10" usage="input" init="*NONE" />
<data name="errorCode" type="int" length="4" usage="input" init="0" />
</program>
System.setErr(System.out);
try
{
// Uncomment the following to get debugging information
//com.ibm.as400.data.PcmlMessageLog.setTraceEnabled(true);
// Construct ProgramCallDocument
// First parameter is system to connect to
// Second parameter is pcml resource name. In this example,
// serialized PCML file "qgyolaus.pcml.ser" or
// PCML source file "qgyolaus.pcml" must be found in the classpath.
pcml = new ProgramCallDocument(as400System, "qgyolaus");
// All input parameters have default values specified in the PCML source.
// Do not need to set them using Java code.
nbrUsers += nbrRcds;
// Call "Get List Entries" (QGYGTLE) to get more users from list
rc = pcml.callProgram("qgygtle");
}
}
System.out.println("Number of users returned: " + nbrUsers);
System.exit(0);
}
}
<struct name="receiver">
<data name="lengthOfEntry" type="int" length="4" />
<data name="dispToObjectPathName" type="int" length="4" />
<data name="lengthOfObjectPathName" type="int" length="4" />
<data name="ccsidOfObjectPathName" type="int" length="4" />
<data name="readOnlyFlag" type="int" length="4" />
<data name="nosuidFlag" type="int" length="4" />
<data name="dispToReadWriteHostNames" type="int" length="4" />
<data name="nbrOfReadWriteHostNames" type="int" length="4" />
<data name="dispToRootHostNames" type="int" length="4" />
<data name="nbrOfRootHostNames" type="int" length="4" />
<data name="dispToAccessHostNames" type="int" length="4" />
<data name="nbrOfAccessHostNames" type="int" length="4" />
<data name="dispToHostOptions" type="int" length="4" />
<data name="nbrOfHostOptions" type="int" length="4" />
<data name="anonUserID" type="int" length="4" />
<data name="anonUsrPrf" type="char" length="10" />
<data name="pathName" type="char" length="lengthOfObjectPathName"
offset="dispToObjectPathName" offsetfrom="receiver" />
<struct name="returnedRcdsFdbkInfo">
<data name="bytesReturned" type="int" length="4" />
<data name="bytesAvailable" type="int" length="4" />
<data name="nbrOfNFSExportEntries" type="int" length="4" />
<data name="handle" type="int" length="4" />
</struct>
</pcml>
System.setErr(System.out);
try
{
// Uncomment the following to get debugging information
// com.ibm.as400.data.PcmlMessageLog.setTraceEnabled(true);
// Construct ProgramCallDocument
// First parameter is system to connect to
// Second parameter is pcml resource name. In this example,
// serialized PCML file "qznfrtve.pcml.ser" or
// PCML source file "qznfrtve.pcml" must be found in the classpath.
pcml = new ProgramCallDocument(as400System, "qznfrtve");
if (rc == false)
{
// Retrieve list of server messages
AS400Message[] msgs = pcml.getMessageList("qznfrtve");
// Iterate and write out Read Write Host Names for this export
nbrOfReadWriteHostNames = pcml.getIntValue("qznfrtve.receiver.nbrOfReadWriteHostNames",
indices);
for(indices[1] = 0; indices[1] < nbrOfReadWriteHostNames; indices[1]++)
{
value = pcml.getValue("qznfrtve.receiver.rwAccessList.hostName", indices);
System.out.println(" Read/write access host name = " + value);
}
// Iterate and write out Root Host Names for this export
nbrOfRootHostNames = pcml.getIntValue("qznfrtve.receiver.nbrOfRootHostNames", indices);
for(indices[1] = 0; indices[1] < nbrOfRootHostNames; indices[1]++)
{
value = pcml.getValue("qznfrtve.receiver.rootAccessList.hostName", indices);
System.out.println(" Root access host name = " + value);
}
// Iterate and write out Access Host Names for this export
nbrOfAccessHostnames = pcml.getIntValue("qznfrtve.receiver.nbrOfAccessHostNames",
indices);
for(indices[1] = 0; indices[1] < nbrOfAccessHostnames; indices[1]++)
{
value = pcml.getValue("qznfrtve.receiver.accessHostNames.hostName", indices);
System.out.println(" Access host name = " + value);
}
System.exit(0);
} // end main()
}
The following disclaimer applies to all of the IBM Toolbox for Java examples:
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
Note: Read the Code example disclaimer for important legal information.
To view the contents of an example JSP source file that you can use with JSPRunReport, see
JSPcust_table.jsp. You can also download a ZIP file that contains the JSP example file. The zipped file also
contains XML and XSL example files that you can use with the XSLReportProcessor example
(PCLRunReport).
//////////////////////////////////////////////////////////////////////////////////
//
// The following example (JSPRunReport) uses the JSPReportProcessor and the
// PDFContext classes to obtain data from a specified URL and convert the data
// to the PDF format. The data is then streamed to a file as a PDF document.
//
// Command syntax:
// java JSPRunReport <jsp_Url> <output_filename>
//
//////////////////////////////////////////////////////////////////////////////////
import java.lang.*;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.awt.print.*;
import java.awt.event.*;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.HashMap;
import com.ibm.xsl.composer.flo.*;
import com.ibm.xsl.composer.areas.*;
import com.ibm.xsl.composer.framework.*;
import com.ibm.xsl.composer.java2d.*;
import com.ibm.xsl.composer.prim.*;
import com.ibm.xsl.composer.properties.*;
import com.ibm.as400.util.reportwriter.processor.*;
import com.ibm.as400.util.reportwriter.pdfwriter.*;
import java.io.IOException;
import java.io.Serializable;
import org.xml.sax.SAXException;
/** create the JSPReportProcessor object and set the template to the specified JSP **/
JSPReportProcessor jspprocessor = new JSPReportProcessor(pdfcontext);
try {
jspprocessor.setTemplate(jspurl);
}
System.exit(0);
}
}
Note: Read the Code example disclaimer for important legal information.
<!--
Copyright (c) 1999 The Apache Software Foundation. All rights reserved.
-->
<%!
String[][] cust_data = new String [4][5];
cust_data[0] = cust_record_1;
cust_data[1] = cust_record_2;
cust_data[2] = cust_record_3;
cust_data[3] = cust_record_4;
}
%>
<%
// add row to table
for(int i = 0; i <= 3; i++)
{
String[] _array = cust_data[i];
%>
<fo:table-row>
<fo:table-cell column-number="1">
<fo:block space-before=".1in">
<% if(_array[0].equals("IBM")) { %>
<fo:inline background-color="blue">
<% out.print(_array[0]); %>
</fo:inline>
<% } else { %>
<% out.print(_array[0]); %>
<% } %>
</fo:block>
</fo:table-cell>
<fo:table-cell column-number="2">
<fo:block space-before=".1in">
<% out.print(_array[1]); %>
</fo:block>
</fo:table-cell>
<fo:table-cell column-number="3">
<fo:block space-before=".1in">
<% out.print(_array[2]); %>
</fo:block>
</fo:table-cell>
<fo:table-cell column-number="4">
<fo:block space-before=".1in">
<% out.print(_array[3]); %>
</fo:block>
</fo:table-cell>
<fo:table-cell column-number="5">
<fo:block space-before=".1in">
<% out.print(_array[4]); %>
</fo:block>
</fo:table-cell>
</fo:table-row>
<%
} // end row while
%>
</fo:table-body>
</fo:table>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// The following example (PCLRunReport) uses the XSLPReportProcessor and the
// PCLContext classes to obtain XML data and convert the data to the PCL format.
// The data is then streamed to a printer OutputQueue.
//
// To view the contents of example XML and XSL source files that you can use
// with PCLRunReport, see realestate.xml and realestate.xsl. You can also
// download a zip file that contains the XML and XSL example files. The zip
// file also contains a JSP example file that you can use with the
// JSPReportProcessor example (JSPRunReport).
//
// Command syntax:
// java PCLRunReport <xml_file> <xsl_file>
//
//////////////////////////////////////////////////////////////////////////////////
import java.lang.*;
import java.awt.*;
import java.io.*;
import java.awt.print.*;
import java.awt.event.*;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.HashMap;
import com.ibm.xsl.composer.flo.*;
import com.ibm.xsl.composer.areas.*;
import com.ibm.xsl.composer.framework.*;
import com.ibm.xsl.composer.java2d.*;
import com.ibm.xsl.composer.prim.*;
import com.ibm.xsl.composer.properties.*;
import com.ibm.as400.util.reportwriter.processor.*;
import com.ibm.as400.util.reportwriter.pclwriter.*;
import java.io.IOException;
import java.io.Serializable;
import org.xml.sax.SAXException;
import com.ibm.as400.access.*;
try{
System.exit(0);
}
Note: Read the Code example disclaimer for important legal information.
<?xml version="1.0"?>
<RESIDENTIAL-LISTINGS VERSION="061698">
</GENERAL>
<FEATURES>
<DISCLOSURES>
In your dreams.
</DISCLOSURES>
<UTILITIES>
Yes
</UTILITIES>
<EXTRAS>
Pest control included.
</EXTRAS>
<CONSTRUCTION>
Wallboard and glue
</CONSTRUCTION>
<ACCESS>
Front door.
</ACCESS>
</FEATURES>
<REMARKS>
</REMARKS>
<CONTACTS>
<COMPANY>
<NAME>
Noplace Realty
</NAME>
<ADDRESS>
12 Main Street
</ADDRESS>
<CITY>
Lowell, MA
</CITY>
<ZIP>
34567
</ZIP>
</COMPANY>
<AGENT>
<NAME>
Mary Jones
</NAME>
<ADDRESS>
</ADDRESS>
<CITY>
</CITY>
<ZIP>
</ZIP>
</AGENT>
<OWNER>
<NAME>
</NAME>
<ADDRESS>
</ADDRESS>
<CITY>
</CITY>
<ZIP>
</ZIP>
</OWNER>
</RESIDENTIAL-LISTING>
<MLS>
<MLS-CODE SECURITY="Restricted">
30298877
</MLS-CODE>
<MLS-SOURCE SECURITY="Public">
<NAME>
Mary the Realtor
</NAME>
<PHONE>
1-617-555-3333
</PHONE>
<FAX>
1-617-555-4444
</FAX>
<WEB>
<EMAIL>
[email protected]
</EMAIL>
<SITE>
www.bigbucks.com
</SITE>
</WEB>
</MLS-SOURCE>
</MLS>
<TYPE>
Home
</TYPE>
<PRICE>
$200,000
</PRICE>
<AGE UNITS="MONTHS">
3
</AGE>
<STRUCTURE>
<NUM-BEDS>
<DATES>
<LISTING-DATE>
4/3/98
</LISTING-DATE>
</DATES>
<LAND-AREA UNITS="ACRES">
0.01
</LAND-AREA>
</GENERAL>
<FEATURES>
<DISCLOSURES>
In your dreams.
</DISCLOSURES>
<UTILITIES>
Yes
</UTILITIES>
<EXTRAS>
Pest control included.
</EXTRAS>
<CONSTRUCTION>
Wallboard and glue
</CONSTRUCTION>
<ACCESS>
Front door.
</ACCESS>
</FEATURES>
<FINANCIAL>
<ASSUMABLE>
I assume so.
</ASSUMABLE>
<OWNER-CARRY>
Too heavy.
</OWNER-CARRY>
<ASSESMENTS>
$150,000
</ASSESMENTS>
<DUES>
$100
</DUES>
<TAXES>
$2,000
</TAXES>
<LENDER>
Fly by nite mortgage co.
</LENDER>
<EARNEST>
Burt
</EARNEST>
<DIRECTIONS>
North, south, east, west
</DIRECTIONS>
</FINANCIAL>
<REMARKS>
</REMARKS>
</RESIDENTIAL-LISTING>
<RESIDENTIAL-LISTING VERSION="061698" ID="ID1290">
<GENERAL>
<MLS>
<MLS-CODE SECURITY="Restricted">
20079877
</MLS-CODE>
<MLS-SOURCE SECURITY="Public">
<NAME>
Bob the Realtor
</NAME>
<PHONE>
1-617-555-1212
</PHONE>
<FAX>
1-617-555-1313
</FAX>
<WEB>
<EMAIL>
<TYPE>
Apartment
</TYPE>
<PRICE>
$65,000
</PRICE>
<AGE UNITS="YEARS">
30
</AGE>
<STRUCTURE>
<NUM-BEDS>
3
</NUM-BEDS>
<NUM-BATHS>
1
</NUM-BATHS>
</STRUCTURE>
<DATES>
<LISTING-DATE>
3/5/97
</LISTING-DATE>
</DATES>
<LAND-AREA UNITS="ACRES">
0.05
</LAND-AREA>
</GENERAL>
<FEATURES>
<DISCLOSURES>
In your dreams.
</DISCLOSURES>
<UTILITIES>
Yes
</UTILITIES>
<EXTRAS>
Pest control included.
</EXTRAS>
<CONSTRUCTION>
Wallboard and glue
</CONSTRUCTION>
<FINANCIAL>
<ASSUMABLE>
I assume so.
</ASSUMABLE>
<OWNER-CARRY>
Too heavy.
</OWNER-CARRY>
<ASSESMENTS>
$150,000
</ASSESMENTS>
<DUES>
$100
</DUES>
<TAXES>
$2,000
</TAXES>
<LENDER>
Fly by nite mortgage co.
</LENDER>
<EARNEST>
Burt
</EARNEST>
<DIRECTIONS>
North, south, east, west
</DIRECTIONS>
</FINANCIAL>
<REMARKS>
</REMARKS>
<CONTACTS>
<COMPANY>
<NAME>
Noplace Realty
</NAME>
<ADDRESS>
12 Main Street
</ADDRESS>
<CITY>
Lowell, MA
</CITY>
<ZIP>
34567
</ZIP>
</COMPANY>
<AGENT>
<NAME>
Mary Jones
</NAME>
<ADDRESS>
</ADDRESS>
<CITY>
</CITY>
<ZIP>
</ZIP>
</AGENT>
<OWNER>
<NAME>
</NAME>
<ADDRESS>
</ADDRESS>
<CITY>
</RESIDENTIAL-LISTING>
<RESIDENTIAL-LISTING VERSION="061698" ID="ID1291">
<GENERAL>
<MLS>
<MLS-CODE SECURITY="Restricted">
29389877
</MLS-CODE>
<MLS-SOURCE SECURITY="Public">
<NAME>
Mary the Realtor
</NAME>
<PHONE>
1-617-555-3333
</PHONE>
<FAX>
1-617-555-4444
</FAX>
<WEB>
<EMAIL>
[email protected]
</EMAIL>
<SITE>
www.bigbucks.com
</SITE>
</WEB>
</MLS-SOURCE>
</MLS>
<TYPE>
Home
</TYPE>
<PRICE>
$449,000
</PRICE>
<AGE UNITS="YEARS">
7
</AGE>
<DATES>
<LISTING-DATE>
6/8/98
</LISTING-DATE>
</DATES>
<LAND-AREA UNITS="ACRES">
2.0
</LAND-AREA>
</GENERAL>
<FEATURES>
<DISCLOSURES>
In your dreams.
</DISCLOSURES>
<UTILITIES>
Yes
</UTILITIES>
<EXTRAS>
Pest control included.
</EXTRAS>
<CONSTRUCTION>
Wallboard and glue
</CONSTRUCTION>
<ACCESS>
Front door.
</ACCESS>
</FEATURES>
<FINANCIAL>
<ASSUMABLE>
I assume so.
</ASSUMABLE>
<OWNER-CARRY>
Too heavy.
</OWNER-CARRY>
<ASSESMENTS>
$300,000
</ASSESMENTS>
<DUES>
$100
</DUES>
<TAXES>
$2,000
</TAXES>
<LENDER>
Fly by nite mortgage co.
</LENDER>
<EARNEST>
Burt
</EARNEST>
<DIRECTIONS>
North, south, east, west
</DIRECTIONS>
</FINANCIAL>
<CONTACTS>
<COMPANY>
<NAME>
Noplace Realty
</NAME>
<ADDRESS>
12 Main Street
</ADDRESS>
<CITY>
Lowell, MA
</CITY>
<ZIP>
34567
</ZIP>
</COMPANY>
<AGENT>
<NAME>
Mary Jones
</NAME>
<ADDRESS>
</ADDRESS>
<CITY>
</CITY>
<ZIP>
</ZIP>
</AGENT>
<OWNER>
<NAME>
</NAME>
<ADDRESS>
</ADDRESS>
<CITY>
</CITY>
<ZIP>
</ZIP>
</OWNER>
<TENANT>
Yes.
</TENANT>
<COMMISION>
15%
</COMMISION>
</CONTACTS>
</RESIDENTIAL-LISTING>
</RESIDENTIAL-LISTINGS>
Note: Read the Code example disclaimer for important legal information.
<?xml version="1.0"?>
<xsl:template match="RESIDENTIAL-LISTINGS">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="theMaster">
<fo:region-body region-name="theRegion"/>
</xsl:template>
</xsl:stylesheet>
ResourceList
v Example: Getting and printing the contents of a ResourceList
v Example: Using generic code to access a ResourceList
v Example: Presenting a resource list in a servlet
Presentation
v Example: Using Presentations
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
Related information:
RJobList Javadoc
The columns for a ResourceListRowData object are specified as an array of column attribute IDs while
each row represents a resource object.
// Create the resource list. This example creates
// a list of all messages in the current user’s message
// queue.
AS400 system = new AS400("MYSYSTEM", "MYUSERID", "MYPASSWORD");
RMessageQueue messageQueue = new RMessageQueue(system, RMessageQueue.CURRENT);
Examples
Here is an example of generic code that prints some of the contents of a ResourceList:
void printContents(ResourceList resourceList, long numberOfItems) throws ResourceException
{
// Open the list and wait for the requested number of items
// to become available.
resourceList.open();
resourceList.waitForResource(numberOfItems);
This is an example of generic code that prints the value of every attribute supported by a resource:
void printAllAttributeValues(Resource resource) throws ResourceException
{
// Get the attribute meta data.
ResourceMetaData[] attributeMetaData = resource.getAttributeMetaData();
Examples: RFML
This section lists the code examples that are provided throughout the documentation of the IBM Toolbox
for Java RFML component.
v Example: Using RFML compared to using IBM Toolbox for Java Record classes
v Example: RFML source file
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
Note: Read the Code example disclaimer for important legal information.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE rfml SYSTEM "rfml.dtd">
</recordformat>
<recordformat name="cusrec1">
</recordformat>
<recordformat name="cusrecAscii">
</recordformat>
<struct name="balance">
<data name="amount" type="zoned" length="6" precision="2" init="7"/>
</struct>
</rfml>
Related reference:
“Example: Using RFML compared to using IBM Toolbox for Java Record classes” on page 409
This example illustrates the differences between using RFML and using the IBM Toolbox for Java Record
classes.
You can also use the servlet and HTML classes together, like in this example.
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
HTML source generated from the Java source by the using HTMLTableConverter
Using the “HTMLTableConverter class” on page 237 in the Java source example above generates the
following HTML code.
<table>
<tr>
<th>Customer ID</th>
<th>Order Number</th>
</tr>
<tr>
<td>777-53-4444</td>
<td>12345-XYZ</td>
The following table shows how the HTML source code looks when viewed in a browser.
Using the HTMLTableConverter class in the Java source example above generates the following HTML
code.
<table>
<tr>
<th>CNUM</th>
<th>LNAM</th>
<th>INIT</th>
<th>STR</th>
<th>CTY</th>
<th>STATE</th>
<th>ZIP</th>
<th>CTLMT</th>
<th>CHGCOD</th>
<th>BDUE</th>
<th>CTDUE</th>
</tr>
<tr>
<td>938472</td>
<td>Henning </td>
<td>G K</td>
<td>4859 Elm Ave </td>
<td>Dallas</td>
<td>TX</td>
<td align="right">75217</td>
<td align="right">5000</td>
<td align="right">3</td>
<td align="right">37.00</td>
<td align="right">0.00</td>
</tr>
<tr>
<td>839283</td>
<td>Jones </td>
<td>B D</td>
<td>21B NW 135 St</td>
<td>Clay </td>
<td>NY</td>
<td align="right">13041</td>
<td align="right">400</td>
<td align="right">1</td>
<td align="right">100.00</td>
<td align="right">0.00</td>
</tr>
<tr>
<td>392859</td>
<td>Vine </td>
<td>S S</td>
<td>PO Box 79 </td>
<td>Broton</td>
<td>VT</td>
<td align="right">5046</td>
<td align="right">700</td>
<td align="right">1</td>
<td align="right">439.00</td>
<td align="right">0.00</td>
</tr>
</table>
The following table shows how the HTML source code looks when viewed in a browser.
CNUM LNAM INIT STR CTY STATE ZIP CTLMT CHGCOD BDUE CTDUE
938472 Henning GK 4859 Elm Ave Dallas TX 75217 5000 3 37.00 0.00
HTML source generated from the Java source by the using HTMLTableConverter
Using the HTMLTableConverter class in the Java source example above generates the following HTML
code.
<table border="2" cellpadding="1" cellspacing="1">
<tr>
<th>Customer Number</th>
<th>Last Name</th>
<th>Initials</th>
The following table shows how the HTML source code looks when viewed in a browser.
import com.ibm.as400.util.html.GridLayoutFormPanel;
import com.ibm.as400.util.html.HTMLConstants;
import com.ibm.as400.util.html.HTMLForm;
import com.ibm.as400.util.html.HTMLTable;
import com.ibm.as400.util.html.HTMLTableCaption;
import com.ibm.as400.util.html.HTMLText;
import com.ibm.as400.util.html.LabelFormElement;
import com.ibm.as400.util.html.LineLayoutFormPanel;
import com.ibm.as400.util.html.SubmitFormInput;
import com.ibm.as400.util.html.TextFormInput;
import com.ibm.as400.util.servlet.HTMLFormConverter;
import com.ibm.as400.util.servlet.SQLResultSetRowData;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400JDBCDriver;
/**
* An example of using the HTMLFormConverter class in a servlet.
*/
public class HTMLFormConverterExample extends HttpServlet
{
private String userId_ = "myUserId";
private String password_ = "myPwd";
private AS400 system_;
out.println(showHtmlMain());
out.close();
}
response.setContentType("text/html");
// Retrieve the row data and HTML table values for this session.
rowData = (SQLResultSetRowData) session.getValue("sessionRowData");
htmlTable = (HTMLTable[]) session.getValue("sessionHtmlTable");
if (rowData != null)
{
// Set the row data value for this session.
session.putValue("sessionRowData", rowData);
if (htmlTable != null)
{
rowData.first();
session.putValue("sessionHtmlTable", htmlTable);
out.println(showHtmlForRecord(htmlTable, 0));
}
}
}
// If the "Return To Main" button was pressed,
// go back to the main HTML form
else if (parameters.containsKey("returnToMain"))
{
session.invalidate();
cleanup();
out.println(showHtmlMain());
}
// if the "First" button was pressed, show the first record
else if (parameters.containsKey("getFirstRecord"))
{
rowData.first();
out.println(showHtmlForRecord(htmlTable, 0));
}
// if the "Previous" button was pressed, show the previous record
else if (parameters.containsKey("getPreviousRecord"))
{
if (!rowData.previous())
{
rowData.first();
}
out.println(showHtmlForRecord(htmlTable, rowData.getCurrentPosition()));
}
// if the "Next" button was pressed, show the next record
else if (parameters.containsKey("getNextRecord"))
{
if (!rowData.next())
{
rowData.last();
}
out.println(showHtmlForRecord(htmlTable, rowData.getCurrentPosition()));
}
// if the "Last" button was pressed, show the last record
else if (parameters.containsKey("getLastRecord"))
{
rowData.last();
out.println(showHtmlForRecord(htmlTable, rowData.getCurrentPosition()));
}
// if none of the above, there must have been an error
else
{
out.println(showHtmlForError("Internal error occurred. Unexpected parameters."));
}
// Get all the records from the file input by the user.
private SQLResultSetRowData getAllRecords(Hashtable parameters, ServletOutputStream out)
throws IOException
{
SQLResultSetRowData records = null;
try
{
// Get the system, library and file name from the parameter list.
String sys = ((String) parameters.get("System")).toUpperCase();
String lib = ((String) parameters.get("Library")).toUpperCase();
String file = ((String) parameters.get("File")).toUpperCase();
if ((sys == null || sys.equals("")) ||
(lib == null || lib.equals("")) ||
(file == null || file.equals("")))
{
out.println(showHtmlForError("Invalid system, file or library name."));
}
else
{
// Get the connection to the server.
getDatabaseConnection (sys, out);
if (databaseConnection_ != null)
{
Statement sqlStatement = databaseConnection_.createStatement();
return records;
}
// Create the text element for the error and add it to the panel.
HTMLText text = new HTMLText(message);
text.setBold(true);
text.setColor(Color.red);
grid.addElement(text);
page.append(errorForm.toString());
}
catch (Exception e)
{
e.printStackTrace ();
}
page.append("</body></html>");
return page.toString();
}
try
{
// Create the HTML Form object
HTMLForm recForm = new HTMLForm("HTMLFormConverterExample");
page.append("</body></html>");
return page.toString();
}
// Show the main HTML form (request input for system, file,
// and library name).
private String showHtmlMain()
{
String title = "HTMLFormConverter Example";
StringBuffer page = new StringBuffer();
page.append (showHeader (title));
try
{
// Set up so that doPost() gets called when the form is submitted.
mainForm.setMethod(HTMLForm.METHOD_POST);
panel.addElement(sysPrompt);
panel.addElement(system);
panel.addElement(filePrompt);
panel.addElement(file);
panel.addElement(libPrompt);
panel.addElement(library);
page.append(mainForm.toString());
page.append("</body></html>");
import com.ibm.as400.util.html.*;
import com.ibm.as400.util.servlet.*;
import com.ibm.as400.access.*;
/*
An example of using IBM Toolbox for Java classes in a servlet.
File . . . . . . LICENSES
Library . . . LIGHTSON
File . . . . . . REPORTS
Library . . . LIGHTSON
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println(showHtmlMain());
out.close();
}
if (parameters.containsKey("askingToReport"))
out.println (showHtmlForReporting ());
else if (parameters.containsKey("askingToRegister"))
out.println (showHtmlForRegistering ());
else if (parameters.containsKey("askingToUnregister"))
out.println(showHtmlForUnregistering());
else if (parameters.containsKey("askingToListRegistered"))
out.println (showHtmlForListingAllRegistered ());
else if (parameters.containsKey("askingToListReported"))
out.println (showHtmlForListingAllReported ());
else if (parameters.containsKey("returningToMain"))
out.println (showHtmlMain ());
else { // None of the above, so assume the user has filled out a form
// and is submitting information. Grab the incoming info
// and do the requested action.
if (parameters.containsKey("submittingReport")) {
String acknowledgement = reportLightsOn (parameters, out);
out.println (showAcknowledgement(acknowledgement));
}
else if (parameters.containsKey("submittingRegistration")) {
String acknowledgement = registerLicense (parameters, out);
out.println (showAcknowledgement(acknowledgement));
}
else {
out.println (showAcknowledgement("Error (internal): " +
"Neither Report, Register, " +
"Unregister, ListRegistered, or ListReported."));
}
}
// Gets the parameters from an HTTP servlet request, and packages them
// into a hashtable for convenience.
private static Hashtable getRequestParameters (HttpServletRequest request)
{
Hashtable parameters = new Hashtable ();
Enumeration enum = request.getParameterNames();
while (enum.hasMoreElements()) {
String key = (String) enum.nextElement();
String value = request.getParameter (key);
parameters.put (key, value);
}
return parameters;
}
// Removes blanks and hyphens from a String, and sets it to all uppercase.
private static String normalize (String oldString)
{
if (oldString == null || oldString.length() == 0) return null;
StringBuffer newString = new StringBuffer ();
for (int i=0; i<oldString.length(); i++) {
if (oldString.charAt(i) != ’ ’ && oldString.charAt(i) != ’-’)
newString.append (oldString.charAt(i));
}
return newString.toString().toUpperCase();
}
system_.setSystemName(sysName);
system_.setUserId(userId);
system_.setPassword(password);
password_ = password;
system_.connectService(AS400.DATABASE);
system_.connectService(AS400.FILE);
system_.addPasswordCacheEntry(sysName, userId, password_);
}
}
catch (Exception e) { e.printStackTrace (); system_ = null; }
return system_;
}
try {
super.init(config);
}
catch (Exception e) { e.printStackTrace(); }
}
}
catch (Exception e) { e.printStackTrace (); }
}
}
if (acknowledgement.length() == 0)
{
try
{
// Insert the new license number and e-mail address into the database.
getDatabaseConnection ();
Statement sqlStatement = databaseConnection_.createStatement();
if (acknowledgement.length() == 0)
{
try
{
// Remove the specified license number and e-mail address from database.
getDatabaseConnection ();
Statement sqlStatement = databaseConnection_.createStatement();
if (acknowledgement.length() == 0)
{
try
{
// Report "lights on" for a specified vehicle.
getDatabaseConnection ();
Statement sqlStatement = databaseConnection_.createStatement();
try {
HTMLForm form = new HTMLForm("LightsOn");
GridLayoutFormPanel grid = new GridLayoutFormPanel();
HTMLText text = new HTMLText(acknowledgement);
if (acknowledgement.startsWith("Error"))
text.setBold(true);
grid.addElement(text);
grid.addElement(new SubmitFormInput("returningToMain", "Home"));
form.addElement(grid);
page.append(form.toString());
}
catch (Exception e) { e.printStackTrace (); }
page.append("</body></html>");
return page.toString();
}
try {
// Set up so that doPost() gets called when the form is submitted.
mainForm.setMethod(HTMLForm.METHOD_POST);
mainForm.addElement(grid);
}
catch (Exception e) { e.printStackTrace (); }
page.append(mainForm.toString());
page.append("</body></html>");
return page.toString();
}
try {
// Set up so that doPost() gets called when the form is submitted.
reportForm.setMethod(HTMLForm.METHOD_POST);
grid.addElement(new LabelFormElement("Color:"));
grid.addElement(colorGroup);
grid.addElement(new LabelFormElement("Building:"));
grid.addElement(location);
reportForm.addElement(grid);
}
catch (Exception e) { e.printStackTrace (); }
page.append(reportForm.toString());
page.append("</body></html>");
return page.toString();
}
try {
// Set up so that doPost() gets called when the form is submitted.
registrationForm.setMethod(HTMLForm.METHOD_POST);
registrationForm.addElement(grid);
}
catch (Exception e) { e.printStackTrace (); }
page.append(registrationForm.toString());
page.append("</body></html>");
return page.toString();
}
try {
// Set up so that doPost() gets called when the form is submitted.
unregistrationForm.setMethod(HTMLForm.METHOD_POST);
unregistrationForm.addElement(grid);
}
catch (Exception e) {
e.printStackTrace ();
CharArrayWriter cWriter = new CharArrayWriter();
PrintWriter pWriter = new PrintWriter (cWriter, true);
e.printStackTrace (pWriter);
page.append (cWriter.toString());
}
page.append(unregistrationForm.toString());
page.append("</body></html>");
return page.toString();
}
getDatabaseConnection ();
Statement sqlStatement = databaseConnection_.createStatement();
if (rowCount == 0) {
page.append ("<font size=4 color=red>No vehicles have been reported.</font>");
}
else {
query = "SELECT LICENSE,WHEN_ADDED FROM LICENSES";
rs = sqlStatement.executeQuery (query);
SQLResultSetRowData rowData = new SQLResultSetRowData (rs);
HTMLTable[] generatedHtml = converter.convertToTables(rowData);
grid.addElement(generatedHtml[0]);
}
sqlStatement.close();
// Note: Mustn’t close statement before we’re done using result set.
mainForm.addElement(grid);
page.append(mainForm.toString());
}
catch (Exception e) { e.printStackTrace (); }
page.append("</body></html>");
return page.toString();
}
try
getDatabaseConnection ();
Statement sqlStatement = databaseConnection_.createStatement();
if (rowCount == 0) {
page.append ("<font size=4 color=red>No vehicles have been reported.</font>");
}
else {
query = "SELECT LICENSE,COLOR,CATEGORY,DATE_ADDED,TIME_ADDED FROM REPORTS";
rs = sqlStatement.executeQuery (query);
SQLResultSetRowData rowData = new SQLResultSetRowData (rs);
HTMLTable[] generatedHtml = converter.convertToTables(rowData);
grid.addElement(generatedHtml[0]);
}
sqlStatement.close();
// Note: Mustn’t close statement before we’re done using result set.
If you want some help getting started, see Writing your first IBM Toolbox for Java program.
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
You can decide which version you want to install by reviewing Requirements for running Java
applications.
After you have Java installed on your client, complete the following tasks:
1. Copy jt400.jar to the workstation.
2. Add jt400.jar to the CLASSPATH on your workstation by appending the full path of the JAR file to
the CLASSPATH. For example, when the jt400.jar file resides in the c:\lib directory on your
workstation (running Windows), add the following to the end of your CLASSPATH statement:
;c:\lib\jt400.jar
3. Open a text editor and type the first simple programming example
Note: Make sure to leave out the text that refers to the Notes (for example, Note 1, Note 2, and so
on). Save the new document with the name CmdCall.java.
4. Start a command session on your workstation and use the following command to compile the simple
programming example:
javac CmdCall.java
5. In the command session, type the following command to run the simple programming example:
java CmdCall
import com.ibm.as400.access.*;
System.exit(0);
}
}
1. IBM Toolbox for Java uses the "AS400" object to identify the target server. If you construct the AS400
object with no parameters, IBM Toolbox for Java prompts for the system name, userid and password.
The AS400 class also includes a constructor that takes the system name, userid and password.
2. Use the IBM Toolbox for Java CommandCall object to send commands to the server. When you create
the CommandCall object, you pass it an AS400 object so that it knows which server is the target of the
command.
3. Use the run() method on the command call object to run a command.
4. The result of running a command is a list of IBM i messages. IBM Toolbox for Java represents these
messages as AS400Message objects. When the command is complete, you get the resulting messages
from the CommandCall object.
5. Print the message text. Also available are the message ID, message severity, and other information.
This program prints only the message text.
[ Next part ]
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// Example using the Message Queue function of the IBM Toolbox for Java
//
// This source is an example of IBM Toolbox for Java "Message Queue".
//
//////////////////////////////////////////////////////////////////////////////////
import java.io.*;
import java.util.*;
System.exit(0); Note 5
}
void displayMessage()
{
}
[ Next part ]
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// Example using the Message Queue function of the IBM Toolbox for Java
//
// This source is an example of IBM Toolbox for Java "Message Queue".
//
//////////////////////////////////////////////////////////////////////////////////
package examples;
import java.io.*;
import java.util.*;
import com.ibm.as400.access.*;
me.Main(parameters);
System.exit(0);
}
void displayMessage()
{
}
if (parms.length > 0)
system.setSystemName(parms[0]); Note 2
}
catch (Exception e)
[ Previous part ]
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// Example using the Message Queue function of the IBM Toolbox for Java
//
// This source is an example of IBM Toolbox for Java "Message Queue".
//
//////////////////////////////////////////////////////////////////////////////////
package examples;
import java.io.*;
import java.util.*;
import com.ibm.as400.access.*;
me.Main(parameters);
System.exit(0);
}
void displayMessage()
{
}
if (parms.length > 0)
system.setSystemName(parms[0]);
while (e.hasMoreElements())
{
[ Previous part ]
[ Next part ]
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// Record level access example. This program will prompt the user
// for the name of the server and the file to display. The file must exist
// and contain records. Each record in the file will be displayed
// to System.out.
//
// Calling syntax: java RLSequentialAccessExample
//
// This source is an example of IBM Toolbox for Java "RecordLevelAccess"
import java.io.*;
import java.util.*;
import com.ibm.as400.access.*;
System.out.println();
try
{
System.out.print("System name: ");
systemName = inputStream.readLine();
System.out.println();
}
catch (Exception e)
{
System.out.println("Error obtaining user input.");
e.printStackTrace();
System.exit(0);
}
theFile.setRecordFormat(format[0]); Note 5
theFile.close(); Note 8
system.disconnectService(AS400.RECORDACCESS); Note 9
}
catch (Exception e)
{
System.out.println("Error occurred attempting to display the file.");
e.printStackTrace();
try
{
// Close the file
theFile.close();
}
catch(Exception x)
{
}
system.disconnectService(AS400.RECORDACCESS);
System.exit(0);
}
// Make sure that the application ends; see readme for details
System.exit(0);
}
}
1. This line of code creates an AS400 object and connects to the record-level access service.
2. This line creates a QSYSObjectPathName object that obtains the integrated file system path name form
of the object to be displayed.
3. This statement creates an object that represents an existing sequential file on the server you are
connected to. This sequential file is the file that will be displayed.
4. These lines retrieve the record format of the file.
5. This line sets the record format for the file.
6. This line opens the selected file for reading. It will read 100 records at a time, when it is possible.
[ Next part ]
[ Previous part ]
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// Record level access example.
//
// Calling syntax: java RLACreateExample
//
//////////////////////////////////////////////////////////////////////////////////
import java.io.*;
import java.util.*;
import com.ibm.as400.access.*;
try
{
SequentialFile theFile = new SequentialFile(system, filePathName);
theFile.open(AS400File.READ_WRITE, 1, AS400File.COMMIT_LOCK_LEVEL_NONE);
theFile.write(newData); Note 3
// End Note Three
system.disconnectService(AS400.RECORDACCESS);
System.exit(0);
}
}
1. (args[0]) in the previous line and MYFILE.FILE are pieces of code that are prerequisites for the rest of
the example to run. The program assumes that the library MYLIB exists on the server and that the
user has access to it.
2. The text within the Java comments labeled "Begin Note Two" and "End Note Two" shows how to
create a record format yourself instead of getting the record format from an existing file. The last line
in this block creates the file on the server.
3. The text within the Java comments labeled "Begin Note Three" and "End Note Three" shows a way to
create a record and then write it to a file.
[ Previous part ]
[ Next part ]
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// JDBCPopulate example. This program uses the IBM Toolbox for Java JDBC driver
// to create and populate a table.
//
// Command syntax:
// JDBCPopulate system collectionName tableName
//
// For example,
// JDBCPopulate MySystem MyLibrary MyTable
//
// This source is an example of IBM Toolbox for Java JDBC driver.
//
//////////////////////////////////////////////////////////////////////////////////
import java.sql.*;
try {
DriverManager.registerDriver(new com.ibm.as400.access.AS400JDBCDriver()); Note 1
try {
Statement dropTable = connection.createStatement ();
dropTable.executeUpdate ("DROP TABLE " + tableName); Note 3
}
catch (SQLException e) {
}
System.exit (0);
}
}
1. This line loads the IBM Toolbox for Java JDBC driver. A JDBC driver is necessary to mediate between
JDBC and the database you are working with.
2. This statement connects to the database. A prompt will appear for the user ID and password. A
default SQL schema is provided so that you will not need to qualify the table name in SQL
statements.
3. These lines delete the table if it already exists.
4. These lines create the table.
5. This line prepares a statement that will insert rows into the table. Because you will be executing this
statement several times, you should use a PreparedStatement and parameter markers.
6. This block of code populates the table for you; every time the loop is executed, it inserts a row into
the table.
7. Now that the table has been created and filled in, this statement closes the connection to the database.
[ Next part ]
[ Previous part ]
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// JDBCQuery example. This program uses the IBM Toolbox for Java JDBC driver to
// query a table and output its contents.
//
// Command syntax:
// JDBCQuery system collectionName tableName
//
// For example,
// JDBCQuery MySystem qiws qcustcdt
//
// This source is an example of IBM Toolbox for Java JDBC driver.
//
//////////////////////////////////////////////////////////////////////////////////
import java.sql.*;
return formattedString;
}
try {
catch (Exception e) {
System.out.println ();
System.out.println ("ERROR: " + e.getMessage());
}
finally {
// Clean up.
try {
if (connection != null)
connection.close ();
}
catch (SQLException e) {
// Ignore.
}
}
System.exit (0);
}
}
1. This line loads the IBM Toolbox for Java JDBC driver. A JDBC driver mediates between JDBC and the
database with which you are working.
2. This line retrieves the connection's meta data, an object that describes many of the characteristics of
the database.
3. This statement executes the query on the specified table.
4. These lines retrieve information about the table.
5. These lines set the column width to either the length of the label or the length of the data, whichever
is longer.
6. This block of code iterates through all of the rows in the table and displays the contents of each
column in each row.
[ Previous part ]
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// Example using the vaccess class, VJobList.
//
// This source is an example of "Job List".
//
//////////////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*; Note 2
// Create a frame.
JFrame frame = new JFrame ("Job List Example"); Note 8
// Create an error dialog adapter. This will display any errors to the user.
ErrorDialogAdapter errorHandler = new ErrorDialogAdapter (frame); Note 9
catch (Exception e)
{
e.printStackTrace(); Note 16
}
System.exit(0); Note 17
}
}
1. This class is in the examples package. Java uses packages to avoid name conflicts between Java class
files.
2. This line makes all of the IBM Toolbox for Java classes in the vaccess package available to this
program. The classes in the vaccess package have the common prefix com.ibm.as400.vaccess. By
using an import statement, the program calls the name instead of the package plus name. For
example, you can reference the AS400ExplorerPane class by using AS400ExplorerPane, not
com.ibm.as400.AS400ExplorerPane.
3. This line makes all of the Java Foundation Classes (JFC) in the Swing package available to this
program. Java programs that use the IBM Toolbox for Java vaccess (GUI) classes need JDK 1.1.2 plus
Java Swing 1.0.3 from Sun Microsystems, Inc. Swing is available with Sun's JFC 1.1.
4. This class has a main method so it can be run as an application. To invoke the program, run "java
examples.GUIExample serverName", where serverName is the name of your server. Either the
jt400.zip or jt400.jar must be in your classpath for this to work.
5. The IBM Toolbox for Java code throws exceptions that your program must catch.
6. The AS400 class is used by IBM Toolbox for Java. This class manages sign-on information, creates
and maintains socket connections, and sends and receives data. In this example, the program will
pass the server name to the AS400 object.
7. The VJobList class is used by the IBM Toolbox for Java to represent a list of server jobs that can be
displayed in a vaccess (GUI) component. Notice that the AS400 object is used to specify the server
on which the list resides.
8. This line constructs a frame or a top-level window that will be used to display the job list.
9. ErrorDialogAdapter is an IBM Toolbox for Java graphical user interface (GUI) component that is
created to automatically display a dialog window whenever an error event occurs in the application.
10. This line creates an AS400ExplorerPane, a graphical user interface (GUI) that represents a hierarchy
of objects within a server resource. The AS400ExplorerPane presents a tree on the left side rooted at
the VJobList and the details of the resource in the right side. This only initializes the pane to a
default state and does not load the contents of the VJobList to the pane.
11. This line adds the error handler you created in step nine as a listener on the VJobList graphical user
interface (GUI) component.
12. This line loads the contents of the JobList into the ExplorerPane. This method must be called
explicitly to communicate to and load information from the server. This gives the application control
over when the communication with the server will occur. With this you can:
v Load the contents before adding the pane to a frame. The frame does not appear until all the
information is loaded, as in this example.
v Load the contents after adding the pane to a frame and displaying that frame. The frame appears
with a "wait cursor" and the information is filled in as it is loaded.
13. This line adds a window listener so that the application ends when the frame closes.
14. This line adds the job list graphical user interface GUI component to the center of the controlling
frame.
15. This line calls the show method to make the window visible to the user.
Managing connections
v Example: Making a connection to the system with a CommandCall object
v Example: Making two connections to the system with a CommandCall object
v Example: Creating CommandCall and IFSFileInputStream objects with an AS400 object
v Example: Using AS400ConnectionPool to preconnect to the system
v Example: Using AS400ConnectionPool to preconnect to a specific service on the system, then reuse the
connection
Exceptions
v Example: Using exceptions
Error events
v Example: Handling error events
v Example: Defining an error listener
v Example: Using a customized handler to handle error events
Trace
v Example: Using trace
v Example: Using setTraceOn()
v Example: Using component trace
Optimization
v Example: Creating two AS400 objects
v Example: Using an AS400 object to represent a second server
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
Examples: ToolboxME
This section lists the code examples that are provided throughout the IBM Toolbox for Java 2 Micro
Edition documentation.
v “ToolboxME example: JdbcDemo.java” on page 363
v “Example: Using ToolboxME, MIDP, and JDBC”
v “Example: Using ToolboxME, MIDP, and IBM Toolbox for Java” on page 704
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
This example demonstrates how a real estate agent might be able to view and bid on properties that are
currently for sale. The agent uses a Tier0 device to access information for the properties, which is stored
in the server database.
When built as a working program, the example code below connects to a database created for this
purpose.
To create a working version of the source code and to obtain the source for creating and populating the
required database, you must download the example. You also may want to review the instructions for
creating and running the example program.
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// ToolboxME example. This program is an example MIDlet that shows how
// you might code a JdbcMe application for the MIDP profile. Refer to the
// startApp, pauseApp, destroyApp and commandAction methods to see how it handles
// each requested transition.
//
//////////////////////////////////////////////////////////////////////////////////
import com.ibm.as400.micro.*;
/*
* Construct a new JdbcMidpBid.
*/
public JdbcMidpBid()
{
display = Display.getDisplay(this);
}
/**
* Show the main screen
*/
public void startApp()
{
main.append("Show Bids", null);
main.append("Get New Bids", null);
main.append("Settings", null);
main.append("About", null);
main.addCommand(exitCommand);
main.setCommandListener(this);
display.setCurrent(main);
}
bidOnProperty();
}
} // current == listings
return;
} // instanceof List
if (s instanceof Form)
{
Form current = (Form)s;
if (current == errorForm)
{
if (c == backCommand)
display.setCurrent(onErrorGoBackTo);
/**
* The settings form.
*/
public void doSettings()
{
settingsForm = new Form("settingsform");
settingsForm.setTitle("Settings");
settingsForm.append(new StringItem("", "DB URL"));
settingsForm.append(urlText);
settingsForm.append(new StringItem("", "JdbcMe server"));
settingsForm.addCommand(backCommand);
settingsForm.setCommandListener(this);
display.setCurrent(settingsForm);
}
/**
* Show the bid screen for the bid target
* that we selected.
*/
public void bidOnProperty()
{
StringItem item = new StringItem("", bidTarget);
/**
* Update the listings card with the
* current list of bids that we are interested in.
*/
public void getNewBids()
{
// Reset the old listing
listings = null;
listings = new List("JdbcMe Bids", Choice.IMPLICIT);
java.sql.Connection conn = null;
Statement stmt = null;
try
{
conn = DriverManager.getConnection(urlText.getString() + ";" + jdbcmeText.getString());
stmt = conn.createStatement();
i = 0;
String s = null;
while (rs.next())
{
++i;
buf.append(",");
s = rs.getString(2);
buf.append(s);
buf.append(", $");
s = rs.getString(3);
buf.append(s);
listings.append(buf.toString(), null);
buf.setLength(0);
}
if (i == 0)
{
listings.append("No bids found", null);
return;
}
}
catch (Exception e)
{
// Currently no valid listings retrieved, so lets
// reset it to empty.
listings = new List("JdbcMe Bids", Choice.IMPLICIT);
listings.append(GETBIDS, null);
listings.addCommand(backCommand);
listings.setCommandListener(this);
/**
* Update the listings card with the
* current list of bids that we are interested in.
*/
public void submitBid()
{
java.sql.Connection conn = null;
Statement stmt = null;
try
{
conn = DriverManager.getConnection(urlText.getString() + ";" + jdbcmeText.getString());
stmt = conn.createStatement();
ResultSet rs = null;
try
{
// Creator and dbtype unused in MIDP
rs = new JdbcMeOfflineResultSet("JdbcMidpBidListings", 0, 0);
rs.absolute(bidRow+1);
rs.updateString(3, bidText.getString());
rs.close();
}
catch (Exception e)
{
if (rs != null)
rs.close();
}
/**
* Show an error condition.
*/
public void showError(Displayable d, Exception e)
{
String s = e.toString();
onErrorGoBackTo = d;
errorForm = new Form("Error");
errorForm.setTitle("SQL Error");
errorForm.append(new StringItem("", s));
errorForm.addCommand(backCommand);
errorForm.setCommandListener(this);
display.setCurrent(errorForm);
}
/**
* Show the current bids.
*/
public void showBids()
{
if (listings == null)
{
// If we have no current listings, lets set
// them up.
listings = new List("JdbcMe Bids", Choice.IMPLICIT);
setupListingsFromOfflineData();
}
display.setCurrent(listings);
}
/**
* Time to pause, free any space we do not need right now.
*/
public void pauseApp()
{
display.setCurrent(null);
}
/**
* Destroy must cleanup everything.
*/
public void destroyApp(boolean unconditional)
{
}
}
Related information:
“Mobile Information Device Profile (MIDP)” on page 351
This example demonstrates each of the functions built into the IBM Toolbox for Java 2 Micro Edition
support. This application features different pages or screens that illustrate some of the many ways in
which your Tier0 device can use these functions.
When built as a working program, the example code below uses a Program Call Markup Language
(PCML) file to run commands on the server.
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// ToolboxME example. This program is an example that shows how
// ToolboxME can use PCML to access data and services.
//
// This application requires that the qsyrusri.pcml file is present in the
// CLASSPATH of the MEServer.
//
//////////////////////////////////////////////////////////////////////////////////
import java.io.*;
import java.sql.*;
import java.util.Hashtable;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.rms.*;
import com.ibm.as400.micro.*;
private Displayable onErrorGoBackTo_; // the form to return to when done displaying the error form
/**
* Creates a new ToolboxMidpDemo.
**/
public ToolboxMidpDemo()
{
display_ = Display.getDisplay(this);
// Note: The KVM-based demo used TabbedPane for the main panel.
// MIDP has no similar class, so we use a List instead.
}
/**
* Show the main screen.
* Implements abstract method of class Midlet.
**/
protected void startApp()
{
main_.append(SIGN_ON, null);
main_.append(COMMAND_CALL, null);
main_.append(PROGRAM_CALL, null);
main_.append(DATA_QUEUE, null);
main_.append(ABOUT, null);
main_.addCommand(actionExit_);
main_.setCommandListener(this);
display_.setCurrent(main_);
}
notifyDestroyed();
}
switch (idx)
{
case 0: // SignOn
showSignonForm();
break;
case 1: // CommandCall
showCmdForm();
break;
case 2: // ProgramCall
showPgmForm();
break;
case 3: // DataQueue
showDqForm();
break;
case 4: // About
showAboutForm();
break;
default: // None of the above
feedback("Internal error: Unhandled selected index in main: " + idx,
AlertType.ERROR);
break;
}
} // current == main
else
feedback("Internal error: The Displayable object is a List but is not main_.",
AlertType.ERROR);
} // instanceof List
else if (dsp instanceof Form)
{
Form current = (Form)dsp;
if (current == signonForm_)
{
if (action == actionSignon_)
{
// Create a ToolboxME system object.
system_ = new AS400(signonSystemText_.getString(),
signonUidText_.getString(),
signonPwdText_.getString(),
signonServerText_.getString());
try
{
// Connect to the server.
system_.connect();
e.printStackTrace();
signonStatusText_.setText("Error.");
cmdMsgText_.setText(null);
cmdStatusText_.setText(status.toString());
}
repaint();
}
catch (Exception e)
{
feedback(e.toString(), AlertType.ERROR);
e.printStackTrace();
cmdMsgText_.setText(null);
cmdStatusText_.setText(null);
repaint();
}
else // None of the above.
{
pgmMsgText_.setText(null);
// See the PCML example in the IBM Toolbox for Java information.
String pcmlName = "qsyrusri.pcml"; // The PCML file we want to use.
String apiName = "qsyrusri";
// Create a hashtable that contains the input parameters for the program call.
Hashtable parmsToSet = new Hashtable(2);
parmsToSet.put("qsyrusri.receiverLength", "2048");
parmsToSet.put("qsyrusri.profileName", signonUidText_.getString().toUpperCase());
try
{
// Run the program.
String[] valuesToGet = ProgramCall.run(system_,
pcmlName,
apiName,
parmsToSet,
parmsToGet);
char[] c = valuesToGet[1].toCharArray();
txt.append(displayParm[1] + ": " + c[3] + c[4] + "/" +
c[5] + c[6] + "/" + c[1] + c[2] + "\n");
char[] d = valuesToGet[2].toCharArray();
txt.append(displayParm[2] + ": " + d[0] + d[1] + ":" + d[2] + d[3] + "\n");
txt.append(displayParm[3] + ": " + valuesToGet[3] + "\n");
if (valuesToGet.length == 0)
{
status.append("no returned values.");
feedback(status.toString(), AlertType.INFO);
}
}
catch (Exception e)
{
feedback(e.toString(), AlertType.ERROR);
e.printStackTrace();
repaint();
}
} // pgmcallForm_
else if (current == dataqueueForm_) // DataQueue
{
if (action == actionGo_)
{
// If the user has not signed on before performing Data Queue actions,
// display an alert.
if (system_ == null)
{
feedback(NOT_SIGNED_ON, AlertType.ERROR);
return;
}
try
{
// See which action was selected (Read or Write).
if (dqReadOrWrite_.getString(dqReadOrWrite_.getSelectedIndex()).equals(DQ_WRITE))
{
dqInputText_.setString(null);
dqOutputText_.setText(null);
}
else if (b.length == 0)
{
dqStatusText_.setText("Dataqueue entry has no data.");
dqOutputText_.setText(null);
}
else
{
dqStatusText_.setText("The ’read’ operation completed.");
dqOutputText_.setText(new String(b));
}
}
repaint();
}
catch (Exception e)
{
e.printStackTrace();
feedback(e.toString(), AlertType.ERROR);
dqOutputText_.setText(null);
repaint();
}
else // None of the above.
{
feedback("Internal error: Action is not recognized.", AlertType.INFO);
}
} // dataqueueForm_
else if (current == aboutForm_) // "About".
{
// Should never reach here, since the only button is "Back".
} // None of the above.
else
feedback("Internal error: Form is not recognized.", AlertType.ERROR);
} // instanceof Form
else
feedback("Internal error: Displayable object not recognized.", AlertType.ERROR);
}
/**
* Displays the "About" form.
**/
private void showAboutForm()
{
// If the about form is null, create and append it.
if (aboutForm_ == null)
{
aboutForm_ = new Form(ABOUT);
aboutForm_.append(new StringItem(null,
"This is a MIDP example application that uses the " +
"IBM Toolbox for Java Micro Edition (ToolboxME)."));
aboutForm_.addCommand(actionBack_);
aboutForm_.setCommandListener(this);
}
display_.setCurrent(aboutForm_);
}
/**
* Displays the "SignOn" form.
**/
private void showSignonForm()
{
// Create the signon form.
if (signonForm_ == null)
{
signonForm_ = new Form(SIGN_ON);
signonForm_.append(signonSystemText_);
signonForm_.append(signonUidText_);
signonForm_.append(signonPwdText_);
signonForm_.append(signonServerText_);
signonForm_.append(signonStatusText_);
signonForm_.addCommand(actionBack_);
signonForm_.addCommand(actionSignon_);
signonForm_.setCommandListener(this);
signonForm_.setTicker(ticker_);
}
display_.setCurrent(signonForm_);
}
display_.setCurrent(cmdcallForm_);
}
/**
* Displays the "ProgramCall" form.
**/
private void showPgmForm()
{
// Create the program call form.
if (pgmcallForm_ == null)
{
pgmcallForm_ = new Form(PROGRAM_CALL);
pgmcallForm_.append(new StringItem(null,
"This calls the Retrieve User Information (QSYRUSRI) " +
"API, and returns information about the current " +
"user profile."));
pgmcallForm_.append(pgmMsgText_);
pgmcallForm_.addCommand(actionBack_);
pgmcallForm_.addCommand(actionClear_);
pgmcallForm_.addCommand(actionRun_);
pgmcallForm_.setCommandListener(this);
pgmcallForm_.setTicker(ticker_);
}
display_.setCurrent(pgmcallForm_);
}
/**
* Displays the "DataQueue" form.
**/
private void showDqForm()
{
// Create the data queue form.
if (dataqueueForm_ == null)
{
dataqueueForm_ = new Form(DATA_QUEUE);
dataqueueForm_.append(dqInputText_);
dataqueueForm_.append(dqOutputText_);
dataqueueForm_.append(dqReadOrWrite_);
dataqueueForm_.append(dqStatusText_);
dataqueueForm_.addCommand(actionBack_);
dataqueueForm_.addCommand(actionClear_);
dataqueueForm_.addCommand(actionGo_);
display_.setCurrent(dataqueueForm_);
}
/**
* This method is used to create a dialog and display feedback
* information using an Alert to the user.
**/
private void feedback(String text, AlertType type, Displayable returnToForm)
{
System.err.flush();
System.out.flush();
if (type == AlertType.INFO)
alert.setTimeout(3000); // milliseconds
else
alert.setTimeout(Alert.FOREVER); // Require user to dismiss the alert.
display_.setCurrent(alert, returnToForm);
}
display_.setCurrent(alert, display_.getCurrent());
}
/**
* Time to pause, free any space we don’t need right now.
* Implements abstract method of class Midlet.
**/
protected void pauseApp()
{
display_.setCurrent(null);
}
/**
* Destroy must cleanup everything.
* Implements abstract method of class Midlet.
**/
protected void destroyApp(boolean unconditional)
{
// Disconnect from the server if the Midlet is being destroyed or exited.
if (system_ != null)
{
try
{
system_.disconnect();
AS/400ToolboxJarMaker
v Example: Extracting AS400.class and all its dependent classes from jt400.jar
v Example: Splitting jt400.jar into a set of 300KB files
v Example: Removing unused files from a JAR file
v Example: Creating a 400KB smaller JAR file by omitting the conversion tables with the -ccsid
parameter
CommandPrompter
v Example: Using CommandPrompter to prompt for and run a command
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// CommandPrompter example. This program uses CommandPrompter, CommandCall, and
// AS400Message to prompt for a command, run the command, and display any
// messages returned if the command does not run.
//
// Command syntax:
// Prompter commandString
//
//////////////////////////////////////////////////////////////////////////////////
import com.ibm.as400.ui.util.CommandPrompter;
import com.ibm.as400.access.AS400;
AS400Panes
v Example: Creating an AS400DetailsPane to present the list of users defined on the
systemAS400DetailsPane
v Example: Loading the contents of a details pane before adding it to a frame
v Example: Using an AS400ListPane to present a list of users
v Example: Using an AS400DetailsPane to display messages returned from a command call
v Example: Using an AS400TreePane to display a tree view of a directory
v Example: Using an AS400ExplorerPane to present various print resources
Command call
v Example: Creating a CommandCallButton
v Example: Adding the ActionCompletedListener to process all IBM i messages that a command
generates
v Example: Using the CommandCallMenuItem
Data queues
v Example: Creating a DataQueueDocument
v Example: Using a DataQueueDocument
JDBC
v Example: Using the JDBC driver to create and populate a table
v Example: Using the JDBC driver to query a table and output its contents
v Example: Creating an AS400JDBCDataSourcePane
Jobs
v Example: Creating a VJobList and presenting the list in an AS400ExplorerPane
v Example: Presenting a list of jobs in an explorer pane
Messages
v Example: Using VMessageQueue
Program call
v Example: Creating a ProgramCallMenuItem
v Example: Processing all program generated IBM i messages
v Example: Adding two parameters
v Example: Using a ProgramCallButton in an application
Print
v Example: Using VPrinter
v Example: VPrinterOutput
Record-level access
v Example: Creating a RecordListTablePane object to display all records less than or equal to a key
v Example: Using RecordListFormPane
SpooledFileViewer
v Example: Creating a Spooled File Viewer to view a spooled file previously created on the system
SQL
v Example: Using SQLQueryBuilderPane
v Example: Using SQLResultSetTablePane
System values
v Example: Creating a system value GUI using the AS400Explorer pane
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// VUserList example. This program presents a list of users on
// a system in a list pane, and allows selection of one or more
// users.
//
// Command syntax:
// VUserListExample system
//
/////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
try
{
// Create an AS400 object. The system name is passed
// as the first command line argument.
AS400 system = new AS400 (args[0]);
if (selectedUsers.length == 0)
System.out.println ("No users were selected.");
else
{
System.out.println ("The selected users were:");
for (int i = 0; i < selectedUsers.length; ++i)
System.out.println (selectedUsers[i]);
}
}
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// VMessageList example. This program presents a detailed
// view of messages returned from a command call.
//
// Command syntax:
// VMessageListExample system
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
try
{
// Create an AS400 object. The system name was passed
// as the first command line argument.
AS400 system = new AS400 (args[0]);
// Create a frame.
JFrame f = new JFrame ("VMessageList example");
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// VIFSDirectory example. This program presents a tree view of
// some directories in the integrated file system.
//
// Command syntax:
// VIFSDirectoryExample system
//
// This source is an example of IBM Toolbox for Java "VIFSDirectory".
//
/////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
try
{
// Create an AS400 object. The system name was passed
// as the first command line argument.
AS400 system = new AS400 (args[0]);
// Create a frame.
JFrame f = new JFrame ("VIFSDirectory example");
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// VPrinters example. This program presents various network
// print resources with an explorer pane.
//
// Command syntax:
// VPrintersExample system
//
// This source is an example of IBM Toolbox for Java "VPrinters".
//
/////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
try
{
// Create an AS400 object. The system name was passed
// as the first command line argument.
AS400 system = new AS400 (args[0]);
// Create a frame.
JFrame f = new JFrame ("VPrinters example");
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// Command call menu item example. This program demonstrates how to
// use a menu item that calls a server command. It will display
// any messages that are returned in a dialog.
//
// Command syntax:
// CommandCallMenuItemExample system
//
/////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
try
{
// Create an AS400 object. The system name was passed
// as the first command line argument.
AS400 system = new AS400 (args[0]);
// Create a frame.
f = new JFrame ("Command call menu item example"
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// Data queue document example. This program demonstrates how to
// use a document that is associated with a server data queue.
//
// Command syntax:
// DataQueueDocumentExample system read|write
//
/////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
rw = args[1].equalsIgnoreCase ("read");
String mode = rw ? "Read" : "Write";
try
{
// Create two frames.
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////
//
// File Dialog example.
//
/////////////////////////////////////////////////////////
import java.io.*;
import java.awt.*;
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
// if a system name was not specified, display help text and exit.
if (parameters.length >= 1)
{
// The first parameter is the system that contains the files.
String system = parameters[0];
try
{
// Create an AS400 object for the server that contains the files.
// Connect to the file server on the server. Connect now so
// the sign-on screen is displayed now.
AS400 as400 = new AS400(system);
as400.connectService(AS400.FILE);
// Create the list of filters the user can choose then add the filters
// to the dialog.
FileFilter[] filterList = {
new FileFilter("All files (*.*)", "*.*"),
new FileFilter("Executables (*.exe)", "*.exe"),
new FileFilter("HTML files (*.html)", "*.html"),
new FileFilter("Images (*.gif)", "*.gif"),
new FileFilter("Text files (*.txt)", "*.txt")};
fileDialog.setFileFilter(filterList, 0);
// Display the dialog and wait until the user presses OK or Cancel
int pressed = fileDialog.showDialog();
// If the user pressed OK, get the fully qualified path and name
// of the file they chose.
if (pressed == IFSFileDialog.OK)
{
System.out.println("User selected: " +
fileDialog.getAbsolutePath());
}
else
System.out.println("User didn’t press Open or Cancel");
}
catch(Exception e)
{
// If any of the above operations failed say the dialog operation
// failed and output the exception.
else
{
System.out.println("");
System.out.println("");
System.out.println("");
System.out.println("Parameters are not correct. Command syntax is:");
System.out.println("");
System.out.println(" FileDialogExample system");
System.out.println("");
System.out.println("Where");
System.out.println("");
System.out.println(" system = IBM i");
System.out.println("");
System.out.println("For example:");
System.out.println("");
System.out.println("");
System.out.println(" FileDialogExample mySystem");
System.out.println("");
System.out.println("");
}
System.exit(0);
}
}
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// IFS text file document example. This program demonstrates how to
// use a document that is associated with a text file in the
// integrated file system.
//
// Command syntax:
// IFSTextFileDocumentExample system path
//
/////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
try
{
// Create two frames.
JFrame f = new JFrame ("IFS text file document example");
AS400 JDBCDataSourcePane
The AS400JDBCDataSourcePane class presents the property values of an AS400JDBCDataSource object.
Optionally, changes can be made to the AS400JDBCDataSource object.
The following example creates an AS400JDBCDataSourcePane and an OK button and adds them to a
frame. Changes made to the GUI are applied to the data source when you click OK.
// Create a data source.
myDataSource = new AS400JDBCDataSource();
// Create an OK button
JButton okButton = new JButton("OK");
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// Job list example. This program presents a list of jobs in an
// explorer pane.
//
// Command syntax:
// VJobListExample system
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
try
{
// Create an AS400 object. The system name was passed
// as the first command line argument.
AS400 system = new AS400 (args[0]);
// Create a frame.
JFrame f = new JFrame ("Job list example");
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// Message queue example. This program presents a message queue in an
// explorer pane.
//
// Command syntax:
// VMessageQueueExample system
//
// This source is an example of IBM Toolbox for Java "VMessageQueue".
//
/////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
try
{
// Create an AS400 object. The system name was passed
// as the first command line argument.
AS400 system = new AS400 (args[0]);
// Create a frame.
JFrame f = new JFrame ("Message queue example");
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// Program call button example. This program demonstrates how to
// use a button that calls a program on the server. It will exchange data
// with the server program via an input and output parameter.
//
// Command syntax:
// ProgramCallButtonExample system
//
// This source is an example of IBM Toolbox for Java "ProgramCallButton".
//
/////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
try
{
// Create a frame.
JFrame f = new JFrame ("Program call button example");
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// VPrinter example. This program presents a printer and its spooled
// files in an explorer pane.
//
// Command syntax:
// VPrinterExample system
//
//////////////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
// If the user does not supply a printer name then show printer information
// for a printer called OS2VPRT;
String printerName = "OS2VPRT";
try
{
// Create an AS400 object. The system name was passed
// as the first command line argument.
AS400 system = new AS400 (args[0]);
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
try
{
// Create an AS400 object. The system name was passed
// as the first command line argument.
AS400 system = new AS400 (args[0]);
// Create a frame.
JFrame f = new JFrame ("VPrinters example");
VPrinterOutput Example
This example program presents a list of spooled files on the server. All spooled files, or only spooled files
for a specific user, can be displayed.
Note: Read the Code example disclaimer for important legal information.
//////////////////////////////////////////////////////////////////////////////////
//
// VPrinterOutput example. This program presents a list of spooled
// files on the server. All spooled files, or spooled files for
// a specific user can be displayed.
//
// Command syntax:
// VPrinterOutputExample system <user>
//
// (User is optional, if not specified all spooled files on the system
// will be displayed. Caution - listing all spooled files on the system
// and take a long time)
//
//////////////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
try
{
// Create an AS400 object. The system name was passed
// as the first command line argument.
AS400 system = new AS400 (args[0]);
system.connectService(AS400.PRINT);
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// SQLQueryBuilderPane example. This program presents a query builder
// that allows the user to build a SQL query.
//
// Command syntax:
// SQLQueryBuilderPaneExample system
//
// This source is an example of IBM Toolbox for Java "SQLQueryBuilderPane",
// and "SQLResultSetFormPane".
//
/////////////////////////////////////////////////////////////////////////
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
try
{
// Register the IBM Toolbox for Java JDBC driver.
DriverManager.registerDriver (new AS400JDBCDriver ());
// Create a frame.
JFrame f = new JFrame ("SQLQueryBuilderPane example");
Note: Read the Code example disclaimer for important legal information.
/////////////////////////////////////////////////////////////////////////
//
// SQLResultSetTablePane example. This program presents the contents of
// a table in a table pane. There is a SQLStatementDocument that allows
// the user to type in any SQL statement. In addition, there is a button
// that allows the user to delete all rows of the table.
import com.ibm.as400.access.*;
import com.ibm.as400.vaccess.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
try
{
// Register the IBM Toolbox for Java JDBC driver.
DriverManager.registerDriver (new AS400JDBCDriver ());
// Create a frame.
JFrame f = new JFrame ("SQLResultSetTablePane example");
Examples: XPCML
This section lists the code examples that are provided throughout the documentation of the IBM Toolbox
for Java XPCML component.
v “Example: Condensing an existing XPCML document” on page 753
v “Example: Condensing an existing XPCML document, including Java code” on page 753
v “Example: Using condensed XPCML to create a ProgramCallDocument object” on page 756
v “Example: Obtaining program call results as condensed XPCML” on page 756
v “Example: Retrieving program call results as XPCML”
v “Example: Passing in parameter values as XPCML” on page 750
v “Examples: Passing in arrays of parameter values as XPCML” on page 751
v “Example: Converting a PCML document to an XPCML document” on page 441
The following disclaimer applies to all of the IBM Toolbox for Java examples:
IBM grants you a nonexclusive copyright license to use all programming code examples from which
you can generate similar function tailored to your own specific needs.
All sample code is provided by IBM for illustrative purposes only. These examples have not been
thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability,
serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The
implied warranties of non-infringement, merchantability and fitness for a particular purpose are
expressly disclaimed.
Notice how array data is specified in the original and the generated XPCML. The element
qgyolaus.receiver, an output parameter, is an XPCML arrayOfStructParm with an attribute that sets the
count to listInfo.rcdsReturned. The following example code includes only part of the QGYOLAUS output.
If the example included all the output, the code might list 89 users under the <arrayOfStructParm>
XPCML tag.
For arrays of simple types, such as arrayOfStringParm, arrayOfIntParm, and so on, the <i> XPCML tag
lists array elements.
<!-- XPCML source for calling "Open List of Authorized Users" -->
<!-- (QGYOLAUS) API -->
<!-- List information structure (common for "Open List" type APIs) -->
<struct name="listInfo">
<intParm name="totalRcds"/>
<intParm name="rcdsReturned">0</rcdsReturned>
<hexBinaryParm name="rqsHandle" totalBytes="4"/>
<intParm name="rcdLength"/>
<stringParm name="infoComplete" length="1"/>
<stringParm name="dateCreated" length="7"/>
<stringParm name="timeCreated" length="6"/>
<stringParm name="listStatus" length="1"/>
<hexBinaryParm totalBytes="1"/>
<unsignedIntParm name="lengthOfInfo"/>
<intParm name="firstRecord"/>
<hexBinaryParm totalBytes="40"/>
</struct>
<!-- Program QGYOLAUS and its parameter list for retrieving -->
<!-- AUTU0150 format -->
// Call QGYOLAUS
boolean rc = xpcmlDoc.callProgram("QGYOLAUS");
Results of the program call, generated as XPCML and stored in file XPCMLOut.xpcml
<?xml version="1.0" ?>
<xpcml version="4.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=’xpcml.xsd’ >
<!-- More records here depending on how many users output. -->
<!-- In this case 89 user records are listed here. -->
In the following examples, the XPCML calls two different programs, prog1 and prog2. Both programs use
the input parameter s1Ref. The first example sets different values for s1Ref for each program call. The
second example specifies the same value for s1Ref for each program call, which illustrates a useful way
to set constant data values for input parameters.
In the following example, after the XML parser reads in and parses the document, the value of element
prog1.s1Ref.s2Ref.s2p1[0] is prog1Val_1 and the value of element prog1.s1Ref.s2Ref.s2p1[1] is prog1Val_2.
<xpcml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="xpcml.xsd" version="4.0">
<struct name="s1">
<stringParm name="s1p1"/>
<structParm name="s2Ref" struct="s2"/>
</struct>
<struct name="s2">
<stringParm name="s2p1" length="10"/>
<arrayOfStringParm name="parm1" count="2"/>
</struct>
In the following example, after the XML parser reads in and parses the document, the value of element
prog1.s1Ref.s2Ref.s2p1[0] is constantVal_1 and the value of element prog1.s1Ref.s2Ref.s2p1[1] is
constantVal_2.
<xpcml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="xpcml.xsd" version="4.0">
<struct name="s2">
<stringParm name="s2p1" length="10">constantVal</stringParm>
<arrayOfStringParm name="parm1" count="2">
<i>constantVal_1</i>
<i>constantVal_2</i>
</arrayOfStringParm>
</struct>
When using XPCML to pass in array data, you must use the count attribute:
v Specify the count attribute on the array element
v Set the count attribute to the number of elements that the array contains at the time you parse the
document
<?xml version="1.0" encoding="UTF-8"?>
<xpcml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="xpcml.xsd" version="4.0">
<struct name="s2">
<stringParm name="s2p1"/>
</struct>
For example, the following XPCML specifies an array of 3 intParms and sets the first element to 12, the
second to 100, and the third to 4:
<?xml version="1.0" ?>
<xpcml version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=’xpcml.xsd’ >
<program name="prog1" path="/QSYS.lib/MYLIG.lib/PROG1.pgm">
<parameterList>
<arrayOfIntParm name="intArray" count="3">
<i>12</i>
<i>100</i>
<i>4</i>
</arrayOfIntParm>
</parameterList>
</program>
</xpcml>
Using the index attribute of the <i> and <struct_i> tags to set array values
You can use the index attribute of the <i> and <struct_i> tags to help you set array values. In the
following example, the XPCML sets the first element of the array to 4, the second to 100, and the third to
12.
<?xml version="1.0" ?>
<xpcml version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=’xpcml.xsd’ >
Generated schema
<!-- parm1’s XSD definition -->
<xs:schema xmlns:xs=’http://www.w3.org/2001/XMLSchema’>
<!-- Link back to XPCML.xsd -->
<xs:include schemaLocation=’xpcml.xsd’/>
<xs:element name="parm1_" substitutionGroup="stringParmGroup" >
<xs:complexType>
<xs:simpleContent>
<xs:restriction base="stringParmType">
<!-- Attributes defined for parm1 -->
<xs:attribute name="name" type="string50" fixed="parm1" />
<xs:attribute name="length" type="xs:string" fixed="10" />
<xs:attribute name="passMode" type="xs:string" fixed="value" />
<xs:attribute name="ccsid" type="xs:string" fixed="37" />
<xs:attribute name="minvrm" type="xs:string" fixed="V5R2M0" />
</xs:restriction>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</schema>
<struct name="qualifiedJobName">
<stringParm name="jobName" length="10">*</stringParm>
<stringParm name="userName" length="10"/>
<stringParm name="jobNumber" length="6"/>
<struct name="jobi0100">
<intParm name="numberOfBytesReturned"/>
<intParm name="numberOfBytesAvailable"/>
<structParm name="qualifiedJobName" struct="qualifiedJobName"/>
<hexBinaryParm name="internalJobIdentifier" totalBytes="16"/>
<stringParm name="jobStatus" length="10"/>
<stringParm name="jobType" length="1"/>
<stringParm name="jobSubtype" length="1"/>
<stringParm length="2"/>
<intParm name="runPriority"/>
<intParm name="timeSlice"/>
<intParm name="defaultWait"/>
<stringParm name="purge" length="10"/>
</struct>
}
catch (Exception e) {
System.out.println("error: - "+e.getMessage());
e.printStackTrace();
}
<struct name="qualifiedJobName">
<jobName_>*</jobName_>
<userName_/>
<jobNumber_/>
</struct>
<struct name="jobi0100">
<numberOfBytesReturned_/>
<numberOfBytesAvailable_/>
<structParm name="qualifiedJobName" struct="qualifiedJobName"/>
<internalJobIdentifier_/>
<jobStatus_/>
<jobType_/>
<jobSubtype_/>
<stringParm length="2"/>
<runPriority_/>
<timeSlice_/>
<defaultWait_/>
<!-- More type definitions for each newly defined type follow here -->
</xs:schema>
The previously mentioned constructors require that you provide the following parameters:
v A String that specifies a condensed XPCML file
v An InputStream that contains the type definitions created by running condenseXPCML()
Using these constructors loads and parses a condensed XPCML file. Additionally, the process logs any
parse errors. After completing the parse, the constructor creates a ProgramCallDocument object.
The following Java code example uses condensed XPCML to create a ProgramCallDocument object. The
example code assumes the following
v The name of the condensed XPCML file is myCondensedXPCML.xpcml
v The name of the extended schema is myXSD.xsd
The code then uses the ProgramCallDocument object to run program qusrjobi_jobi0100.
AS400 system = new AS400();
// Create a ProgramCallDocument and parse the file.
ProgramCallDocument xpcmlDoc =
new ProgramCallDocument(system,
"myCondensedXPCML.xpcml",
new FileInputStream("myXSD.xsd"));
boolean rc = xpcmlDoc.callProgram("qusrjobi_jobi0100");
Note: The XPCML code that you use to call the program (after creating the ProgramCallDocument object)
is the same as the code you would use with PCML.
Use setXsdName() to specify the name of the extended schema, which generateXPCML() uses to generate
the noNamespaceSchemaLocation attribute of the <xpcml> tag in the condensed XPCML.
Using setXsdName() is important when you want to use the program call results (in condensed XPCML)
as source for another ProgramCallDocument object. You must specify the name of the extended schema
so that the parser knows which schema file to use when parsing.
For example, the following code obtains the results from a program call and generates condensed
XPCML.
AS400 system = new AS400();
boolean rc = xpcmlDoc.callProgram("qusrjobi_jobi0100");
The following code shows an example of obtaining program call results as condensed XPCML:
<xpcml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="myXSD.xsd" version="4.0">
Use the following sites to learn more about the IBM Toolbox for Java:
v IBM Toolbox for Java and JTOpen : Offers information about service packs, performance tips,
examples, and much more. You can also download a zipped package of this information, including the
Javadocs.
v IBM Toolbox for Java Frequently Asked Questions (FAQ) : Provides answers to questions about
performance, troubleshooting, JDBC, and more.
Use the following sites to learn more about ToolboxME and the Java implementation of wireless
technologies:
v IBM Toolbox for Java and JTOpen : Offers more information about ToolboxME.
v IBM alphaWorks® Wireless : Offers information about new wireless technologies, including
downloads and links to development resources.
v Sun Java 2 Platform, Micro Edition : Provides additional information about the Java wireless
technologies, including the following:
– K Virtual Machine (KVM)
– Connected Limited Device Configuration (CLDC)
– Mobile Information Device Profile (MIDP)
v Java Technology for Wireless, Mobile, and Embedded Devices : Offers a wide range of technical
information for Java wireless application developers.
v Wireless application development tools:
Java
Java is a programming language that allows you to develop portable object-oriented applications and
applets. Use the following sites to learn more about Java:
v IBM developerWorks® Java technology zone : Offers information, education, and tool to help you
use Java, IBM products, and other technologies to create business solutions.
v IBM alphaWorks Java : Offers information about new Java technologies, including downloads and
links to development resources.
v The Source for Java Developers : Offers information about the various uses for Java, including new
technologies.
v System i LDAP : Provides information about LDAP (Lightweight Directory Access Protocol) on
IBM i.
Servlets are small Java programs that run on a server and mediate requests from one or many clients
(each of which runs in a browser) to one or more databases. Because servlets are programmed in Java,
they can execute requests as multiple threads within a single process, thereby saving system resources.
Use the following sites to learn more about servlets:
v Java Servlet technology : Provides technical information, instructions, and tools to help you
understand and use servlets.
XHTML
XHTML is touted as the successor to HTML 4.0. It is based on HTML 4.0, but incorporates the
extensibility of XML. Use following sites to learn more about XHTML:
v The Web Developer's Virtual Library : Offers an introduction to XHTML, including examples and
links to additional information.
XML
Extensible Markup Language (XML) is a metalanguage that allows you to describe and organize
information in ways that are easily understandable by both humans and computers. A metalanguage
allows you to define a document markup language and its structure. Use the following sites to learn
more about XML:
v IBM developerWorks XML zone : Provides a site dedicated to the work IBM does with XML and
how it works to facilitate e-commerce
v IBM alphaWorks XML : Offers information about emerging XML standards and tools, including
downloads and links to development resources.
v XML.org : Provides news and information about the XML community, including industry news,
calendars of events, and more.
v XML Cover Pages : Provides a comprehensive online reference work for XML, SGML, and related
XML standards, like XSL and XSLT.
Other references
v IBM HTTP Server for i : Provides information, resources, and tips about the IBM HTTP Server for
i.
v IBM i Access : Offers information about IBM i Access, including downloads, FAQs, and links to
additional sites.
v IBM WebSphere Host On-Demand : Provides information about the browser-based emulator that
offers support for S/390®, IBM i, and DEC/Unix emulation.
v IBM Support and downloads : Offers a portal to IBM hardware and software support.
Personal Use: You may reproduce these publications for your personal, noncommercial use provided that
all proprietary notices are preserved. You may not distribute, display or make derivative works of these
publications, or any portion thereof, without the express consent of IBM.
Commercial Use: You may reproduce, distribute and display these publications solely within your
enterprise provided that all proprietary notices are preserved. You may not make derivative works of
these publications, or reproduce, distribute or display these publications or any portion thereof outside
your enterprise, without the express consent of IBM.
Except as expressly granted in this permission, no other permissions, licenses or rights are granted, either
express or implied, to the publications or any information, data, software or other intellectual property
contained therein.
IBM reserves the right to withdraw the permissions granted herein whenever, in its discretion, the use of
the publications is detrimental to its interest or, as determined by IBM, the above instructions are not
being properly followed.
You may not download, export or re-export this information except in full compliance with all applicable
laws and regulations, including all United States export laws and regulations.
IBM may not offer the products, services, or features discussed in this document in other countries.
Consult your local IBM representative for information on the products and services currently available in
your area. Any reference to an IBM product, program, or service is not intended to state or imply that
only that IBM product, program, or service may be used. Any functionally equivalent product, program,
or service that does not infringe any IBM intellectual property right may be used instead. However, it is
the user's responsibility to evaluate and verify the operation of any non-IBM product, program, or
service.
IBM may have patents or pending patent applications covering subject matter described in this
document. The furnishing of this document does not grant you any license to these patents. You can send
license inquiries, in writing, to:
IBM Director of Licensing
IBM Corporation
North Castle Drive
Armonk, NY 10504-1785
U.S.A.
For license inquiries regarding double-byte (DBCS) information, contact the IBM Intellectual Property
Department in your country or send inquiries, in writing, to:
Intellectual Property Licensing
Legal and Intellectual Property Law
IBM Japan, Ltd.
3-2-12, Roppongi, Minato-ku, Tokyo 106-8711
The following paragraph does not apply to the United Kingdom or any other country where such
provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION
PROVIDES THIS PUBLICATION “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some
states do not allow disclaimer of express or implied warranties in certain transactions, therefore, this
statement may not apply to you.
This information could include technical inaccuracies or typographical errors. Changes are periodically
made to the information herein; these changes will be incorporated in new editions of the publication.
IBM may make improvements and/or changes in the product(s) and/or the program(s) described in this
publication at any time without notice.
Any references in this information to non-IBM Web sites are provided for convenience only and do not in
any manner serve as an endorsement of those Web sites. The materials at those Web sites are not part of
the materials for this IBM product and use of those Web sites is at your own risk.
IBM may use or distribute any of the information you supply in any way it believes appropriate without
incurring any obligation to you.
Licensees of this program who wish to have information about it for the purpose of enabling: (i) the
exchange of information between independently created programs and other programs (including this
one) and (ii) the mutual use of the information which has been exchanged, should contact:
IBM Corporation
Such information may be available, subject to appropriate terms and conditions, including in some cases,
payment of a fee.
The licensed program described in this document and all licensed material available for it are provided
by IBM under terms of the IBM Customer Agreement, IBM International Program License Agreement,
IBM License Agreement for Machine Code, or any equivalent agreement between us.
Any performance data contained herein was determined in a controlled environment. Therefore, the
results obtained in other operating environments may vary significantly. Some measurements may have
been made on development-level systems and there is no guarantee that these measurements will be the
same on generally available systems. Furthermore, some measurements may have been estimated through
extrapolation. Actual results may vary. Users of this document should verify the applicable data for their
specific environment.
Information concerning non-IBM products was obtained from the suppliers of those products, their
published announcements or other publicly available sources. IBM has not tested those products and
cannot confirm the accuracy of performance, compatibility or any other claims related to non-IBM
products. Questions on the capabilities of non-IBM products should be addressed to the suppliers of
those products.
All statements regarding IBM's future direction or intent are subject to change or withdrawal without
notice, and represent goals and objectives only.
All IBM prices shown are IBM's suggested retail prices, are current and are subject to change without
notice. Dealer prices may vary.
This information contains examples of data and reports used in daily business operations. To illustrate
them as completely as possible, the examples include the names of individuals, companies, brands, and
products. All of these names are fictitious and any similarity to the names and addresses used by an
actual business enterprise is entirely coincidental.
COPYRIGHT LICENSE:
This information contains sample application programs in source language, which illustrate programming
techniques on various operating platforms. You may copy, modify, and distribute these sample programs
in any form without payment to IBM, for the purposes of developing, using, marketing or distributing
application programs conforming to the application programming interface for the operating platform for
which the sample programs are written. These examples have not been thoroughly tested under all
conditions. IBM, therefore, cannot guarantee or imply reliability, serviceability, or function of these
programs. The sample programs are provided "AS IS", without warranty of any kind. IBM shall not be
liable for any damages arising out of your use of the sample programs.
Each copy or any portion of these sample programs or any derivative work, must include a copyright
notice as follows:
© (your company name) (year). Portions of this code are derived from IBM Corp. Sample Programs. ©
Copyright IBM Corp. _enter the year or years_.
If you are viewing this information softcopy, the photographs and color illustrations may not appear.
Trademarks
IBM, the IBM logo, and ibm.com are trademarks or registered trademarks of International Business
Machines Corp., registered in many jurisdictions worldwide. Other product and service names might be
trademarks of IBM or other companies. A current list of IBM trademarks is available on the Web at
Copyright and trademark information at www.ibm.com/legal/copytrade.shtml.
Adobe, the Adobe logo, PostScript, and the PostScript logo are either registered trademarks or trademarks
of Adobe Systems Incorporated in the United States, and/or other countries.
Linux is a registered trademark of Linus Torvalds in the United States, other countries, or both.
Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the
United States, other countries, or both.
UNIX is a registered trademark of The Open Group in the United States and other countries.
Java and all Java-based trademarks and logos are trademarks of Sun Microsystems, Inc. in the United
States, other countries, or both.
Other company, product, or service names may be trademarks or service marks of others.
Personal Use: You may reproduce these publications for your personal, noncommercial use provided that
all proprietary notices are preserved. You may not distribute, display or make derivative works of these
publications, or any portion thereof, without the express consent of IBM.
Commercial Use: You may reproduce, distribute and display these publications solely within your
enterprise provided that all proprietary notices are preserved. You may not make derivative works of
these publications, or reproduce, distribute or display these publications or any portion thereof outside
your enterprise, without the express consent of IBM.
Except as expressly granted in this permission, no other permissions, licenses or rights are granted, either
express or implied, to the publications or any information, data, software or other intellectual property
contained therein.
IBM reserves the right to withdraw the permissions granted herein whenever, in its discretion, the use of
the publications is detrimental to its interest or, as determined by IBM, the above instructions are not
being properly followed.
You may not download, export or re-export this information except in full compliance with all applicable
laws and regulations, including all United States export laws and regulations.
Printed in USA