IBM Lotus Forms
Server – API

Using the API, you can develop applications that process XFDL forms, including
XForms data models within XFDL forms. You can create and manage applications
that analyze, route, validate, and create electronic forms.

The API also contains the Function Call Interface (FCI) library. Using
the FCI, you can extend the capabilities of your forms by adding custom
XFDL functions that are available to forms designers for use at run
time.

What's new in IBM Lotus Forms
Server – API4.0

This version of Lotus FormsAPI has several updates, including performance improvements, additional
platform support, and support of new features in XFDL 8.0.

Support for additional platforms

Support for WebSphere® Application Server 7.0 and zLinux has been added. The support for i5/OS®, AIX®, and Linux® platforms has also been updated. See API system requirements for the complete list of currently supported platforms.

Installing Lotus Forms
API

These procedures contain instructions for installing the
API as a single component that is independent of other Lotus Forms Server
products.

Installing Lotus Forms API
on Windows

You can install the API using the installer in graphical
mode or in console mode.

You must be logged in as a user belonging to the Administrators group when running the installer.

This procedure assumes that you will be using the graphical
mode to install the API. To run the installer in console mode, at
Step 2 open a terminal window and change to the temporary directory.
If you are installing on a 32-bit computer, at the command line type LFServer_400_Win32.exe -i console. If you are installing on a 64-bit computer,
at the command line type LFServer_400_Win64.exe -i console. The console procedure is almost identical
except that you use the keyboard instead of the mouse to enter data
and to navigate through the screens.

To install the API in graphical
mode:

Extract the .zip file to a convenient location on your
server. It is best to create a new folder for the extracted files
and folders.

Double click the installer.

On 32-bit systems: LFServer_400_Win32.exe

On 64-bit systems: LFServer_400_WinX64.exe

The installer begins initializing, and a few
seconds later the installer window opens.

Select a language and click OK.

Click Next and read the license
agreement.

Click I accept the terms in the license agreement then click Next. The installer configures
the IBM Autonomic Deployment
Engine. If the Autonomic Deployment Engine is not on your system,
the installer installs it for you. When configuration is complete,
the Select Installation Directory panel opens.

Enter or select a location for the API then click Next. The Select Server Components panel opens.

Installing Lotus Forms API
on AIX, IBM i, Linux, and Solaris

You can install the API using the installer in graphical
mode or in console mode. To use the graphical installer, you must
have X-Windows.

You must be logged in as root user when running
the installer.

If you are installing on Solaris: Make sure that you have the libstdc++.so.6 library before
installing the API. To obtain and install libstdc++.so.6, download
the following file: ftp://ftp.sunfreeware.com/pub/freeware/sparc/10/libgcc-3.4.6-sol10-sparc-local.gz

If you are installing on AIX: Make sure that you have the latest version of the XL C runtime installed.
To check the version, at the command line type:

lslpp -La | grep -i xlC

On AIX 5.3, the version
must be 8.0 or greater. On AIX 6.1 the version must be 9.0 or greater.

If you are installing on IBM i: You must have a user profile that has *ALLOBJ and *SECADM special
authorities.

This procedure assumes that you will be using the graphical
mode to install the API. The console procedure is almost identical
except that you use the keyboard instead of the mouse to enter data
and to navigate through the screens.

Table 1 shows the command
that you issue in Step 2 to start the installer for your operating
system.

Table 1. Installer executable file names

Operating system

64-bit

32-bit

AIX

./LFServer_400_AIXPPC64.bin

./LFServer_400_AIXPPC32.bin

IBM i (i5/OS)

./LFServer_400_i5OS64.jar

./LFServer_400_i5OS.jar

Linux

./LFServer_400_LinuxX64.bin

./LFServer_400_Linux.bin

zLinux

./LFServer_400_LinuxS390x.bin

./LFServer_400_LinuxS390.bin

Solaris

./LFServer_400_SolarisSparc64.bin

./LFServer_400_SolarisSparc.bin

IBM i: The installer
is available in console mode only. In the Qshell environment, change
to the directory that contains LFServer_400_i5OS.jar and issue the following command:

Locate the zip file that applies to your operating system,
and extract all of the files and folders to a convenient temporary
directory on your system.

Open a terminal window and start the installer by running
the executable for your operating system. The installer
begins initializing, and a few seconds later the installer window
opens.

Select a language and click OK.

Click Next and read the license
agreement.

Click I accept the terms in the license agreement then click Next. The installer configures
the IBM Autonomic Deployment
Engine. If the Autonomic Deployment Engine is not on your system,
the installer installs it for you. When configuration is complete,
the Select Destination Folder panel opens.

Enter or select a location for the API then click Next.

Choose an installation type set then click Next.

Select API then click Next.

If you want the installer to deploy the API to an existing WebSphere Application Server
or WebSphere Process Server:

Select the check box then click Next.

Enter the location of the server then click Next. The WebSphere Application
Server Settings panel opens, and the installer populates
the profile, cell, node, and server information fields.

Select the profile that you want to use, and make sure
that the cell, node, and server information is correct.

Enter the User Name and Password information, then click Next. The installer verifies the WebSphere Application Server information.

In the System variables list, select
the Path variable, then click Edit. The Edit System Variable window opens.

At the end of the list In the Variable value field, type the location of the API DLLs. The default location of
the DLLs is:

C:\Program Files\IBM\Lotus Forms\Server\4.0\API\redist\Win32

Important: Make sure that you use a semicolon
as a separator between values.

Click OK on each of the open windows.

Updating the PureEdgeAPI.ini file

You must create the PureEdgeAPI.ini file if it does not exist. If the file already exists then you must
update it to add the location of the new API.

The contents of the PureEdgeAPI.ini file determine which applications use which version of the API. The API will not work without a PureEdgeAPI.ini file.

The file can exist in one or more of the following locations:

the calling application's folder

the current working folder

the C:\WINDOWS folder

When the API starts, it searches the folders in the order shown
and uses the first PureEdgeAPI.ini file that
it finds.

Note: If you chose to automatically deploy the API to WebSphere Application
Server during installation of the API, then the PureEdgeAPI.ini file already exists.
The installer creates the file and adds the location of the API for you. You should verify that the location is correct.

To update the PureEdgeAPI.ini file:

Go to the folder where you want the PureEdgeAPI.ini file to exist.

If no PureEdgeAPI.ini file exists, create
the file with a text editor and add the following lines:

Note: The file path shown is the default installation location.
If you did not install the API in the default location, then you must adjust the file path to match
the location of the API on your system.

Configuration settings in prefs.config

The API can use a configuration file called prefs.config to set several properties. Normally, you do not need this file because
the default settings are adequate for most purposes.

If the prefs.config file exists,
it is in one or more of the following locations:

When determining the configuration, the API first looks at the configuration file in the user specific folder,
then the file in the All Users folder. The API will read both configuration files, but any settings in the user
specific folder will override settings in the All Users folder.

The configuration file uses tag value pairs to set
the following properties:

Tag

Setting

The path to your Netscape certificate store.
If the path is not provided, the API will attempt to locate the certificate
store automatically.

The path to your Netscape security libraries.
To determine this path, search for nss3.dll.

javaPath

The path to your Java virtual machine. If you do not provide a path, the API
will attempt to locate the Java VM automatically. In most cases, automatic detection will succeed
under Windows.

Note: If the
calling program is running in an application server such as WebSphere Application
Server, or
in a portal server such as WebSphere Portal, the javaPath must point to the same JVM that the application
server uses.

checkCRLDistribution Points

An on or off value. If on, the API will check CRL distribution
points whenever verifying a digital certificate. This requires Internet
access, and will slow the verification process. If off, the API will only use locally stored CRLs to verify certificates.

javaVM

Sets the default Java Virtual Machine. Once set, the API will use that JVM if
it is available, otherwise it will locate the latest JVM installed
on the computer.

Set this to the string that the
JVM uses to register itself. For example, "Sun VM <version>". The version is guaranteed to include a major and minor number,
and may include further information, such as a maintenance number,
build number, and so on.

Since it can be difficult
to get an exact match, you can use the * wildcard in the version string.
For example, you might use the following string:

Sun VM 1.4*

This will match any version beginning
with 1.4, such as "1.4.2_03 JDK" or "1.4 JDK". When there
are multiple matches, the match that will be selected is indeterminate,
so it is best to be specific.

Additionally,
the API always chooses the JDK over the JRE. For example, if you search
for "Sun VM 1.4*", and you have "Sun VM 1.4.2_03 JDK" and "Sun VM 1.4.2_03 JRE" installed, the API will use the JDK.

Note that this setting is for Windows only.

jvmOptions.x

Allows you to pass configuration options to
the Java VM. Each option must
have its own numbered entry as shown:

jvmOptions.1 = <config setting 1>
jvmOptions.2 = <config setting 2>

By default, the API does not pass
any configuration options.

javaIgnoreUnrecognized

An on or off value. If on, the Java VM will ignore unrecognized options used in the javaOptions
setting. If off, the Java VM will report unrecognized options in
the javaOptions setting. Default is off.

domspooltodiskthreshold

The in-memory size of form enclosures, in
bytes. Enclosures that are greater than this threshold are removed
from memory and spooled to a temporary file in the system temp folder.

The default size is 32768 bytes. If you do not want enclosures
to be spooled to disk, set the size to 0 (zero).

Note that the
size is the space that the enclosure takes when in memory; its file
size might be different.

schemasFolder

Allows you to specify the path to the schemas
folder for any external schemas required by an application or its
forms. If no schemasFolder setting is specified, and an external schema
is referenced, the API will look for a schemas folder in the same
directory as the currently running application.

defaultDateFormat

Allows you to specify the format to assume
for ambiguous dates that are entered by users. Valid settings are: DayMonthYear, MonthDayYear, YearMonthDay

The default is MonthDayYear. For example, by default the date
01/02/09 will be interpreted as January 2, 2009.

To configure the API, open the prefs.config file in a text editor
and set the preferences accordingly. If you do not include a particular
setting, the default is used instead. For example, your prefs.config file might look like this:

checkCRLDistributionPoints = off

In this case, the API will automatically detect both the location of the Netscape Profile
and the location of the Java virtual machine. However, the API will not check CRL distribution points and will use the default
configuration options for the Java VM.

Registering the COM dynamic link library

If you plan to use the COM API, you must register the pe_com.dll file with Windows.

The Network Security Services libraries are
required for creating and verifying electronic signatures. The libraries
are installed with most Netscape and Mozilla products, including Firefox,
SeaMonkey, and Mozilla Application Suite. They can also be obtained
directly from mozilla.org. To find the location of this directory
on your computer, search for the file libnss3.so.

Many methods exist of setting these paths; the method that
you choose depends on the operating system, the interactive shell
that you use, the preferences of the system administrator, or any
other policies that might apply in your particular environment.

Updating the PureEdgeAPI.ini file on AIX, Linux, and Solaris

You must create the PureEdgeAPI.ini file if it does not exist. If the file already exists then you must
update it to add the location of the new API.

The contents of the PureEdgeAPI.ini file determine which applications use which version of the API. The API will not work without a PureEdgeAPI.ini file.

The file can exist in one or more of the following locations:

the calling application's directory

the current working directory

the /etc directory

When the API starts, it searches the folders in the order shown
and uses the first PureEdgeAPI.ini file that it finds.

Note: If
you chose to automatically deploy the API to WebSphere Application
Server during installation of the API, then the PureEdgeAPI.ini file already exists.
The installer creates the file and adds the location of the API for you. You should verify that the location is correct.

To update the PureEdgeAPI.ini file:

Go to the directory where you want the PureEdgeAPI.ini file to exist.

If no PureEdgeAPI.ini file exists, create
the file with a text editor and add one of the following lines, depending
on your operating system:

If a PureEdgeAPI.ini file already exists,
make sure that the correct <path to API> for your
operating system is in the [API] section.

Note: The file path shown is the default installation location.
If you did not install the API in the default location, then you must adjust the file path to match
the location of the API on your system.

Configuration settings in prefs.config on AIX, Linux, and Solaris

The API can use a configuration file called prefs.config to set several properties. If you are using the API in Java, then you must set the location of the Java virtual machine. The default
settings of the other properties are adequate for most purposes.

Important: If you chose to automatically deploy
the API to WebSphere Application
Server when you installed the API, then the prefs.config file already exists. The installer creates the file and adds the
location of the JVM for you, in the javaPath setting.
You should verify that the javaPath setting is correct.

The prefs.config file can be in one or more
of the following locations:

When determining the configuration, the API first
looks at the configuration file in the user-specific directory, then
the file in the /etc/PureEdge/API 8.0/prefs directory.
The API will read both configuration files, but any settings in the
user-specific directory will override settings in the/etc/PureEdge/API
8.0/prefs directory.

Note: When creating these directories,
remember that paths which include spaces must be enclosed in quotation
marks. Also, ensure that you create permissions to access these directories
using chmod a+r.

After you have installed
the API, create the prefs.config file if it does
not already exist. The file uses tag value pairs to set the following
properties:

Tag

Setting

overrideDefaultPathToNetscapeProfile

The path to your Netscape certificate store.
If the path is not provided, the API will attempt to locate the certificate
store automatically.

overrideDefaultPathToNetscapeSecurityLibraries

The path to your Netscape security libraries.
To determine this path, search for a directory that contains libnss3.so and libnspr4.so.

rsaSecurityEngineNames

A comma-separated list of security engines
that the API will query for RSA signature support. The default setting
in API version 3.5 and later is:

rsaSecurityEngineNames = Netscape,CryptoAPI

To query all signature engines that are supported by the API,
use the * wildcard. For example:

rsaSecurityEngineNames = *

If you use the * wildcard, it must be the only
entry. The * wildcard is the behavior of API versions
3.0.1 and earlier.

If you are using the API on i5/OS, then you must either include the Java security engine in the list,
or use the * wildcard. For example:

rsaSecurityEngineNames = Netscape,CryptoAPI,Java

If
you specify an engine that is not supported on your platform, the
API will ignore that entry.

javaPath

The path to your Java virtual machine.

If you are using
the API from a C program, the javaPath can point
to any JVM on your system.

If you are using the API from a Java program, the javaPath must point to the same JVM that the calling Java program uses.

If the calling program
is running in an application server such as WebSphere Application
Server, or
in a portal server such as WebSphere Portal, the javaPath must point to the same JVM that the application
server uses.

checkCRLDistribution Points

An on or off value. If on, the API will check CRL distribution
points whenever verifying a digital certificate. This requires Internet
access, and will slow the verification process. If off, the API will only use locally stored CRLs to verify certificates.

javaOptions

A space delimited list of configuration options
that will be passed to the Java VM when it is started by the API. By default, the API does not pass
any configuration options.

javaIgnoreUnrecognized

An on or off value. If on, the Java VM will ignore unrecognized
options used in the javaOptions setting. If off, the Java VM
will report unrecognized options in the javaOptions setting. Default is off.

domspooltodiskthreshold

The in-memory size of form enclosures, in
bytes. Enclosures that are greater than this threshold are removed
from memory and spooled to a temporary file in the system temp folder.

The default size is 32768 bytes. If you do not want enclosures
to be spooled to disk, set the size to 0 (zero).

Note that the
size is the space that the enclosure takes when in memory; its file
size might be different.

schemasFolder

Allows you to specify the path to the schemas
folder for any external schemas required by an application or its
forms. If no schemasFolder setting is specified, and an external schema
is referenced, the API will look for a schemas folder in the same
directory as the currently running application.

defaultDateFormat

Allows you to specify the format to assume
for ambiguous dates that are entered by users. Valid settings are: DayMonthYear, MonthDayYear, YearMonthDay

The default is MonthDayYear. For example, by default the date
01/02/09 will be interpreted as January 2, 2009.

To configure the API, open the prefs.config file in a text editor and set the preferences
accordingly. If you do not include a particular setting, the default
is used instead. For example, your prefs.config file might look like
this:

In this case, the API will automatically
detect the location of the Netscape Profile and will use the Java VM in the /usr/java/jre/lib/sparc/ directory. However, the API will not check CRL distribution points
and will not send any configuration options to the Java VM.

Configuring WebSphere Application Server to use Lotus Forms API

You can deploy the API to WebSphere Application
Server in one
of two ways: automatically during installation, or manually after
installation.

Important: Do not manually configure WebSphere Application
Server if you
chose to automatically deploy the API. You only need to manually configure WebSphere Application
Server under
one or more of these conditions:

you did not choose to automatically deploy the API during installation
of the API

you are deploying the API in a managed node environment

Notes:

If you are deploying the API in a managed node environment, you
must run the installer on each machine that hosts one or more managed
nodes, and then manually configure WebSphere Application
Server. Do
not automatically deploy the API during installation if you are using
managed nodes.

You
must use the 32-bit versions of WebSphere Application
Server and IBM WebSphere Portal when running
on 64-bit systems. If you are using WebSphere Portal on AIX or Solaris, you must install
the 32-bit version of WebSphere Application
Server before
installing WebSphere Portal. After you have installed WebSphere Application
Server, run
the WebSphere Portal install type that allows you to deploy to an existing WebSphere Application
Server.

If you are using AIX, Linux, or Solaris, you must also
set the javaPath parameter in the prefs.config file. The javaPath must point to the same JVM
that WebSphere Application
Server uses.

Make sure that you configure the API before deploying the API
to WebSphere Application
Server. Specifically, make sure that a PureEdgeAPI.ini file exists.

Several steps are required to manually deploy the API
to WebSphere Application
Server:

Add or update the location of the API library files. The resource name depends on the operating system.

Operating system

Resource name

Windows

Add a PATH resource and point it to
the API directories that contain .dll files. For example:

${LFS_API_DIR};${LFS_API_DIR}/PureEdge/80/system

AIX

Add a LIBPATH resource and point it
to the API directories that contain .so files. For example:

${LFS_API_DIR}:${LFS_API_DIR}/PureEdge/80/system

Solaris

Add a LD_LIBRARY_PATH resource and
point it to the API directories that contain .so files. For example:

${LFS_API_DIR}:${LFS_API_DIR}/PureEdge/80/system

Linux

Add a LD_LIBRARY_PATH resource and
point it to the API directories that contain .so files. For example:

${LFS_API_DIR}:${LFS_API_DIR}/PureEdge/80/system

IBM i

Add a LIBPATH resource and point it
to the API directories that contain .so files. For example:

${LFS_API_DIR}:${LFS_API_DIR}/PureEdge/80/system

Note: If the PATH, LIBPATH, or LD_LIBRARY_PATH resources have already
been defined, then append the API directories to the existing paths.
Remember to use the correct separator; Windows uses a semicolon, but AIX, Linux, and Solaris platforms use a colon.

Setting the server class loader

You must add the location of the API to the WebSphere class loader.

To set the server class loader:

In WebSphere Application
Server, open the Classloader panel for your
server.

Additional usage notes

The Viewer and API cannot read forms that have a UTF-8 byte-order
mark (BOM). Attempting to do so will produce the following error: Unable to load form: Invalid document structure.

To prevent
this problem: If you use a text editor to edit your forms, configure
your editor so it does not add a BOM to UTF-8 documents. (See your
text editor's documentation for details.)

To remove a BOM
from a form: Open the form in the Designer and save it.

If you are using a server application that notarizes signatures
(that is, you are using the Authenticated Clickwrap or HMAC signature
engine), when the user submits a signed form to the server, the CryptoAPI
digital certificate may display a prompt on the server. Because the
prompt is displayed on the server, where no person can respond to
it, the server (or a thread on the server) may appear to hang.

If you use Mozilla-based web browsers, you should set up your
server modules to specify that the web browser clear its cache before
it posts a form submission. Some versions of Mozilla-based browsers
cache posts. As a result, if a post of a form is interrupted for some
reason and you submit the form a second time, the browser sends the
cached (and incomplete) first post.

VBScript does not correctly support output parameters. Because
of this, you must set all output parameters to null.

In cases in
which you would normally use vbNull, you must instead use "1", which is the constant value of vbNull. If you do not use "1", the function you are calling will not work correctly.

When building a C application that uses the API on AIX, Linux, or Solaris, ensure that you link with the libpe_cc.so library.

Under Solaris, you must link with the -Blocal linker option (or
equivalent). This makes all of the symbols within the program local,
so that loaded shared libraries cannot resolve against those symbols.
If this linker flag is not given, and the application is using the Java support, one of the shared
libraries loaded by the Java VM resolves against symbols defined in libpe_cc.so and causes a
segmentation fault when that function is called.

Samples

Sample Applications for Windows

The API includes the following sample applications:

Calculate Age Sample

Form Sample (Classic C and Java APIs, plus Streaming Java API)

FCI Sample (Classic C and Java APIs only)

JSP Sample (Classic and Streaming Java APIs only)

These applications are provided to demonstrate the
use of many of the functions in the API, and are useful for testing
your API installation and development environment.

Note: To view the forms provided with these sample applications, you
must have a licensed or evaluation copy of IBM Lotus Forms Viewer installed on your computer.

The Calculate Age Sample Application

The Calculate Age sample application demonstrates the most
commonly used functions in the API.

This application reads a form called CalculateAge.xfd into
memory, and reads the values for the year, month, and day of birth from the
form. It then writes those values into a series of hidden fields that are
used by a compute to determine the person's age. Once the values are written,
the application writes the form as Output.xfd.

Running Calculate Age Under C

Compile the source code file calculateAge.c
to produce an executable called calculateAge.exe. Then follow these
steps to run the Calculate Age sample application:

Using the Viewer, open the form called calculateAge.xfd
located in the following folder:

<API Installation Folder>\samples\Win32\form\demo\calculate_age\

Change the name and birth date if you want,
then save and close the form.

Run calculateAge.exe.

This creates a form called output.xfd in the current
folder.

Open the output.xfd form, and check the
result in the Age field.

Running Calculate Age Under Classic and Streaming Java

Follow these steps to set up and run the
Calculate Age sample application under Java:

Using the Viewer, open the form called calculateAge.xfd
located in the folder:

<API Installation Folder>\samples\java\form\demo\calculate_age\

Change the name and birth date if you want,
then save and close the form.

Using your Java compiler, compile the file called calculateAge.java found
in the current folder.

This produces a new class file called calculateAge.class.

Run calculateAge.class.

This creates a form called output.xfd in the current
folder.

Open the output.xfd form, and check the
number in the Age field.

Running Calculate Age For COM

The Calculate Age sample for COM is written
in Visual Basic and the sample project files were generated using Microsoft® Visual Basic 6.0.
To run the sample, follow these steps:

Using the Viewer, open the form called CalculateAge.xfd
located in the folder:

<API Installation Folder>\samples\Win32\COM\demo\calculate_age\

Change the name and birth date if you want,
then save and close the form.

Load the Calculate Age project files in Microsoft Visual Studio and
compile them.

This produces a new executable called CalculateAge.exe.

Run CalculateAge.exe.

This creates a form called output.xfd in the current
folder.

Open the output.xfd form, and check the
number in the Age field.

The Form Sample Application

The Form library sample application demonstrates more of
the functions available in the API.

This application reads into memory an input form called
formSample.xfd. It then reads the current date and birth date values from
the form and sets a formula on the Age field that automatically computes
the user’s age. Next, the application determines the user’s gender based on
the radio buttons in the form. It then replaces these buttons with an image
representing the user’s gender. Finally, it duplicates the address field to
create a mailing address field. When complete, the application saves the changes
made to formSample.xfd in a new form called output.xfd.

Running the Form Sample Under C on AIX, Linux, and Solaris

These steps explain how to run the form sample application
in the Viewer.

Compile the source code file formSample.c
to produce an executable called formSample.exe. Then follow these
steps to set up and run the Form sample application:

Using the Viewer, open the form called FormSample.xfd
located in the folder:

<API Installation Folder>\samples\Win32\form\demo\sample_application\

Notice the radio buttons used to indicate
gender and the empty Age field. Close theViewer.

Run the sample application formSample.exe.

This produces a new form called output.xfd in the
current folder.

Use the Viewer to compare the two forms and note the changes produced by the application.

Running the Form Sample Under Java

To set up and run the Form sample under Java:

Using the Viewer, open the form called FormSample.xfd
found in the folder:

<API Installation Folder>\samples\java\form\demo\sample_application

Notice the radio buttons used to indicate
gender and the empty Age field. Close the Viewer.

Using your Java compiler, compile the file called formSample.java found
in the current folder.

This produces a new class file called formSample.class.

Run the sample application formSample.class.

This produces a new form called output.xfd in the
current folder.

Use the Viewer to compare the two forms.

The FCI Sample Applications

The API includes two different samples that demonstrate
the FCI, depending on whether you are working in C or Java.

Running the FCI Sample Under C

The FCI sample application for C uses the
FCI methods to create a function called multiply that
can be called from within any form. This function multiplies two values
and returns the result.

To run the sample:

Compile the source code file fciExtension.c
located in the folder:

<API Installation Folder>\samples\Win32\fci\demo\multiply\

Move fciExtension.ifx into the Forms System
global extensions folder:

<API Installation Folder>\PureEdge\80\system

Using the Viewer, open the form fciSample.xfd,
located in the folder:

<API Installation Folder>\samples\Win32\fci\demo\multiply

Fill out fciSample.xfd. The result appears
in the Result field.

Running the FCI Sample Under Java

The FCI sample application for Java uses the FCI methods to create a function
called convertDate. This function takes two arguments,
the date and the locale, and converts the date into the specified
country's language and format. The application displays the converted
date as a value for the Converted Date label. In
this sample, the JAR file containing the extension was embedded into
the form.

To run the FCI sample application:

Open the form called fciSampleWithJar.xfd
found in the folder:

<API Installation Folder>\samples\java\fci\demo\convert_date\

Enter a date in the Date field, then select a language and date conversion format.

Click on Click me to convert
the date.

The converted date appears on the form.

Note: For information on how to build JAR (Java archive) files, refer to the Lotus Forms Server API – Java API User's Manual. For information on embedding JAR files into XFDL forms, refer
to the online help for the Designer.

Sample Applications for AIX, Solaris, and Linux

The API includes the following sample applications:

Calculate Age Sample (C and Java APIs)

Form Sample (C and Java APIs
)

FCI Sample (C and Java APIs
)

JSP Sample ( Java API )

The applications are provided to demonstrate the use of many of
the functions in the API, and are useful for testing your API installation
and development environment.

Note: To view the forms provided with these sample applications, you
must have a licensed or evaluation copy of IBM Lotus Forms Viewer installed on a Windows computer.

The Calculate Age Sample Application for AIX, Linux, and Solaris

The Calculate Age sample application demonstrates
the most commonly used functions in the API.

This application reads a form called calculateAge.xfd into memory, and reads the values for the year, month, and day of
birth from the form. It then writes those values into a series of
hidden fields that are used by a compute to determine the person's
age. Once the values are written, the application writes the form
as output.xfd.

Running Calculate Age Under C on AIX, Linux, and Solaris

Perform the following steps to set up and run the Calculate
Age sample under C on AIX, Linux, and Solaris systems.

Switch to the directory:

<API Installation Folder>/samples/<UNIX OS>/form/demo/calculate_age/

To view XFDL forms you must use a computer
running Windows. Copy the
file calculateAge.xfd to a computer running Windows.

In Windows, use the Viewer to open calculateAge.xfd.

Change the name and birth date if you want,
then save and close the form.

If you changed the values in the form, copy
the saved form back to the original directory on your UNIX® computer.

Create the makefile by typing xmkmf at the command prompt and press Enter.

At the command prompt, type make and press Enter.

This will build the application file (calculateAge).

To run the sample application, type ./calculateAge and press Enter.

This will create a form called output.xfd.

Copy the file output.xfd to a computer running Windows.

In Windows, use the Viewer to open the output.xfd form and check the number
in the Age field.

Running Calculate Age Under Classic and Streaming Java on AIX, Linux, and Solaris

Perform the following steps to set up and run the Calculate
Age sample under Java on AIX, Linux, and Solaris systems.

Switch to the directory:

<API Installation Folder>/samples/java/form/demo/calculate_age/

To view XFDL forms you must use a computer
running Windows. Copy the
file calculateAge.xfd to a computer running Windows.

In Windows, use the Viewer to open calculateAge.xfd.

Change the name and birth date if you want,
then save and close the form.

If you changed the values in the form, copy
the saved form back to the original directory on your UNIX computer.

Using your Java compiler, compile the file called calculateAge.java found in the current folder.

This produces a new class file called calculateAge.class.

Run calculateAge.class.

This will create a form called output.xfd.

Copy the output.xfd form to a computer running Windows.

In Windows, use the Viewer to open the output.xfd form and check the number
in the Age field.

The Form Sample Application on AIX, Linux, and Solaris

The Form library sample application demonstrates more of
the functions available in the API.

This application reads into memory an input form
called formSample.xfd. It then reads the current
date and birth date values from the form and sets a formula on the Age field that automatically computes the user's age. Next,
the application determines the user's gender based on the radio buttons
in the form. It then replaces these buttons with an image representing
the user's gender. Finally, it duplicates the address field to create
a mailing address field. When complete, the application saves the
changes in a new form called output.xfd.

Running the form sample application under C on AIX, Linux, and Solaris

Run the form sample application in IBM Lotus Forms Viewer to view what you have created.

To set up and run the Form sample under
C:

Switch to the directory:

<API Installation Folder>/samples/<UNIX_OS>/demo/sample_application/

To view XFDL forms you must use a computer
running Windows. Copy the
file formSample.xfd to a computer running Windows.

In Windows, use the Viewer to open formSample.xfd.

Notice the radio buttons used to indicate
gender and the empty Age field. You can now close the
Viewer.

Create the makefile by typing xmkmf at the command prompt and press Enter.

At the command prompt, type make and press Enter.

This will build the application file (formSample).

To run the sample application, type ./formSample and press Enter.

This produces a new form called output.xfd in the current folder.

Copy the file output.xfd to a computer running Windows.

In Windows, use the Viewer to compare the two forms.

Running the Form Sample Under Java on AIX, Linux, and Solaris

Run the form sample application in IBM Lotus Forms Viewer to view what you have created.

To set up and run the Form sample under Java:

Switch to the directory:

<API Installation Folder>/samples/java/form/demo/sample_application/

To view XFDL forms, you must use a computer
running Windows. Copy the
file formSample.xfd to a computer running Windows.

In Windows, use the Viewer to open formSample.xfd.

Notice the radio buttons used to indicate
gender and the empty Age field. You can now close the Viewer.

Using your Java compiler, compile the file called formSample.java found in the current folder.

This produces a new file called formSample.class.

Run the sample application formSample.class.

This produces a new form called output.xfd in the current folder.

Copy output.xfd to
your Windows computer, then
compare the two forms in the Viewer to see the changes that were made by the sample application.

The FCI Sample Application

The API includes two different samples that demonstrate
the FCI, depending on whether you are working in C or Java.

Running the FCI Sample Under C on AIX, Linux, and Solaris

The FCI sample application for C uses the FCI methods to
create a function called multiply that can be called
from within XFDL forms. This function multiplies two values and returns
the result.

To set up and run the FCI sample under
C:

Switch to the directory:

<API Installation Folder>/samples/<UNIX OS>/fci/demo/multiply/

Create the makefile by typing xmkmf at the command prompt and press Enter.

At the command prompt, type make and press Enter. This will build the application
file and the extension file (fciExtension.ifx).

Move the file fciExtension.ifx to the /usr/lib/PureEdge/80/extensions/ directory.

To run the sample application, type ./sampleap and press Enter. The following line will appear:

Multiplying 24 by 13 gives 312.000000

This indicates that the application executed successfully
and multiplied the two numbers using the multiply function.

Running the FCI Sample Under Java on AIX, Linux, and Solaris

The FCI sample application for Java uses the FCI methods to create a function
called convertDate. The convertDate function takes two arguments, the date and the locale, and converts
the date into the language and format of the selected locale. The
application displays the converted date as a value for the Converted
Date label.

Follow the steps
below to set up and run the FCI sample application:

Switch to the folder:

<API Installation Folder>/samples/java/fci/demo/convert_date/

To view XFDL forms, you must use a computer
running Windows. Copy the
file fciSampleWithJar.xfd to
a computer running Windows.

In Windows, use the Viewer to open fciSampleWithJar.xfd.

Enter a date in the Date field, then select a language and date conversion format.

Click on Click me to convert
the date.

The converted date appears on the form.

Running the JSP Sample Application

The JSP sample application is only available for Java. The sample demonstrates how
to integrate XFDL code with JSP. This application consists of three
files: jspget.jsp, getlabel.txt, and jsppost.txt. To run the application,
you need to place the above files into a J2EE compliant web server's
JSP folder. For more information refer to Lotus Forms Server API – Java API User's Manual and to your web server's documentation.

JSP Sample Application

Java Server Pages (JSP) is
a platform independent technology designed to make it easier to add
dynamic content to web pages. A web application server compiles JSP
scripts into Java servlets that
are executed by the server's Java virtual machine. The resulting dynamic content is inserted into
the web document that is then displayed in the end user's web browser.
Because JSP technology integrates with both HTML and XML documents,
you can use JSP to extend the capabilities of XFDL forms.

This section assumes that you are familiar with both JSP and XFDL.
The information in this section is not intended to show you how to
write JSP scripts. Rather, its purpose is to explain how to integrate
XFDL with JSP. For information on JSP refer to http://java.sun.com/products/jsp/.
For more information on XFDL, refer to the XFDL Specification.

System Requirements

To process JSP pages that contain XFDL, you must have one of the
following servlet containers:

Combining JSP and XFDL

Creating a JSP page involves integrating
JSP elements with the source code of the original HTML or XML web
document. In the case of XFDL forms, this means adding appropriate
JSP elements to the form's XFDL code using a text editor. Once complete,
the resulting document is a JSP page and should have a .jsp extension.

Note: Once you add JSP code to an XFDL form, you will no longer be
able to open the file with Lotus Forms Designer.

While the specific content of each JSP page depends
on the logic of the application and the design of the form, certain
fixed elements must be present in every JSP page that contains XFDL.
The following elements must appear exactly as shown in every JSP that
includes XFDL:

Element

Description

<?xml version="1.0"?>

This line is the standard XML file identifier. It must appear
as the first line in the JSP page. There can be no blank lines or
spaces ahead of this text.

<% response.setContentType("application/x-xfdl"); %>

This line sets the mime type of the http response object. In
this case, it identifies the object as an XFDL document. As a result,
the user's browser will display the document using the Viewer. With
the exception of any optional comments or whitespace, this line should
appear immediately after the XML file identifier.

Once you have included these standard elements,
you can add the rest of your custom JSP code such as directives, declarations,
or scriptlets.

Note: The XFDL portion of the JSP page must not
be compressed but it is valid to use the XFDL <transmitformat>
option to specify either ascii or binary compression for the transmission
of the page.

Sample JSP Page

The following source code creates a simple JSP page
containing an XFDL form. In this example, the JSP scriptlet obtains
the current date and converts it into a string. The form contains
an XFDL label item that displays the string.

Sample JSP Application

The API includes a sample web application demonstrating
how to use JSP pages to extend the functionality of XFDL forms. This
simple application consists of three files, located in the folder <API Program Folder>\samples\java\jsp\demo. The following table describes the functions of each file:

File

Description

jspget.jsp

This JSP page is an example of a standard HTTP GET operation.
The first JSP scriptlet obtains the current date and calculates the
number of days until Christmas. The XFDL form specifies two labels
to display this information. The second scriptlet creates the URL
that the form's submit button uses to call jsppostt2.jsp. Within
the XFDL portion of the page, a JSP include directive
obtains a label item from getlabel.txt.

getlabel.txt

Although this file does not contain a complete form, it does
contain XFDL code defining a label item. jspget.jsp
accesses this code using an include directive.

jsppost.jsp

This page is an example of a standard HTTP POST operation.
The scriptlet uses the API's streaming method readForm to obtain the number of days until Christmas and the signature from
jspget.jsp. It then uses getSignatureVerificationStatus to validate the signature. Finally, the XFDL portion of the page
specifies two labels to display the results to the end user.

To run this sample in WebSphere Application Server, you must first package the above
files into a WAR file. You can then deploy the WAR file using the WebSphere Application Server
Administrator Console. For other application servers, you can package
the files as WARs or place the JSP files into your web server JSP
folder. Refer to the documentation of your application server for
more information.

To run the application, users either follow
a link or type the URL into the address field of the browser. For
example, if the application is running on WebSphere Application Server, the URL would
be: http://<server_name>:<port><example_dir>/jsp/jspget.jsp.

Tutorials

The tutorials demonstrate how to work with XFDL forms in
C, Java™, and Visual Basic. They also demonstrate the features of
the API that allow you to create, modify, and save XFDL forms, and
how to extend XFDL forms using the function call interface library.

Developing an application in Java

In this tutorial, you will create an application that shows
you how to read, modify, and write forms using the Form Library

By working through the tutorial, you will perform all
of the steps involved in creating a simple application that uses the
API methods, including:

Initializing the Form Library.

Reading a form into your application.

Setting and retrieving form data.

Removing a form from memory.

Destroying a form.

The sample application in this tutorial reads an input form called
CalculateAge.xfd into memory. It retrieves the user's birth day, month,
and year as well as the current date from the form. It then places
these values into hidden fields in the form. This triggers the form
to compute the user's age and display the result. When complete,
the application saves the changes made to calculateAge.xfd as a new
form called Output.xfd.

Note: The sample application described in this tutorial is included
with the API and can be found in the folder: <API Program Folder>\Samples\Java\Form\Demo\Calculate_Age\

Set up the rest of your application. This generally
includes defining any classes and methods for your application as
well as declaring and initializing any variables you may need. The
following code sets up the Calculate Age application:

Create the public class CalculateAge and
the main method for the class.

public class CalculateAge
{

Declare a FormNodeP object called theForm to
represent the form.

private static FormNodeP theForm;

Create the program's main method.

public static void main(String argv[])
{

Declare the program's variables.

int birthYear;
int birthMonth;
int birthDay;

The program's main method essentially
consists of a series of calls to other methods. The Form Library methods
are called from the definition of these methods.

Initializing the Form Library

All applications that use the API functions
must initialize the Form Library to ensure correct error and memory
handling behavior. The sample application does this in a separate
method calledinitialize.
In turn, initialize calls
the Form Library methodDTK.initialize and passes it
the name of the current program.

Retrieving A Value from a Form

Once you have set up and
initialized your application with the API and loaded a form into memory, your
application is ready to start working with the form. The following code uses getLiteralByRefEx to get a specific value from the
form:

Define the method getBirthDay and
a string variable called temp.

private static int getBirthDay( ) throws Exception
{
String temp;

Call getLiteralByRefEx to
retrieve the literal information contained in the form node PAGE1.BIRTHDAY.value

Define the following methods to
retrieve the user's birth month and year from the input form. These methods
will be exactly the same as getBirthDay except for the parameters passed
to getLiteralByRefEx.

Define the remaining methods to
set the user's birth month and year in the form's hidden fields. These methods
will be exactly the same as setBirthDay except for the parameters passed
to getLiteralByRefEx.

Writing a Form to Disk

Once
you have finished making the desired changes to the form, you should
save it to disk. If you want to retain the original form (calculateAge.xfd),
you should save the modified form under a new name. This program saves
the modified form as Output.xfd.

Define the method saveForm.
This method demonstrates the use of the FormNodeP method writeForm.

Distributing Applications That Use the Form Library

32-bit applications that use methods
from the Form Library will run on any computer that supports the Java Runtime Environment or the Microsoft Software Development
Kit For Java v3.1 or later.

If you distribute applications
that use the Form Library, you will also need to distribute a number
of API files. Refer to Developing and distributing applications for
information about distributing applications that use the Form Library.

Form Library summary

By working through this section you have successfully
built the Calculate Age application. In the process, you have learned
how to initialize, compile, and test form applications using the following
methods from the Form Library:

initialize

getXFDL

readForm

getLiteralByRefEx

setLiteralByRefEx

writeForm

destroy

The source code for the Calculate Age application
is included with this API and can be found in the following folder:

<API Program folder>\Samples\Java\Form\Demo\Calculate_Age\

For a longer example using the Form
Library of methods refer to the other sample application installed
with the API. The source files for this application are located in
the following folder:

<API Program folder>\Samples\Java\Form\Demo\Sample_Application\

To view the forms provided with the sample applications, you must have a copy of the
Viewer installed.

Developing an extension with the FCI Library

In this tutorial, you will create a simple extension to
an XFDL form.

A series of practical examples is provided
which you can work through to build a package of functions called sample_package, which contains one function
called convertDate. The convertDate function converts
a date to a language and format specific to another country. Try adding
other functions to the package for more practice using the FCI Library
of methods.

Although the FCI Library contains many methods,
you only need to use a few of them to create a simple package of functions.
These are:

lookupInterface

registerInterface

registerFunctionCall

evaluate

help

The remaining FCI methods allow you to customize
the behavior of your functions and extensions. For example, you can
attach additional information to a particular extension, or get a
list of currently registered extensions.

Creating the Extension class

When the Forms System is initialized,
the API checks for existing extensions and calls the initialization
method (extensionInit) for each extension. Your
first step in creating a function call is to create an Extension class
that generates a new FunctionCall object. Follow
the procedure below to create the Extension class
called FCIExtension:

Create a new Java source
file called FCIExtension.java.

Define the Java package.
For example:

com.yourcompany.samples;

Import the following files and any other
required files to any Java files
that call FCI methods. These lines must be placed before any class
or interface definitions:

Creating a FunctionCall class

The FunctionCall class
contains definitions for your custom functions. It also registers
the FunctionCall object and each of the custom
functions that it supports with the Forms System so that the functions
and packages that it contains will be recognized.

Define a unique identification number for
each custom function that you are going to create using the FCI.

In the following example,FciFunctionCall contains
a function called convertDate that converts any
date to the date format and language of a specific country. The convertDate function
in FciFunctionCall has an ID number of 1:

Retrieving the Function Call Manager

The
Function Call Manager is used to handle services specific to function calls,
such as handling requests for a particular function. The Function Call Manager
is represented by a FunctionCallManager object.

Declare the Function Call Manager before requesting
it from the IFX Manager.

In the following example, the FciFunctionCall constructor
declares the Function Call Manager with the type FunctionCallManager.

Use
the IFSSingleton method getFunctionCallManager in
the function call constructor to request a FunctionCallManager object
from the IFX Manager.

The getFunctionCallManager call
requests the Function Call Manager from the IFX Manager.

The return value of the getFunctionCallManager method
is a generic object, and must be typecast to the object type you have requested.
In this case, the object returned from getFunctionCallManager is
typecast to FunctionCallManager.

In the following example the FciFunctionCall constructor
requests the Function Call Manager (FCM Notice that before the
Function Call Manager is returned, it is explicitly cast to the type FunctionCallManager.

Use
the FunctionCallManager method registerFunctionCall in
the function call constructor to register each of your custom functions
and corresponding package(s) with the Function Call Manager.

The FCI allows you to assign a version number to
each function that you create. This allows you to provide upgrades
to single functions in extensions you have already distributed to
users. For more information see the next section.

When registering your package(s) of functions with
the Function Call Manager, be aware of the API package naming conventions.
For more information see the next section.

You must register each of your custom functions
separately. So, if you are registering three functions with the Function
Call Manager, you must call registerFunctionCall three
times.

In the following example, the FciFunctionCall constructor
uses the registerFunctionCall method to register
the convertDate function with the Function Call
Manager:

About Function Version Numbers

Along
with registering your package(s) of custom functions with the Function Call
Manager, the registerFunctionCall method is also used to specify a
version number for each function that you create. In the previous example,
the ConvertDate function is registered with the version number 0x01000300.

Assigning a version number to each function allows you to
provide upgrades to single functions in extensions you have already distributed
to users.

For example, if you distributed an extension containing
a package of 50 functions for your application and then wanted to change the
behavior of one of the functions, you could:

Write a new extension containing just the upgraded function.

Register the new function using registerFunctionCall,
with the same package name and function name as the original function but
with a higher version number.

Distribute the new extension to users.

When the API initializes all of the extensions it would
find two functions with the same package name and function name. It would
deregister the one with the lower version number thereby updating your application.

Package Naming Conventions

The main purpose of package names
is to distinguish the functions in a package from those in other packages
that could potentially have the same names. All packages you create must contain
an underscore in their names. For example, the convertDate function
belongs to a package called sample_package.

Choose a name that aptly describes the set of functions
you are creating and is distinct enough to be unique within its realm of usage.

The package name is an internal logical element of the
API.

Package names are case sensitive.

All package names you define must contain an underscore.

Note: A group of functions is provided with the Forms System software as the
package. The package is reserved for system functions that are defined in
the XFDL Specification. You may not add to the system package or call your
packages by the name system.

Providing help information for each of your functions

By
using the method help, you can provide help
information to form designers within a development environment (for
example, Lotus
Forms Designer). Use help to help form
designers choose and use the correct functions.

Provide in-depth help information for each
of the functions you create by implementing the FunctionCall method help.

The FunctionCall class must
implement the help method since it is defined
as part of the FunctionCall interface.

In the following example, help provides
help information for the convertDate function in
the class FciFunctionCall.

Building the extension

Once
you have generated the Java source
files for your Extension class, you must compile
the source code to create the extension.

Use a Java compiler
that is supported by this API to compile your Extension class
files. Refer to the IBM Lotus Forms
Server - API Installation and Setup Guide for more information
on compatible development environments.

Before building your extension you should have
a collection of .java files that represent your extension. After compiling
the .java files you will have a set of files with the same name as
the .java files but with the extension .class.

For example, after compiling the source code for
the Extension class FCIExtension.java and the FunctionCall class
FciFunctionCall.java your Java compiler
will create two corresponding files: FCIExtension.class and FciFunctionCall.class.
These two class files make up the extension called FCIExtension.

The details of compiling your source code are not
included in this manual. Consult your Java documentation
for specific information on how to use your Java compiler.

Packaging extensions as JAR Files

Once you have created your extensions you can package
the .class files into a single Java Archive
(JAR) file and distribute the file. This means that you can package
multiple extensions into one JAR file for distribution.

Before building the JAR file, you must create a manifest
that indicates which classes in the JAR file are extensions.

Using
your favorite text-editor, create a manifest file for the extensions
you wish to package in the JAR file.

The manifest file has the file extension .mf. For
example, the manifest file for FCIExtension is
called:

FCI.mf

The first line of the manifest must include the
manifest-version number. See the following example for the correct
syntax.

The manifest file is broken down into sections,
where each section represents a particular Extension class
and its attribute as an extension.

The class listed in each section of the manifest
file is the class that implements the Extension interface. In the
following example FCIExtension.class implements FCIExtension.

For example, the manifest file for FCIExtension will
have the following syntax and format (notice that there is a space
after every colon)

Optionally, you can replace the class names with
the root folder for your package. This will include all classes that
are defined in that package. For example, to create a JAR file called
FormIFX for FCIExtension, you would type the following:

Set this to the string that the JVM uses to register
itself. For example,"Sun VM <version>". The version is guaranteed
to include a major and minor number, and may include further information,
such as a maintenance number, build number, and so on.

Since it can be difficult to get an exact match,
you can use the * wildcard in the version string. For example, you
might use the following string:

Sun VM 1.4*

This will match any version beginning with 1.4,
such as “1.4.2_03 JDK” or “1.4 JDK”.

When there are multiple matches, the API will default
to the latest version. For example, if you search for version 1.4*,
and you have “Sun VM 1.4 JDK” and “Sun VM 1.4.2_03 JDK” installed,
the API will use version 1.4.2_03.

Additionally, the API always chooses the JDK over
the JRE. For example, if you search for version 1.4*, and you have
“Sun VM 1.4.2_03 JDK” and “Sun VM 1.4.2_03 JVM” installed, the API
will use the JDK.

Location of Installed extensions (Security Issues)

The location in which
an extension is installed determines how much access the extension
has to the user's system resources (for example, user's
system files). The following table summarizes the security features
that are set when an extension is installed in a particular location.

Location of Installed extension

Security Features

The extension is installed as a JAR or ZIP file in the Extensions
folder of the Lotus
Forms product that will use the extension.

The extension has full access to the user's system resources.

The extension is installed as a JAR or ZIP file in the Forms
System Global Extensions folder:

C:\<Windows
System>\PureEdge\extensions

The extension has full access to the user's system resources.

The extension is installed as a set of .class files in the
folder:

<Windows System>\PureEdge\java\source.

The extension has full access to the user's system resources.

The extension is packaged as a JAR (or Zip) file and enclosed
directly within a form.

The extension has access only to the form that encloses it.
The extension cannot access other parts of the user's system
or cause any damage.

Refer to the following section
regarding additional security restrictions for functions enclosed
in XFDL forms.

FCI Library summary

By working through this section you have successfully
built an extension for date conversion. In the process you have learned
how to set up, compile, test, and distribute extensions. You also
learned how to use the following FCI methods:

getFunctionCallManager

registerInterface

registerFunctionCall

evaluate

help

The Convert Date sample application is included
with this API. you will find it in the folder < Program
Folder>\samples\java\fci\demo\convert_date.

In order to view the forms provided with this sample
application, you must have a licensed or evaluation copy of Lotus Forms Viewer
installed.

Developing an application in C

In this tutorial, you will create an application that shows
you how to read, modify, and write forms using the Form Library

By working through the tutorial, you will perform all
of the steps involved in creating a simple application that uses the
API functions, including:

Initializing the Form Library.

Reading a form into your application.

Setting and retrieving form data.

Removing a form from memory.

Destroying a form.

The sample application in this tutorial reads an input form called
CalculateAge.xfd into memory. It retrieves the user's birth day, month,
and year as well as the current date from the form. It then places
these values into hidden fields in the form. This triggers the form
to compute the user's age and display the result. When complete,
the application saves the changes made to calculateAge.xfd as a new
form called Output.xfd.

Note: The sample application described in this tutorial is included
with the API and can be found in the folder: <API Program Folder>\Samples\Win32\Form\Demo\Calculate_Age\

Create your main function
and declare any variables needed for your application. The main function
in calculateAge.c will declare variables for the birth day, birth
month, and birth year. It will also be responsible for calling the
functions declared previously. Finally, main is
responsible for freeing any memory used by the application by making
a call to the function UFLDestroy.

Initializing the Form Library

All applications that use the API functions
must initialize the Form Library to ensure correct error and memory
handling behavior. The sample application does this in a separate
method calledinitialize.
In turn, initialize calls
the Form Library functionIFSInitialize and passes it
the name of the current program.

Define the initialize function
to call the function IFSInitialize.IFSInitialize initializes
the API environment.

#ifndef OLD_STYLE_PARAMS
r_short initialize(void *theInstance)
#else
r_short initialize(theInstance)
void *theInstance;
#endif
{
r_error error;
/* Call IFSInitialize. The parameters are:
1. SampleAp : the name of the application being run.
2. 1.0.0 : the version of the application being run.
3. 2.6.0 : the version of the API to use by default.
An error code will be returned if there is a problem. */
error =IFSInitialize("SampleAp", "1.0.0", "2.6.0");
if (error != OK)
{
reportError("IFSInitialize error %hd.\n", (r_short)error);
return(NOTOK);
}
return(OK);
}

Loading a Form

Before your program can begin
working with a form, you must load it into memory. CalculateAge does this
by defining a loadFormfunction to
handle these tasks.

Call UFLReadForm within
the implementation of your loadForm function to read in the form, calculateAge.xfd.

#ifndef OLD_STYLE_PARAMS
r_short loadForm(formNodeP *form)
#else
r_short loadForm(form)
formNodeP *form;
#endif
{
/* Call UFLReadForm. The parameters are:
1. calculateAge.xfd : indicates the file on the local drive to read the
form from.
2. 0 : because we do not need the #include lines to be resolved.
The UFLReadForm will return a pointer to the root node of the new form
structure once it is loaded into memory. */
if ((*form = UFLReadForm("calculateAge.xfd", 0)) == NULL)
{
reportError("Could not load form.\n", 0);
return(NOTOK);
}
return(OK);
}

Retrieving A Value from a Form

Once you have set up and
initialized your application with the API and loaded a form into memory, your
application is ready to start working with the form. The following code uses UFLGetLiteralByRefEx to get a specific value from the
form:

Retrieve the birth date indicated on
the form by implementing the getBirthDate function. getBirthDate will
make three calls to UFLGetLiteralByRefEx.

#ifndef OLD_STYLE_PARAMS
r_short getBirthDate(formNodeP form, int *birYear, *birMonth,
int *birDay)
#else
r_short getBirthDate(form, birYear, birMonth, birDay)
formNodeP form;
int *birYear;
int *birMonth;
int *birDay;
#endif
{
r_charP temp=NULL;
r_short error;
/* Call UFLGetLiteralByRefEx to get the literal information for the
'PAGE1.BIRTHYEAR.value' node. An error code will be returned if there
is a problem. */
error = UFLGetLiteralByRefEx(form, NULL, "PAGE1.BIRTHYEAR.value", 0,
NULL, NULL, &temp);
if (error != OK)
{
reportError("UFLGetLiteralByRefEx error %hd.\n", error);
return(NOTOK);
}
/* If a literal value was returned, convert it into an integer value.
Otherwise, indicate that no value was entered into the field, and exit
the program. */
if (temp != NULL)
*birYear = atoi((char *)temp);
else
{
reportError("The birth year was not entered.\n",0 );
return(NOTOK);
}
/* Call UFLGetLiteralByRefEx to get the literal information for the
'PAGE1.BIRTHMONTH.value' node. An error code will be returned if there
is a problem. */
error = UFLGetLiteralByRefEx (form, NULL, "PAGE1.BIRTHMONTH.value",
0, NULL, NULL, &temp);
if (error != OK)
{
reportError("UFLGetLiteralByRefEx error %hd.\n", error);
return(NOTOK);
}
/* If a literal value was returned, convert it into an integer value.
Otherwise, indicate that no value was entered into the field, and exit
the program. */
if (temp != NULL)
*birMonth = atoi((char *)temp);
else
{
reportError("The birth month was not entered.\n",0 );
return(NOTOK);
}
/* Call UFLGetLiteralByRefEx to get the literal information for the
'PAGE1.BIRTHDAY.value' node. An error code will be returned if there is
a problem. */
error = UFLGetLiteralByRefEx(form, NULL, "PAGE1.BIRTHDAY.value", 0,
NULL, NULL, &temp);
if (error != OK)
{
reportError("UFLGetLiteralByRefEx error %hd.\n", error);
return(NOTOK);
}
/* If a literal value was returned, convert it into an integer value.
Otherwise, indicate that no value was entered into the field, and exit
the program. */
if (temp != NULL)
*birDay = atoi((char *)temp);
else
{
reportError("The birth day was not entered.\n", 0);
return(NOTOK);
}
return(OK);
}

Writing a Form to Disk

Once
you have finished making the desired changes to the form, you should
save it to disk. If you want to retain the original form (calculateAge.xfd),
you should save the modified form under a new name. This program saves
the modified form as Output.xfd.

The following example implements
the function saveForm. This function calls the API function UFLWriteForm that
writes a form to disk.

#ifndef OLD_STYLE_PARAMS
r_short saveForm(formNodeP form)
#else
r_short saveForm(form)
formNodeP form;
#endif
{
r_short error;
/* Call UFLWriteForm. The parameters are:
1. form : a pointer to the root node of the form.
2. output.xfd : the filename you want to use (you could also use a path
here).
3. NULL : since we do not want to set a triggeritem.
4. 0 : since we do not want to allow the transmit options to work.
An error code is returned if there is a problem. */
error = UFLWriteForm (form, "output.xfd", NULL, 0);
if (error != OK)
{
reportError("UFLWriteForm error %hd.\n", error);
return(NOTOK);
}
return(OK);
}

Closing a Form

Next, you must free the memory used by the form. This is the last operation in the main function of the
program.

Free the memory by using UFLDestroy,
which destroys the root node of the form and all of its children:

/* Now that we are done with the form, we can free the memory by
calling UFLDestroy. The parameter, 'theForm', is a pointer to
the root node of the form. This causes the root node and all
of its children (the complete form) to be deleted from memory. */
UFLDestroy(theForm);
return(OK);
}

Distributing Applications That Use the Form Library

If you distribute applications
that use the Form Library, you will also need to distribute a number
of API files. Refer to Developing and distributing applications for
information about distributing applications that use the Form Library.

Form Library summary

By working through this section you have successfully
built the Calculate Age application. In the process, you have learned
how to initialize, compile, and test form applications using the following
methods from the Form Library:

IFSInitialize

UFLReadForm

UFLGetLiteralByRefEx

UFLSetLiteralByRefEx

UFLWriteForm

UFLDestroy

The source code for the Calculate Age application
is included with this API and can be found in the following folder:

<API Program folder>\Samples\Win32\Form\Demo\Calculate_Age\

For a longer example using the Form
Library of methods refer to the other sample application installed
with the API. The source files for this application are located in
the following folder:

<API Program folder>\Samples\Win32\Form\Demo\Sample_Application\

To view the forms provided with the sample
applications, you must have a copy of the
Viewer installed.

Developing an extension with the FCI Library

In this tutorial, you will create a simple extension that
adds a multiply function to an XFDL form.

A series of practical
examples is provided which you may work through to build an extension
called Sample Extension. The extension contains
a package of functions called sample_package, which
contains one function called multiply. The multiply function
multiplies the value of two fields together and stores the result
in a third field. Try adding other functions to the package for more
practice using the FCI Library.

Although the FCI Library contains many functions,
you only need to use a few of them to create a simple package of functions.
These are:

C_ExtensionInit

IFSObject_AllocateObject

FunctionCall_SetObjectProc

IFXRegisterInterface

FCMRegisterFunctionCall

FunctionCallEvaluate

FunctionCallHelp

The remaining FCI functions allow you to customize
the behavior of your functions and extensions. For example you can
attach additional information to a particular extension, or get a
list of currently registered extensions.

Creating the Extension Source File

When the
Forms System is initialized, the API checks for any existing extensions
and calls the initialization function (C_ExtensionInit). Your
first step in creating a custom function is to set up and initialize C_ExtensionInit.

Create a new FunctionCall structure inside C_ExtensionInit by
calling the function, IFSObject_AllocateObject. A generic IFSObject
will be created and a generic IFSObject pointer will be returned. Cast the
returned pointer to a FunctionCall pointer.

In the following example, C_ExtensionInit creates
a new FunctionCall structure by calling the IFSObject_AllocateObject function.
The pointer returned from the call to IFSObject_AllocateObject is cast
to a pointer to a FunctionCall structure.

Defining Services Provided by the FunctionCall Structure

The
FunctionCall structure you have created will provide two services
or functions.

The first service is the implementation
of your custom functions. A forward declaration for this service was
declared previously as the function FCISimpleFunctions. This function
tells the forms driver what to do when custom functions are called
from within forms.

The second service defines
the help available to form designers when working with your custom
functions in Lotus
Forms compliant products, such as the Designer. A forward declaration
for this service was declared previously as the function FCISimpleHelp.

Use the function called FunctionCall_SetObjectProc to
define the services offered by the FunctionCall structure.

This function is called once for each service being
defined, and is passed the following parameters:

TheFunctionCall structure.

The function that implements the service.

The type of service being defined

In the following example FunctionCall_SetObjectProc is
called twice. The first call defines the services offered by FCISimpleFunctions. And
the second call defines the services offered by FCISimpleHelp.

Registering a FunctionCall with the IFX Manager

Each
FunctionCall structure must be registered with the IFX Manager as an interface
that provides function call support.

C_ExtensionInit, registers the FunctionCall
structure with the IFX Manager using the function IFXRegisterInterface.

The last parameter in the call to IFXRegisterInterface is
a pointer to an object of type IFXCriteriaMatchingHandler. An object
of this type can be generated by calling the function FCMGetDefaultListener.

In the following example theFunctionCall is registered
with the IFX Manager theIFXManager.

Call
the Function Call Manager function FCMRegisterFunctionCall from C_ExtensionInit to
register each of your custom functions and corresponding package(s)
with the Forms System.

The FCI allows you to assign a version number to
each function that you create. This allows you to provide upgrades
to single functions in extensions you have already distributed to
users. For more information see About
Function Version Numbers, below.

When registering your package(s) of functions with
the Function Call Manager, be aware of the API package naming conventions.
For more information see Package
Naming Conventions, below.

You must register each of your custom functions
separately. So, if you are registering three functions with the Function
Call Manager, you must call FCMRegisterFunctionCall three
times.

In the following example C_ExtensionInit uses
the FCMRegisterFunctionCall function to register
the multiply function with the Function Call Manager:

Along with registering
your package(s) of custom functions with the Function Call Manager,
the FCMRegisterFunctionCall function is also used
to specify a version number for each function that you create. In
the previous example the multiply function is registered with the
version number 0x01000300.

Assigning a version
number to each function allows you to provide upgrades to single functions
in extensions you have already distributed to users.

For
example, if you distributed an extension containing a package of 50
functions for your application and then wanted to change the behavior
of one of the functions you could:

Write a new extension containing just the upgraded
function.

Register the new function using FCMRegisterFunctionCall,
with the same package name and function name as the original function
but with a higher version number.

Distribute the new extension to users.

When the API initialized all of the extensions
it would find two functions with the same package name and function
name. It would deregister the one with the lower version number thereby
updating your application.

Package Naming
Conventions

The main purpose of package
names is to distinguish the functions in a package from those in other
packages that could potentially have the same names. All packages
you create must contain an underscore in their names. For example
the beep function belongs to a package called my_funcs.

Choose a name that aptly describes the set of functions
you are creating and that is distinct enough to be unique within its
realm of usage.

Since the package name is an internal logical element
of the application, the 8-character naming restriction and case-insensitivity
of Windows files do not
exist.

Note: A group of functions is provided with the Forms System
software as the system package. The system package is reserved for
system functions that are defined in the XFDL Specification. You may
not add to the system package or call your packages by the name system.
Instead, ensure your package names contain an underscore.

Implementing your custom functions

Implement your custom functions
as part of the extension.

The
function defined previously as FCISimpleFunctions implements
the behavior of your custom functions.

FCISimpleFunctions can be passed several
commands by the Forms driver. When a function call in a form is to
be evaluated, FCISimpleFunctions will be passed the command FCICOMMAND_RUN as
a value for the parameter theCommand.

This function must ensure that proper error checking
is implemented. The function should check that the package and function
names have been properly defined, and that the package name supplied
by the Forms driver matches the package name specified in your extension.
If you plan to write a multi-thread function, you should also check
that the application using the function is thread safe (using MUGetThreadSafeFlag).

In the following example, the Multiply function
is implemented as part of FCISimpleFunctions in fciExtension.c:

Providing help information for each of your functions

By using the function
template FunctionCallHelp, you can provide help information to form designers
within a development environment (for example the Designer). Use FunctionCallHelp
to help form designers choose and use the correct functions.

Provide in depth help information for each of the
functions you create by implementing the function FCISimpleHelp.

FCISimpleHelp must be implemented since the service
was defined previously with the call to FunctionCall_SetObjectProc.

In the following example, FCISimpleHelp provides
help information for the multiply function.

Compiling Your Extension

Once you have generated the C source
file for your extension, you must compile the source code to create the extension.

Use a compiler for C that is supported by the API to compile
your extension.

Before building your extension you should have a .c source
file that represents your extension. After compiling the .c file you will
have a set of files with the same name as the .c files but with the extension
.ifx.

For example, after compiling the source code for the extension
fciExtension.c, your C compiler will create the corresponding extension: fciExtension.ifx.

The details of compiling your source code are not included
here. Consult your compiler documentation for information.

FCI Library summary

By working through this section you have successfully
built an extension. In the process you have learned how to initialize,
compile and test FCI applications and use the following functions
from the FCI Library:

IFSObject_AllocateObject

FunctionCall_SetObjectProc

IFXRegisterInterface

FCMRegisterFunctionCall

This FCI application has been included with this
API and can be found in the folder <API Program folder>\Samples\Win32\Fci\Demo\Multiply.

To view the forms provided with these sample applications,
you must have a licensed or evaluation copy of the Lotus Forms Viewer installed.

Note: Files that are compatible with the Visual C++ development environment
can be found in the <API Program folder>\Samples\Win32.

Developing an application in Visual Basic

In this tutorial, you will create an application that shows
you how to read, modify, and write forms using the Form Library

By working through the tutorial, you will perform all
of the steps involved in creating a simple application that uses the
API functions, including:

Initializing the Form Library.

Reading a form into your application.

Setting and retrieving form data.

Removing a form from memory.

Destroying a form.

The sample application in this tutorial reads an input form called
CalculateAge.xfd into memory. It retrieves the user's birth day, month,
and year as well as the current date from the form. It then places
these values into hidden fields in the form. This triggers the form
to compute the user's age and display the result. When complete,
the application saves the changes made to calculateAge.xfd as a new
form called Output.xfd.

Note: The sample application described in this tutorial is included
with the API and can be found in the folder: <API Program Folder>\Samples\COM\Form\Demo\Calculate_Age\

Setting Up Your Application

This example assumes that
you are developing a program in Microsoft Visual
Basic using Microsoft Studio.
To begin, you must first set up your development environment to use
the API type library.

Create a new Visual Basic project.

Any project using the API must include the following
type library:

IFS_COM_API.tlb

To add this
to your Visual Basic Project, open the References ;
dialog from the Project menu and select “InternetForms
API”.

Set up the rest of your application. This generally
includes setting up your main algorithm and declaring any variables
you will need. The following code sets up the Calculate Age application:

' Create the Main method for the program.
Sub Main()
' Declare a number of variables. TheForm represents the form, while the
' other variables are values we will read from the form.
Dim TheForm As IFormNodeP
Dim BirthYear As Integer
Dim BirthMonth As Integer
Dim BirthDay As Integer
' The program's Main consists of a number of calls to other functions.
Initialize
Set TheForm = LoadForm
BirthYear = GetBirthYear(TheForm)
BirthMonth = GetBirthMonth(TheForm)
BirthDay = GetBirthDay(TheForm)
SetBirthYear BirthYear, TheForm
SetBirthMonth BirthMonth, TheForm
SetBirthDay BirthDay, TheForm
SaveForm TheForm
' Free the memory in which the form was stored.
TheForm.Destroy
End Sub

Initializing the Form Library

All applications that use the API functions
must initialize the Form Library to ensure correct error and memory
handling behavior. The sample application does this in a separate
method calledInitialize.
In turn, Initialize calls
the Form Library functionIFSInitialize and passes it
the name of the current program.

Sub Initialize()
Dim DTK As DTK
' Get the DTK object. You need this call the IFSInitialize function.
Set DTK = CreateObject("PureEdge.DTK")
' Call DTK.IFSInitialize. DTK is a static class representing the Java
' API development toolkit. The parameters are:
' 1. CalculateAge: the name of the application being run.
' 2. 1.0.0 : the version of the application being run.
' 3. 2.6.0 : the version of the API being run.
' An exception will be thrown if there is a problem.
DTK.IFSInitialize "CalculateAge", "1.0.0", "2.6.0"
End Sub

Loading a Form

Before your program can begin
working with a form, you must load it into memory. CalculateAge does this
by defining a LoadFormfunction to
handle these tasks.

Call ReadForm within
the implementation of your loadForm function to read in the form, calculateAge.xfd.

Function LoadForm() As IFormNodeP
Dim XFDL As XFDL
' Get the XFDL object. You need this to call the ReadForm function.
Set XFDL = CreateObject("PureEdge.xfdl_XFDL")
' Call XFDL.ReadForm. The parameters are:
' 1. calculateAge.xfd : indicates the file on the local drive to read
' the form from.
' 2. 0 : no special behavior.
' readForm will return a reference to the root node of the
' new form structure once it is loaded into memory. An exception
' will be thrown if there is a problem.
Set LoadForm = XFDL.ReadForm("c:\calculateage.xfd", 0)
End Function

Retrieving A Value from a Form

Once you have set up and
initialized your application with the API and loaded a form into memory, your
application is ready to start working with the form. The following code uses GetLiteralByRefEx to get a specific value from the
form:

Retrieve the birth date from the
form as three separate values: the birth day, birth month, and birth year.
To do this, we will use three separate functions. Each function uses GetLiteralByRefEx to
retrieve one of the values.

Function GetBirthDay(TheForm) As Integer
Dim BDay As String
' Call IFormNodeP.GetLiteralByRefEx to get the literal information for
' the PAGE1.BIRTHDAY.value node. An exception will be thrown if
' there is a problem.
BDay = TheForm.GetLiteralByRefEx(vbNullString, _
"PAGE1.BIRTHDAY.value", 0, vbNullString, Nothing)
' If a literal value was returned, convert it into an integer value;
' otherwise, indicate that no value was entered into the field
' and throw an exception.
If (Len(BDay) > 0) Then
GetBirthDay = CInt(BDay)
Else
MsgBox "The birth day was not entered.", vbCritical
Stop
End If
End Function
' Similar to GetBirthDay
Function GetBirthMonth(TheForm) As Integer
Dim BMonth As String
BMonth = TheForm.GetLiteralByRefEx(vbNullString, _
"PAGE1.BIRTHMONTH.value", 0, vbNullString, Nothing)
If (Len(BMonth) > 0) Then
GetBirthMonth = CInt(BMonth)
Else
MsgBox "The birth month was not entered.", vbCritical
Stop
End If
End Function
' Similar to getBirthDay()
Function GetBirthYear(TheForm) As Integer
Dim BYear As String
BYear = TheForm.GetLiteralByRefEx(vbNullString, _
"PAGE1.BIRTHYEAR.value", 0, vbNullString, Nothing)
If (Len(BYear) > 0) Then
GetBirthYear = CInt(BYear)
Else
MsgBox "The birth year was not entered.", vbCritical
Stop
End If
End Function

Setting a Value in a Form

Once a form is loaded into memory, a developer
can set the values associated with any of the item or option nodes located
in the form by calling SetLiteralByRefEx.

Change the values of hidden fields
in the original form. These hidden fields are arguments for a compute in the
SHOWAGE label that calculates the user's age. To do this, we will use three
separate functions. Each function uses SetLiteralByRefEx to
set one of the values.

Sub SetBirthDay(BDay As Integer, TheForm As IFormNodeP)
Dim Day As String
' Convert the birthday to a String
Day = CStr(BDay)
' Call TheForm.SetLiteralByRefEx. The parameters are:
' 1. vbNullString : reserved. Must be vbNullString.
' 2. PAGE1.HIDDENDAY.value : the reference to the node.
' 3. 0 : must be zero.
' 4. vbNullString : sets the character set to ANSI.
' 5. Nothing : no namespace node required.
' 6. Day : the value to assign to the literal.
' An Exception will be thrown if there is a problem.
TheForm.SetLiteralByRefEx vbNullString, "PAGE1.HIDDENDAY.value", _
0, vbNullString, Nothing, Day
End Sub
' Similar to SetBirthDay()
Sub SetBirthMonth(BMonth As Integer, TheForm As IFormNodeP)
Dim Month As String
' Convert the birth month to a String
Month = CStr(BMonth)
' Set the birth month as a value in the form.
TheForm.SetLiteralByRefEx vbNullString, "PAGE1.HIDDENMONTH.value", _
0, vbNullString, Nothing, Month
End Sub
' Similar to setBirthDay()
Sub SetBirthYear(BYear As Integer, TheForm As IFormNodeP)
Dim Year As String
' Convert the birth year to a String
Year = CStr(BYear)
' Set the birth year as a value in the form.
TheForm.SetLiteralByRefEx vbNullString, "PAGE1.HIDDENYEAR.value", _
0, vbNullString, Nothing, Year
End Sub

Writing a Form to Disk

Once
you have finished making the desired changes to the form, you should
save it to disk. If you want to retain the original form (calculateAge.xfd),
you should save the modified form under a new name. This program saves
the modified form as Output.xfd.

The following example implements
the function SaveForm. This function calls the
API function WriteForm that writes a form to disk.

Sub SaveForm(TheForm)
' Call theForm.writeForm. theForm is the root node of the form to
' be written. The parameters are:
' 1. output.xfd : the filename you want to use (you could also use
' a path here).
' 2. Nothing : since we do not want to set a triggeritem.
' 3. 0 : since we do not want to allow the transmit options to work.
' An exception is thrown if there is a problem.
TheForm.WriteForm "output.xfd", Nothing, 0
End Sub

Closing a Form

Next, you must free the memory used by the form. This is the last operation in the main function of the
program.

The program's main method
calls the API's Destroy method to delete
TheForm object.

' Now that we are done with the form, we can free the memory by
' calling Destroy. The object, 'TheForm', is a reference to
' the root node of the form. This causes the root node and all
' of its children (the complete form) to be deleted from memory.
TheForm.Destroy
End Sub

Distributing Applications That Use the Form Library

If you distribute applications
that use the Form Library, you will also need to distribute a number
of API files. Refer to Developing and distributing applications for
information about distributing applications that use the Form Library.

Form Library summary

By working through this section you have successfully
built the Calculate Age application. In the process, you have learned
how to initialize, compile, and test form applications using the following
methods from the Form Library:

IFSInitialize

ReadForm

GetLiteralByRefEx

SetLiteralByRefEx

WriteForm

Destroy

The source code for the Calculate Age application
is included with this API and can be found in the following folder:

<API Program folder>\Samples\COM\Form\Demo\Calculate_Age\

To view the forms provided with the sample application, you must have a copy of the
Viewer installed.

A unique number that differentiates one instance
of the function from another instance. See Notes for more information.

theCommand

short

The name of the command for this method to perform.
See Notes for more information. Other commands can be found within
the manual.

theForm

FormNodeP

The form that contains the function.

theComputeNode

FormNodeP

The node within the form that stores the function.
See Notes for more information.

theFunctionData

IFSUserDataHolder

Reserved. Although this expression is not used,
it must be present.

theFunctionInstanceData

IFSUserDataHolder

Reserved. Although this expression is not used,
it must be present.

theArgList

FormNodeP [ ]

The list of arguments. See Notes for more information.

theResult

FormNodeP

The FormNodeP object in which
you should store the result. Simply use setLiteralEx on this object
to store the result.

Returns

Nothing
if call is successful or throws a generic exception (UWIException)
if an error occurs.

Notes

theCommand — the value of theCommand represents the command that evaluate will perform.

The value of theCommand depends
on the value of the parameter called theFlags in the method called registerFunctionCall.

Usually theCommand will be
set to FCICOMMAND_RUN. This indicates that a function must be evaluated.

Other possible values for theCommand include:

FCICOMMAND_INSTANCEDEREGISTER — This constant indicates
that evaluate should execute some procedure
when an instance of the function has been deregistered.

FCICOMMAND_DEREGISTER — This constant indicates that evaluate should execute some procedure when the function has been deregistered.

FCICOMMAND_REGISTER — This constant indicates that evaluate should execute some procedure when the function is registered.

FCICOMMAND_INSTANCEREGISTER — This constant indicates
that evaluate should execute some procedure
when an instance of the function is registered.

theFunctionInstance — is a
unique number that differentiates one instance of the function with
another instance. For example, if a form contains two calls to the
function testPackage.multiply then two unique values for theFunctionInstance variable will exist.

theComputeNode — is the node
within the form that contains the function. For example, if you have
an item such as:

Then theComputeNode will
point to the node that represents the value option.

theFunctionInstanceData - is data
specific to an instance of a function. It will always be returned
when the instance of the function is called. This object is only provided
when the FCI_WANTS_INSTANCE_DATA flag is provided during the registerFunctionCall
call.

theArgList — Each argument's
value is stored as a literal within a FormNodeP object. For example,
to get the value of the first argument, type the following:

theArgList[0].getLiteralEx(null)

Note: To get the number of arguments in theArgList use: theArgList.length

Example

public class FciFunctionCall extends com.PureEdge.xfdl.FunctionCallImplBase
implements FunctionCall
{
public static final int FUNCTION_ID = 1;
/* Additional Code Removed */
public void evaluate(String thePackageName,
String theFunctionName, int theFunctionID,
int theFunctionInstance, short theCommand,
com.PureEdge.xfdl.FormNodeP theForm,
com.PureEdge.xfdl.FormNodeP theComputeNode,
com.PureEdge.IFSUserDataHolder theFunctionData,
com.PureEdge.IFSUserDataHolder theFunctionInstanceData,
com.PureEdge.xfdl.FormNodeP [] theArgList,
com.PureEdge.xfdl.FormNodeP theResult) throws UWIException
{
/* The first switch in this method is based on theCommand. The only case
that we are interested in handling is FCICOMMAND_RUN that indicates
that we should evaluate a function. */
switch (theCommand)
{
case FunctionCall.FCICOMMAND_RUN:
/* The second switch is based on theFunctionID that you set for each
of your custom functions. This makes it easy for a single FunctionCall
object to support multiple functions. */
switch(theFunctionID)
{
case FciFunctionCall.FUNCTION_ID:
/* Insert the Details of your custom function here */
break;
}
break;
default:
break;
}
}
/* Additional code Removed */
}

help method

Description

Provides help information about each
of your custom functions in the form development environment (for
example, Lotus Forms Designer).

Returns

Nothing
if call is successful or throws a generic exception (UWIException)
if an error occurs.

Notes

theFCIInterface — Typically
a FunctionCall object will register its own function with the Function
Call Manager. Use the keyword this to represent the current object.

theFunctionID — Each function
that you create as part of a particular package must have a unique
identification number. Define each function's ID number as a constant
at the beginning of the class. For example, the multiply function
has an ID number of 1:

FunctionCall Class Constants

The following table lists the constants that
are used within the FunctionCall class along with a short description
of each constant:

Named Constants

Description

FunctionCall.FCI_FOLLOWS_ STRICT_CALLING_ PARAMETERS

Used in the method registerFunctionCall as a possible value
for the parameter theFlags.

Indicates that
the user of your custom function must provide the parameters you define in
the registerFunctionCall parameter theCallingParams.

FunctionCall.FCI_WANTS_ INSTANCE_DEREGISTER_ CALL

Used in the method registerFunctionCall as a possible value
for the parameter theFlags.

Indicates that the Forms
System should call evaluate with theCommand set to FCICOMMAND_
INSTANCEDEREGISTER when an instance of the function is deregistered.

FunctionCall.FCI_WANTS_ INSTANCE_REGISTER_CALL

Used in the method registerFunctionCall as a possible value
for the parameter theFlags.

Indicates that the Forms
System should call evaluate with theCommand set to FCICOMMAND_INSTANCEREGISTER when
an instance of the function is registered.

FunctionCall.FCI_WANTS_
REGISTER_CALL

Used in the method registerFunctionCall as a possible value
for the parameter theFlags.

Indicates that the Forms
System should call evaluate with theCommand set to FCICOMMAND_REGISTER when
the function is registered.

FunctionCall.FCIARGFLAG_
OPTIONAL

Used as a possible value for the flag theArgsFlagList in the
method help. This value represents an optional parameter.

FunctionCall.FCIARGFLAG_ OPTIONAL

Used as a possible value for the flag theRetValFlag in the method help.
This value represents a return value that is optional.

FunctionCall.FCIARGFLAG_
REPEATING

Used as a possible value for the flag theArgsFlagList in the
method help. This value represents a repeating parameter.

FunctionCall.FCIARGFLAG_
STRING

Used as a possible value for the flag theArgsFlagList in the
method help. This value represents a parameter of type String.

FunctionCall.FCIARGFLAG_ STRING

Used as a possible value for the flag theRetValFlag in the method help.
This value represents a return value of type String.

FunctionCall.FCICOMMAND_
DEREGISTER

Used in the method evaluate as a possible value for the parameter theCommand.

This constant indicates that evaluate should execute
some procedure when the function has been deregistered.

FunctionCall.FCICOMMAND_

INSTANCEDEREGISTER

Used in the method evaluate as a possible value for the parameter theCommand.

This constant indicates that evaluate should execute
some procedure when an instance of the function has been deregistered.

FunctionCall.FCICOMMAND_

INSTANCEREGISTER

Used in the method evaluate as a possible value for the parameter theCommand.

This constant indicates that evaluate should execute
some procedure when an instance of the function is registered.

FunctionCall.FCICOMMAND_
REGISTER

Used in the method evaluate as a possible value for the parameter theCommand.

This constant indicates that evaluate should execute
some procedure when the function is registered.

FunctionCall.FCICOMMAND_
RUN

Used in the method evaluate as a possible value for the parameter theCommand.

This constant indicates that evaluate should evaluate
a given function.

FunctionCall.FUNCTIONCALL_

CURRENT_VERSION

Current version of the Function Call Interface.

Used in the methods registerInterface as
a value for the parameter theInterfaceVersion.

FunctionCall.FUNCTIONCALL_

INTERFACE_NAME

Name of the Function Call Interface.

Used in the methods registerInterface as
a value for the parameter theInterfaceName

FunctionCall.FUNCTIONCALL_ MIN_VERSION_SUPPORTED

The
minimum version of the Function Call Interface that is supported.

Used
in the methods registerInterface as a value for the parameter theMinInterfaceVersion.

Developing and distributing applications

Overview of the XFDL Form Structure

This section provides an overview of an XFDL form as it
is represented in memory. You must understand the memory structure
of a form to effectively develop applications using the API.

The Node Structure

When a form is loaded into memory, it is constructed
as a series of linked nodes. Each node represents an element of the
form, and together these nodes create a tree that describes the form.
The following diagram illustrates the general composition of a single
node.

Each node within the tree has the following properties:

Type — For page and item nodes, this describes the type
of node, such as button, line, field, and so on. Page nodes are always of type page.

Literal — The literal value of the node
(for example, a literal string). If the node has a formula, the result
of the formula will be stored here.

Identifier — The page tag,
item tag, option name, or custom name assigned to the node.

Compute — The
compute assigned to the node (for example, "field_1.value + field_2.value").
The result of the compute will be stored in the literal of the node.

Depending on the node type, some of these properties
may be null.

The Node Hierarchy

Every node is part of an
overall hierarchy that describes the complete form. This hierarchy
follows a standard tree structure, with the top of the tree being
the top (or root) of the hierarchy.

Form — Each form has one
form level node. This is the root node of the tree.

Page —
Each form contains pages, which are represented as children of the
form node. Each form has at least two page nodes - one for the globalpage,
which stores the global settings, and one for the first page of the
form.

Item — Each page contains
items, which are represented as children of the page node. An item
node is created for each item, including the global item which stores
page settings.

Option — Each item contains
options, which are represented as children of the item node. An option
node is created for each option.

Argument — Options often
contain further settings, or arguments, which are represented as children
of the option node or as children of other argument nodes. There may
be more than one level of argument node created below an option node,
depending on the settings of the option. The easiest way to access
a particular node in the hierarchy is to use a reference. References
allow you to locate a specific node without first having to locate
the parent of that node.

A sample node hierarchy diagram is shown below:

Figure 1. Sample Node Hierarchy

About references

References
allow you to identify a specific page, item, option, or argument by
providing a "path" to that element. This means that you can access
an element directly without having to locate any of its ancestors.
The syntax of a reference follows this general pattern:

page.item.option[argument]

Each element of the reference is constructed as
follows:

Page and Item — Pages
and items are identified by their scope identifiers (sid). For example, Page1 or Field1.

Options — Options are identified by
their tag name. For example, value or itemlocation.

Arguments — Arguments are identified
by their tag name or a zero-based numeric index. Argument references
are always enclosed in brackets. For example, [1] or [message].

Arguments can also have any depth. For example,
you might have an argument that contains arguments. You can reference
additional levels of depth by adding another bracketed reference.
For example, to refer to the first argument in the first argument
of the printsettings option, you could use either [0][0] or
the tag names in brackets, such as [pages][filter].

You can create references to any level of the node
hierarchy. For example, the following table illustrates a number of
references starting at different levels of the form:

Start At

Ref to Page

Ref to Item

Ref to Option

Ref to Argument

Page

Page1

Page1.Field1

Page1.Field1.format

Page1.Field1.format[message]

Item

—

Field1

Field1.format

Field1.format[message]

Option

—

—

format

format[message]

Argument

—

—

—

[message]

Dereferencing

When
making a reference to an item node, there may be times when you do not know
which node to reference because it depends on some action from the user of
the form. Consider a situation in which a user selects a cell from a list.
Because you don't know beforehand which cell the user will choose, it is not
possible to explicitly reference the item node for the chosen cell. In such
cases you would use dereferencing to retrieve the node indirectly.

Essentially, dereferencing allows you to make a dynamic
reference that is evaluated at runtime. This is accomplished by placing the
-> symbol to the right of the dynamic reference.

For example, consider a list item called List1 that
has three cells called Cell1, Cell2, Cell3. If you want
to access the item node of the cell selected by the user, use the following
reference string:

List1.value->

At runtime, the portion of the expression that is to the
left of the dereference symbol is evaluated and replaced. If the user chooses
the second cell, List1.value is evaluated and replaced with:

Cell2

As a result, the item node for Cell2 is returned.

In some cases, instead of accessing the item node of the
chosen cell, you may want to access one of the cell's option nodes. Again,
dereferencing is used. The reference string would be:

List1.value->value

As before, the above expression is evaluated at runtime.
The expression to the left of the dereference symbol is evaluated
and replaced, just as before. So if the second cell is selected, List1.value is
evaluated as Cell2. This value is then concatenated with the expression
to the right of the dereference symbol. This produces:

Cell2.value

As a result, the option node for Cell2.value is returned.

Note: Do not include any spaces before or after the dereference symbol (->).

Namespace in References

References that include options
or arguments in any namespace other than XFDL normally require the inclusion
of the namespace prefix in the reference. For example, if you want to reference
"myOption" in the "custom" namespace, refer to that option as "custom:myOption"
as shown:

page_1.myItem.custom:myOption

If you are referencing named arguments, you should also
use the appropriate namespace. For example:

page_1.myItem.custom:myOption[custom:myArgument]

However, if you are referencing an argument by index number
you do not need to worry about namespace. All arguments, regardless of namespace,
are indexed in order. For example, if "myOption" contains two arguments, the
first in the XFDL namespace and the second in the custom namespace, use
the following reference for the second argument:

page_1.myItem.custom:myOption[1]

Note: Page and item references never require a namespace prefix because they
are uniquely identified by their sid.

The null Namespace

In some cases, forms
may have no default namespace or may have a default namespace that is explicitly
set to an empty string. In these cases, you can use null as the prefix
for the empty namespace. For example, the following field declares a default
namespace that is empty:

In this case, to reference the value of the field, you would
use the null prefix as shown:

Page1.null:myField.null:value

Advanced Information about the Node Structure

When
an XFDL form is stored in memory, it exists as a series of nodes that are
linked in a tree structure. As described in The Node Hierarchy,
the tree structure follows this hierarchy: form, page, item, option, and argument.

Within a single branch of the tree, all elements of the
same level are treated as siblings, each of which has a common parent, and
each of which may have its own children.

The following example illustrates the node structure of
a simple form, and gives a top-down description of the node structure.

A Sample Hierarchy

The following XFDL code creates the node hierarchy
shown in Figure 1. The result is a simple form that contains three items (a
line and two labels).

The Sample Tree Structure

Each tree begins
with the form, or root, node. This node contains no information -
it simply represents the starting point of the tree structure.

Below the form node are the page nodes. In the previous
example, there are two page nodes: "global" and "PAGE1". The "global"
page node stores any global settings that apply to the form, and "PAGE1"
stores the contents of the first form page. Additional pages are stored
as siblings of the "PAGE1" node.

Below each page node are the item nodes. As shown
in the previous example, the first item node of a page is always the
"global" item. The "global" item stores settings that apply to the
items on that page. Each additional item in the page is stored as
a sibling of the global item.

Below
each item node are the option nodes. Each option node represents an
option setting for that item, such as a background color or font setting.

Below
each option node are the argument nodes. These nodes contain the settings
for the parent option. For example, the background color might be
set to "blue". There can be an infinite number and depth of these
nodes, depending upon the number and depth of the settings for that
option.

For instance, in the sample form, the size node
for "REFLINE" has two argument nodes: one for the width and one for
the height. In contrast, the printsettings option
can have multiple argument nodes which themselves have argument nodes
as children. The following is an example of the node structure of
the printsettings option:

printsettings Node Structure

Thus, in storing
the printsettings option, two levels of argument
nodes are created. The first level describes the number of array elements
in the option (two). The second level gives the arguments for each
element.

Due to their potential complexity, pay
careful attention to the mapping of argument nodes.

Note: In cases
where an option has multiple elements in an array (for example, printsettings),
there will be a single option node, but a separate argument node for
each element in the array.

Node Properties

There
are several levels of nodes in an XFDL form: form (or root), page,
item, option, and argument (which can have an infinite number of levels).
Each node has four properties: literal, type, identifier, and compute.
A node does not necessarily contain information for every property.

For example, a page node can never have values for
the compute or literal properties. And while a value for the user
data property is optional, a page node must always have values for
the type and identifier properties.

The following table illustrates
what properties may be in use for each node level.

yes — node can have that property
always — node always has that property
no — node cannot have that property

Libraries

The API contains two libraries; the Form library and the FCI library.
You use the Form library for reading, parsing, modifying, and writing forms.
The FCI library allows you to create custom functions that extend the capabilities
of forms.

Introduction to the Form Library

You use the form library to develop applications that manipulate
XFDL forms. Your C and Java applications
use the form library to:

Read and write forms.

Retrieve information contained in a form's elements.

Assign information to the elements of a form.

Create new elements within a form.

Remove elements from a form.

Extract images or enclosures from a form.

Verify digital signatures.

With the Java Streaming API,
your applications can:

Read and write forms.

Retrieve information contained in a form's elements.

Assign information to the elements of a form.

Introduction to the FCI Library

The Function Call Interface (FCI) API provides a means for creating
extremely powerful form applications in a simple and elegant manner.

The FCI Library is a collection of methods for developing
custom-built functions that form developers may call from XFDL forms.
By creating custom functions, you can extend the capabilities of forms
without requiring an upgrade to either your forms software or the
form description language (XFDL). Using the methods from this library
you can:

Create packages of functions for forms.

Set up the packages as extensions for Lotus Forms products, such as Viewer or Designer.

Determine how and when the functions are used.
For example, you can specify that a function should run when a form
opens, when it closes and so on.

About Functions, Packages and Extensions

The purpose of the FCI is to make the functionality of
forms extensible without requiring updates to your forms driver software.
This API allows you to create self-contained modules called extensions that provide packages of functions for use in XFDL forms.

Note: The forms driver software is any application that initializes
and calls on the API.

Functions can be used almost anywhere in an XFDL
form; the appropriateness of their use depends mainly on their behavior.
For instance the XFDL Specification contains a default
package of functions called system. Every application
built with the API version 4.4 or greater can use these functions.

Functions are grouped together to form packages.
When you call a function from a form, you must include the function's
package name in the call. For example, the function beep is part of the package called my_funcs. To call
the beep function from a form and assign the result to the form option do_beep you would type the following:

The most common use of a function is to return a
value that is used to set a form option, such as the value of a field. For example, the toupper function
in the system package, which converts a string to upper
case and returns the result, might be used to set the value of a particular form field. This method could take as its sole argument
the value of a label elsewhere on the form (or on another form) and
convert it to upper case as follows:

FunctionCall: To create
a package of functions you must create an extension. The extension provides services for function calls via an object. The FunctionCall object
contains your package(s) of custom-built functions.

Package Naming Conventions

The main purpose of package names
is to distinguish the functions in a package from those in other packages
that could potentially have the same names. All packages you create must contain
an underscore in their names. For example, the convertDate function
belongs to a package called sample_package.

Choose a name that aptly describes the set of functions
you are creating and is distinct enough to be unique within its realm of usage.

The package name is an internal logical element of the
API.

Package names are case sensitive.

All package names you define must contain an underscore.

Note: A group of functions is provided with the Forms System software as the
package. The package is reserved for system functions that are defined in
the XFDL Specification. You may not add to the system package or call your
packages by the name system.

About the Function Call Interface (FCI)

The FCI is itself an extension. It is currently only
available for Windows 32-bit
applications. A set of Java wrapper
classes, supplied as a Java Archive
file (JAR file) or ZIP file, provide a Java interface to the DLL.

How the Form and FCI Libraries Work Together

The Form Library provides developers with tools for accessing
and manipulating XFDL forms as structured data types. For instance,
methods in the Form Library will provide your applications with a
means for reading and writing forms, retrieving information contained
in form elements or assigning information to the elements of a form.

The FCI Library of methods allows you to create
an extension structure that contains one or more packages of your
custom functions.

Once you have set up the framework for your custom
functions you can use Java system
methods, Form Library methods or even other FCI methods to implement
the details of each function.

The FCI Extension Architecture

The extensions folder of the Lotus Forms product that
will use the extension (for example, the Viewer or Designer products).

The API extensions folder, <Windows System>\PureEdge\extensions.

The Java source
folder, <Windows System>\PureEdge\java\source.

Enclosed within XFDL forms.

When the Forms System is initialized, the API checks
for extensions. If it finds any, it calls the initialization method
for each extension and passes each method an object called the IFX Manager.

As part of the initialization, those extensions
that provide a function call interface create one or more FunctionCall objects.

Then, each FunctionCall object
requests a FunctionCallManager object from
the IFX Manager.

Each FunctionCall object
registers itself with the IFX Manager as a function call and then
registers your custom-built functions and corresponding packages with
the Function Call Manager.

The final result is an extension containing a registered FunctionCall object. The registered FunctionCall object contains your package of custom functions.

When a function is called in a form, the forms driver
requests the package and function from the API. The API will use the
Function Call Manager to locate the FunctionCall object that contains the requested function and evaluate it.

Note: The forms driver software is any application that initializes
and calls the API.

Developing applications on Windows

Setting up the C environment to use the Form library

Although this procedure is specific to Microsoft Visual C++ 6.0, you can use it
as a guideline to set up alternate development environments.

To set up your development environment to use the Form
Library, follow this procedure:

Create a new 64-bit or 32-bit Windows project.

Add the API include file to your project. This folder is
located at:

<API Installation Folder>/include/

Include pe_cc.lib.

Set the Preprocessor Definitions in your project to WINDOWS.

If you are using Microsoft Visual Studio .NET, you must set the project to use
a multi-threaded DLL. (You can find this option under Project > Properties. Open the C/C++ > Code Generation folder, and set the Run-time drop-down list to Multi-threaded DLL.)

Setting up the C environment to use the FCI library

Although this procedure is specific to Microsoft Visual C++ 6.0, you can use it
as a guideline to set up alternate development environments.

To set up your development environment to use the FCI
Library, follow this procedure:

Create a new Win32 Dynamic-Link Library project.

Add the API include file to your project. This folder is
located at:

<API Installation Folder>/include/

Include pe_cc.lib in your project.

Set the Preprocessor Definitions in your project to WINDOWS.

If you are using Microsoft Visual Studio .NET, you must set the project to use
a Multithreaded dll. (You can find this option under Project > Properties. Open the C/C++ > Code Generation folder, and set the Run-time drop-down list
to Multi-threaded DLL.)

Set your project to output files with an .ifx extension.

Setting Up the Java Development
Environment (Classic only)

To use the Java API you must:

Configure your integrated development environment
to use the API.

Configure your computer to run applications that
use the API.

Note: You cannot configure your system to use both the Classic
and Streaming Java APIs. You
must choose only one.

To configure your integrated development environment to use
the Java API:

Note: To find the Netscape Security
Libraries directory, search for the libnss3.so file.

Distributing applications on Windows

If you plan to distribute applications that call the API, you must
ensure the following:

That your package includes the correct API files.

That the PureEdgeAPI.ini file is set up correctly on each computer.

That the prefs.config file is set up correctly on each computer.

That signature support is set up correctly on each computer.

That each computer has the correct environment variable settings.

Redistributing API Files

When you redistribute the API, you must
copy the complete contents of the following folder, including the
sub-folders, to the target's Windows System folder:

<API Installation Folder>\redist\Win32\

Setting up the PureEdgeAPI.ini file

The PureEdgeAPI.ini file determines which
applications use which version of the API. This ensures that older
applications do not attempt to use newer APIs, which may not be compatible.

The PureEdgeAPI.ini file must be placed in the Windows folder. If no PureEdgeAPI.ini
file exists on the target computer, you should install your own. If
a PureEdgeAPI.ini file already exists, you should update the file
to include an entry for your application. For more information about
setting up the PureEdgeAPI.ini file for your application, refer to
the IFSInitialize function if you are using C, or theinitialize method if you are
using Java.

Setting Up the prefs.config File

The prefs.config file controls the configuration
of the API. When you distribute an application that uses the API,
you must also distribute a configuration file for that application.
This file ensures that the API is configured properly to work with
your application.

You can install the configuration
file in any of the following locations:

These locations are listed in order
of precedence, from highest to lowest. When loading the configuration
information, the API first checks the lowest precedence location,
then works its way to the highest. The configuration settings are
loaded from each location, but settings in a higher precedence location
override those in a lower precedence location.

In
these paths, the <application> and <version> are determined
by the parameters of the IFSInitialize function.
You must call this function from your application to initialize the
API, and as part of that you must supply a name and version for your
application. Use the same name and version in your path.

For example, if you called the IFSInitialize function
with a name of "CustomApp" and a version of "1.0", you would
install the configuration file in the following location for All
Users:

Distributing applications on AIX, Solaris, and Linux

If you plan to distribute applications that call the API, you must
ensure the following:

That your package includes the correct API files.

That the PureEdgeAPI.ini file is set up correctly on each computer.

That the prefs.config file is set up correctly on each computer.

That each computer has the correct environment variable settings.

Redistributing API Files on AIX, Linux, and Solaris

Identifies the directories that need to be redistributed.

To redistribute the API, you must copy
the complete contents of the following directory, including the sub-directories,
to the target's /usr/lib/ directory:

<API_Installation_Folder>/redist/<UNIX_Type>/

Where <UNIX_Type> is one of: Linux, AIX, or SunOS.

Setting up the PureEdgeAPI.ini file on AIX, Linux, and Solaris

You must have a PureEdgeAPI.ini file to successfully create Lotus Forms applications

The PureEdgeAPI.ini file is located in the following directory:

/etc

If no PureEdgeAPI.ini file exists, you should install
your own. If a PureEdgeAPI.ini file already exists, you should update
the file to include an entry for your application. For more information
about setting up the PureEdgeAPI.ini file for your application, refer
to the IFSInitialize function if
you are using C, or theinitialize method if you are using Java.

Setting up the prefs.config file on AIX, Linux, and Solaris

The prefs.config file controls the configuration of the
API. When you redistribute the API with your application, you must
also install an application-specific configuration file on the target
computers. You should set this file to configure the API properly
for your application.

You must install the configuration file in one of the following
locations:

Both files are checked for configuration information, and the
settings in the user specific file override the settings in the /etc/PureEdge/prefs/prefs.config file. However, if you
do not require user specific settings, you only need to install the /etc/PureEdge/prefs/prefs.config file. In
these paths, the <application> and <version> are determined
by the parameters of the IFSInitialize function.
You must call this function from your application to initialize the
API, and as part of that you must supply a name and version for your
application. Use the same name and version in your path.

For example, if you called the IFSInitialize function with a name of "CustomApp" and a version of "1.0", you
would install the configuration file in the following location:

Note: If you did not install the API in the /usr/lib directory, use the appropriate directory in the
above settings. For example, if you installed the API in /home/jdoe then you would use /home/jdoe/.PureEdge/80/system.

Troubleshooting and support

If you are experiencing a problem with the API:

Refer to the documentation for the task you are performing
or the product component you are working with. These topics may contain
troubleshooting information for common problems.

Notices

This information was developed for products and services offered
in the U.S.A.

IBM may not offer the products, services, or features discussed
in this document in other countries. Consult your local IBM representative
for information on the products and services currently available in
your area. Any reference to an IBM product, program, or service is
not intended to state or imply that only that IBM product, program,
or service may be used. Any functionally equivalent product, program,
or service that does not infringe any IBM intellectual property right
may be used instead. However, it is the user's responsibility to evaluate
and verify the operation of any non-IBM product, program, or service.

IBM may have patents or pending patent applications covering subject
matter described in this document. The furnishing of this document
does not grant you any license to these patents. You can send license
inquiries, in writing, to:

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:

Such information may be available, subject to appropriate terms
and conditions, including in some cases, payment of a fee.

The licensed program described in this document and all licensed
material available for it are provided by IBM under terms of the IBM
Customer Agreement, IBM International Program License Agreement or
any equivalent agreement between us.

Trademarks

IBM, the IBM logo, ibm.com, Lotus, and Notes are trademarks or
registered trademarks of International Business Machines Corporation
in the United States, other countries, or both. These and other IBM
trademarked terms are marked on their first occurrence in this information
with the appropriate symbol (® or ™), indicating US registered or
common law trademarks owned by IBM at the time this information was
published. Such trademarks may also be registered or common law trademarks
in other countries. A current list of IBM trademarks is available
on the Web at http://www.ibm.com/legal/copytrade.shtml

Java and all Java-based trademarks and logos are trademarks or
registered trademarks of Oracle and/or its affiliates.

Linux is a registered trademark of Linus Torvalds in the United
States, other countries, or both.

Microsoft and Windows are trademarks of Microsoft Corporation in
the United States, other countries, or both.

UNIX is a registered trademark of The Open Group in the United
States and other countries.

Other company, product, or service names may be trademarks or service
marks of others.