271 lines
16 KiB
HTML
271 lines
16 KiB
HTML
|
<?xml version="1.0" encoding="UTF-8"?>
|
||
|
<!DOCTYPE html
|
||
|
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
|
<html lang="en-us" xml:lang="en-us">
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
|
<meta name="security" content="public" />
|
||
|
<meta name="Robots" content="index,follow" />
|
||
|
<meta http-equiv="PICS-Label" content='(PICS-1.1 "http://www.icra.org/ratingsv02.html" l gen true r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true r (n 0 s 0 v 0 l 0) "http://www.classify.org/safesurf/" l gen true r (SS~~000 1))' />
|
||
|
<meta name="DC.Type" content="reference" />
|
||
|
<meta name="DC.Title" content="Building iSeries program calls with PCML" />
|
||
|
<meta name="abstract" content="To build iSeries program calls with PCML, you must start by creating a Java application and a PCML source file." />
|
||
|
<meta name="description" content="To build iSeries program calls with PCML, you must start by creating a Java application and a PCML source file." />
|
||
|
<meta name="DC.Relation" scheme="URI" content="pcml.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="rzahh503.htm" />
|
||
|
<meta name="copyright" content="(C) Copyright IBM Corporation 2006" />
|
||
|
<meta name="DC.Rights.Owner" content="(C) Copyright IBM Corporation 2006" />
|
||
|
<meta name="DC.Format" content="XHTML" />
|
||
|
<meta name="DC.Identifier" content="pcmlproc" />
|
||
|
<meta name="DC.Language" content="en-us" />
|
||
|
<!-- All rights reserved. Licensed Materials Property of IBM -->
|
||
|
<!-- US Government Users Restricted Rights -->
|
||
|
<!-- Use, duplication or disclosure restricted by -->
|
||
|
<!-- GSA ADP Schedule Contract with IBM Corp. -->
|
||
|
<link rel="stylesheet" type="text/css" href="./ibmdita.css" />
|
||
|
<link rel="stylesheet" type="text/css" href="./ic.css" />
|
||
|
<title>Building iSeries program
|
||
|
calls with PCML</title>
|
||
|
</head>
|
||
|
<body id="pcmlproc"><a name="pcmlproc"><!-- --></a>
|
||
|
<!-- Java sync-link --><script language="Javascript" src="../rzahg/synch.js" type="text/javascript"></script>
|
||
|
<h1 class="topictitle1">Building iSeries program
|
||
|
calls with PCML</h1>
|
||
|
<div><p>To build iSeries™ program calls with PCML, you must start by
|
||
|
creating a Java™ application and a PCML source file.</p>
|
||
|
<div class="section"><p>Depending on your design process, you must write one or more PCML
|
||
|
source files where you describe the interfaces to the iSeries programs that will be called
|
||
|
by your Java application. Refer to <a href="pcmlsyn.htm#pcmlsyn">PCML
|
||
|
syntax</a> for a detailed description of the language.</p>
|
||
|
<p>Then your Java application
|
||
|
interacts with the PCML classes (in this case, the ProgramCallDocument class).
|
||
|
The <a href="javadoc/com/ibm/as400/data/ProgramCallDocument.html#NAVBAR_TOP"> ProgramCallDocument class</a> uses your PCML source file
|
||
|
to pass information between your Java application and the iSeries programs.
|
||
|
Figure 1 illustrates how Java applications interact with the PCML
|
||
|
classes.</p>
|
||
|
<p><strong><span class="synph" id="pcmlproc__figpdmlwindowsconvert"><a name="pcmlproc__figpdmlwindowsconvert"><!-- --></a><span class="kwd"></span></span>Figure
|
||
|
1. Making program calls to the server using PCML</strong>.</p>
|
||
|
<p><img src="rzahh503.gif" alt="Flow chart that outlines the process of creating a program call with PCML" /> <img src="c.gif" longdesc="rzahh503.htm" alt="Image description" /></p>
|
||
|
<p>When your application constructs the ProgramCallDocument object,
|
||
|
the XML parser reads and parses the PCML source file. For more information
|
||
|
about using an XML parser with IBM<sup>®</sup> Toolbox for Java, see <a href="rzahhxmlparserxslprocessor.htm#rzahhxmlparserxslprocessor">XML parser and XSLT processor</a>.</p>
|
||
|
<p>After the ProgramCallDocument
|
||
|
class has been created, the application program uses the ProgramCallDocument
|
||
|
class's methods to retrieve the necessary information from the server through
|
||
|
the iSeries distributed
|
||
|
program call (DPC) server.</p>
|
||
|
<p>To improve run-time performance, the ProgramCallDocument
|
||
|
class can be serialized during your product build time. The ProgramCallDocument
|
||
|
is then constructed using the serialized file. In this case, the XML parser
|
||
|
is not used at run-time. Refer to <a href="#pcmlproc__serialization">Using
|
||
|
serialized PCML files</a>.</p>
|
||
|
</div>
|
||
|
<div class="section" id="pcmlproc__sourcefiles"><a name="pcmlproc__sourcefiles"><!-- --></a><h4 class="sectiontitle">Using PCML source files</h4><p><img src="./delta.gif" alt="Start of change" />Your Java application
|
||
|
uses PCML by constructing a ProgramCallDocument object with a reference to
|
||
|
the PCML source file. The ProgramCallDocument object considers the PCML source
|
||
|
file to be a Java resource. The java application finds the PCML source
|
||
|
file by using the Java CLASSPATH<img src="./deltaend.gif" alt="End of change" /></p>
|
||
|
<p>The following Java code
|
||
|
constructs a ProgramCallDocument object:</p>
|
||
|
<pre> AS400 as400 = new AS400();
|
||
|
ProgramCallDocument pcmlDoc = new ProgramCallDocument(as400, "myPcmlDoc");</pre>
|
||
|
<p> The
|
||
|
ProgramCallDocument object will look for your PCML source in a file called
|
||
|
myPcmlDoc.pcml. Notice that the .pcml extension is not specified on the constructor. </p>
|
||
|
<p>If
|
||
|
you are developing a Java application in a Java package,
|
||
|
you can package-qualify the name of the PCML resource:</p>
|
||
|
<pre> AS400 as400 = new AS400();
|
||
|
ProgramCallDocument pcmlDoc = new ProgramCallDocument(as400, "com.company.package.myPcmlDoc");</pre>
|
||
|
</div>
|
||
|
<div class="section" id="pcmlproc__serialization"><a name="pcmlproc__serialization"><!-- --></a><h4 class="sectiontitle">Using serialized PCML files</h4><p>To
|
||
|
improve run-time performance, you can use a serialized PCML file. A serialized
|
||
|
PCML file contains serialized Java objects representing the PCML. The
|
||
|
objects that are serialized are the same objects that are created when you
|
||
|
construct the ProgramCallDocument from a source file as described above.</p>
|
||
|
<p>Using
|
||
|
serialized PCML files improves performance because the XML parser is not needed
|
||
|
at run-time to process the PCML tags.</p>
|
||
|
<p>The PCML can be serialized using
|
||
|
either of the following methods:</p>
|
||
|
<ul><li>From the command line: <div class="p"><pre> java com.ibm.as400.data.ProgramCallDocument -serialize mypcml</pre>
|
||
|
</div>
|
||
|
<p>This
|
||
|
method is helpful for having batch processes to build your application.</p>
|
||
|
</li>
|
||
|
<li>From within a Java program: <div class="p"><pre> ProgramCallDocument pcmlDoc; // Initialized elsewhere
|
||
|
pcmlDoc.serialize();</pre>
|
||
|
</div>
|
||
|
</li>
|
||
|
</ul>
|
||
|
<p>If your PCML is in a source file named myDoc.pcml, the result of serialization
|
||
|
is a file named myDoc.pcml.ser. </p>
|
||
|
</div>
|
||
|
<div class="section" id="pcmlproc__sourcevsserialize"><a name="pcmlproc__sourcevsserialize"><!-- --></a><h4 class="sectiontitle">PCML source files vs. serialized PCML
|
||
|
files</h4><p>Consider the following code to construct a ProgramCallDocument:
|
||
|
</p>
|
||
|
<pre> AS400 as400 = new AS400();
|
||
|
ProgramCallDocument pcmlDoc = new ProgramCallDocument(as400, "com.mycompany.mypackage.myPcmlDoc");</pre>
|
||
|
<p>The
|
||
|
ProgramCallDocument constructor will first try to find a serialized PCML file
|
||
|
named myPcmlDoc.pcml.ser in the com.mycompany.mypackage package in the Java CLASSPATH.
|
||
|
If a serialized PCML file does not exist, the constructor will then try to
|
||
|
find a PCML source file named myPcmlDoc.pcml in the com.mycompany.mypackage
|
||
|
package in the Java CLASSPATH. If a PCML source file does not exist,
|
||
|
an exception is thrown.</p>
|
||
|
</div>
|
||
|
<div class="section" id="pcmlproc__qualifiednames"><a name="pcmlproc__qualifiednames"><!-- --></a><h4 class="sectiontitle">Qualified names</h4><p>Your Java application
|
||
|
uses ProgramCallDocument.setValue() to set input values for the iSeries program
|
||
|
being called. Likewise, your application uses ProgramCallDocument.getValue()
|
||
|
to retrieve output values from the iSeries program.</p>
|
||
|
<p>When accessing
|
||
|
values from the ProgramCallDocument class, you must specify the fully qualified
|
||
|
name of the document element or <<strong>data</strong>> tag. The qualified name is
|
||
|
a concatenation of the names of all the containing tags with each name separated
|
||
|
by a period.</p>
|
||
|
<p>For example, given the following PCML source, the qualified
|
||
|
name for the <strong>"nbrPolygons"</strong> item is <strong>"polytest.parm1.nbrPolygons"</strong>.
|
||
|
The qualified name for accessing the <strong>"x"</strong> value for one of the points
|
||
|
in one of the polygons is <strong>"polytest.parm1.polygon.point.x"</strong>.</p>
|
||
|
<p>If
|
||
|
any one of the elements needed to make the qualified name is unnamed, all
|
||
|
descendants of that element do not have a qualified name. Any elements that
|
||
|
do not have a qualified name cannot be accessed from your Java program.</p>
|
||
|
<pre><pcml version="1.0">
|
||
|
<program name="polytest" path="/QSYS.lib/MYLIB.lib/POLYTEST.pgm">
|
||
|
<!-- Parameter 1 contains a count of polygons along with an array of polygons -->
|
||
|
<struct name="parm1" usage="inputoutput">
|
||
|
<data name="nbrPolygons" type="int" length="4" init="5" />
|
||
|
<!-- Each polygon contains a count of the number of points along with an array of points -->
|
||
|
<struct name="polygon" count="nbrPolygons">
|
||
|
<data name="nbrPoints" type="int" length="4" init="3" />
|
||
|
<struct name="point" count="nbrPoints" >
|
||
|
<data name="x" type="int" length="4" init="100" />
|
||
|
<data name="y" type="int" length="4" init="200" />
|
||
|
</struct>
|
||
|
</struct>
|
||
|
</struct>
|
||
|
</program>
|
||
|
</pcml></pre>
|
||
|
</div>
|
||
|
<div class="section" id="pcmlproc__accessingarrays"><a name="pcmlproc__accessingarrays"><!-- --></a><h4 class="sectiontitle">Accessing data in arrays</h4><p>Any <<strong>data</strong>>
|
||
|
or <<strong>struct</strong>> element can be defined as an array using the <strong>count</strong> attribute.
|
||
|
Or, a <<strong>data</strong>> or <<strong>struct</strong>> element can be contained within
|
||
|
another <<strong>struct</strong>> element that is defined as an array.</p>
|
||
|
<p>Furthermore,
|
||
|
a <<strong>data</strong>> or <<strong>struct</strong>> element can be in a multidimensional
|
||
|
array if more than one containing element has a <strong>count</strong> attribute specified.</p>
|
||
|
<p>In
|
||
|
order for your application to set or get values defined as an array or defined
|
||
|
within an array, you must specify the array index for each dimension of the
|
||
|
array. The array indices are passed as an array of <strong>int</strong> values. Given
|
||
|
the source for the array of polygons shown above, the following Java code
|
||
|
can be used to retrieve the information about the polygons:</p>
|
||
|
<pre> ProgramCallDocument polytest; // Initialized elsewhere
|
||
|
Integer nbrPolygons, nbrPoints, pointX, pointY;
|
||
|
nbrPolygons = (Integer) polytest.getValue("polytest.parm1.nbrPolygons");
|
||
|
System.out.println("Number of polygons:" + nbrPolygons);
|
||
|
indices = new int[2];
|
||
|
for (int polygon = 0; polygon < nbrPolygons.intValue(); polygon++)
|
||
|
{
|
||
|
indices[0] = polygon;
|
||
|
nbrPoints = (Integer) polytest.getValue("polytest.parm1.polygon.nbrPoints", indices );
|
||
|
System.out.println(" Number of points:" + nbrPoints);
|
||
|
|
||
|
for (int point = 0; point < nbrPoints.intValue(); point++)
|
||
|
{
|
||
|
indices[1] = point;
|
||
|
pointX = (Integer) polytest.getValue("polytest.parm1.polygon.point.x", indices );
|
||
|
pointY = (Integer) polytest.getValue("polytest.parm1.polygon.point.y", indices );
|
||
|
System.out.println(" X:" + pointX + " Y:" + pointY);
|
||
|
}
|
||
|
}</pre>
|
||
|
</div>
|
||
|
<div class="section" id="pcmlproc__debugging"><a name="pcmlproc__debugging"><!-- --></a><h4 class="sectiontitle">Debugging</h4><p>When you use PCML to call
|
||
|
programs with complex data structures, it is easy to have errors in your
|
||
|
PCML that result in exceptions from the ProgramCallDocument class. If the
|
||
|
errors are related to incorrectly describing offsets and lengths of data,
|
||
|
the exceptions can be difficult to debug. </p>
|
||
|
<p>Use the following method
|
||
|
from the <a href="trace.htm#trace">Trace</a> class to turn on PCML
|
||
|
tracing:</p>
|
||
|
<pre> Trace.setTraceOn(true); // Turn on tracing function.
|
||
|
Trace.setTracePCMLOn(true); // Turn on PCML tracing.</pre>
|
||
|
<div class="note"><span class="notetitle">Note:</span> All
|
||
|
public methods in the <a href="javadoc/com/ibm/as400/data/PcmlMessageLog.html#NAVBAR_TOP">PcmlMessageLog</a> class, including tracing, were deprecated
|
||
|
in V5R2.</div>
|
||
|
<p> The Trace <a href="javadoc/com/ibm/as400/access/Trace.html#SETFILENAME(JAVA.LANG.STRING)">setFileName() method</a> enables you to send the following
|
||
|
types of information to specific log files or, by default, to System.out:</p>
|
||
|
<ul><li>A dump of the hexadecimal data being transferred between the Java application
|
||
|
and the iSeries program.
|
||
|
This shows the program input parameters after character data is converted
|
||
|
to EBCDIC and integers are converted to big-endian. It also shows the output
|
||
|
parameters before they are converted to the Java environment. <p>The data is shown
|
||
|
in a typical hexadecimal dump format with hexadecimal digits on the left and
|
||
|
a character interpretation on the right. The following is an example of this
|
||
|
dump format. (The following example was altered to allow for width restrictions)</p>
|
||
|
<div class="p"><pre>qgyolobj[6]
|
||
|
Offset : 0....... 4....... 8....... C....... 0....... 4....... 8....... C.......
|
||
|
0...4...8...C...0...4...8...C...
|
||
|
0 : 5CE4E2D9 D7D9C640 4040
|
||
|
**USRPRF *</pre>
|
||
|
In the above example,
|
||
|
the dump shows the seventh parameter has 10 bytes of data set to "*USRPRF
|
||
|
".</div>
|
||
|
</li>
|
||
|
<li>For output parameters, following the hexadecimal dump is a description
|
||
|
of how the data has been interpreted for the document. (The following example
|
||
|
was altered to allow for width restrictions) </li>
|
||
|
</ul>
|
||
|
<div class="p"><pre>/QSYS.lib/QGY.lib/QGYOLOBJ.pgm[2]
|
||
|
Offset : 0....... 4....... 8....... C....... 0....... 4....... 8....... C.......
|
||
|
0...4...8...C...0...4...8...C...
|
||
|
0 : 0000000A 0000000A 00000001 00000068 D7F0F9F9 F0F1F1F5 F1F4F2F6 F2F5F400
|
||
|
*................P09901151426254.*
|
||
|
20 : 00000410 00000001 00000000 00000000 00000000 00000000 00000000 00000000
|
||
|
*................................*
|
||
|
40 : 00000000 00000000 00000000 00000000
|
||
|
*................ *
|
||
|
Reading data -- Offset: 0 Length: 4 Name: "qgyolobj.listInfo.totalRcds"
|
||
|
Byte data: 0000000A
|
||
|
Reading data -- Offset: 4 Length: 4 Name: "qgyolobj.listInfo.rcdsReturned"
|
||
|
Byte data: 0000000A
|
||
|
Reading data -- Offset: 8 Length: 4 Name: "qgyolobj.listInfo.rqsHandle"
|
||
|
Byte data: 00000001
|
||
|
Reading data -- Offset: c Length: 4 Name: "qgyolobj.listInfo.rcdLength"
|
||
|
Byte data: 00000068
|
||
|
Reading data -- Offset: 10 Length: 1 Name: "qgyolobj.listInfo.infoComplete"
|
||
|
Byte data: D7
|
||
|
Reading data -- Offset: 11 Length: 7 Name: "qgyolobj.listInfo.dateCreated"
|
||
|
Byte data: F0F9F9F0F1F1F5
|
||
|
Reading data -- Offset: 18 Length: 6 Name: "qgyolobj.listInfo.timeCreated"
|
||
|
Byte data: F1F4F2F6F2F5
|
||
|
Reading data -- Offset: 1e Length: 1 Name: "qgyolobj.listInfo.listStatus"
|
||
|
Byte data: F4
|
||
|
Reading data -- Offset: 1f Length: 1 Name: "qgyolobj.listInfo.[8]"
|
||
|
Byte data: 00
|
||
|
Reading data -- Offset: 20 Length: 4 Name: "qgyolobj.listInfo.lengthOfInfo"
|
||
|
Byte data: 00000410
|
||
|
Reading data -- Offset: 24 Length: 4 Name: "qgyolobj.listInfo.firstRecord"
|
||
|
Byte data: 00000001
|
||
|
Reading data -- Offset: 28 Length: 40 Name: "qgyolobj.listInfo.[11]"
|
||
|
Byte data: 00000000000000000000000000000000000000000000000000000000000000000000000000000000</pre>
|
||
|
The
|
||
|
above messages can be very helpful in diagnosing cases where the output data
|
||
|
coming from the iSeries program
|
||
|
does not match the PCML source. This can easily occur when you are using dynamic
|
||
|
lengths and offsets.</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div>
|
||
|
<ul class="ullinks">
|
||
|
<li class="ulchildlink"><strong><a href="rzahh503.htm">Long description of Figure 1: Making program calls to the server using PCML (rzahh503.gif)</a></strong><br />
|
||
|
</li>
|
||
|
</ul>
|
||
|
|
||
|
<div class="familylinks">
|
||
|
<div class="parentlink"><strong>Parent topic:</strong> <a href="pcml.htm" title="Program Call Markup Language (PCML) is a tag language that helps you call server programs, with less Java code.">Program Call Markup Language</a></div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</body>
|
||
|
</html>
|