ibm-information-center/dist/eclipse/plugins/i5OS.ic.rzahh_5.4.0.1/pcmlproc.htm

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 &lt;<strong>data</strong>&gt; 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>&lt;pcml version="1.0"&gt;
&lt;program name="polytest" path="/QSYS.lib/MYLIB.lib/POLYTEST.pgm"&gt;
&lt;!-- Parameter 1 contains a count of polygons along with an array of polygons --&gt;
&lt;struct name="parm1" usage="inputoutput"&gt;
&lt;data name="nbrPolygons" type="int" length="4" init="5" /&gt;
&lt;!-- Each polygon contains a count of the number of points along with an array of points --&gt;
&lt;struct name="polygon" count="nbrPolygons"&gt;
&lt;data name="nbrPoints" type="int" length="4" init="3" /&gt;
&lt;struct name="point" count="nbrPoints" &gt;
&lt;data name="x" type="int" length="4" init="100" /&gt;
&lt;data name="y" type="int" length="4" init="200" /&gt;
&lt;/struct&gt;
&lt;/struct&gt;
&lt;/struct&gt;
&lt;/program&gt;
&lt;/pcml&gt;</pre>
</div>
<div class="section" id="pcmlproc__accessingarrays"><a name="pcmlproc__accessingarrays"><!-- --></a><h4 class="sectiontitle">Accessing data in arrays</h4><p>Any &lt;<strong>data</strong>&gt;
or &lt;<strong>struct</strong>&gt; element can be defined as an array using the <strong>count</strong> attribute.
Or, a &lt;<strong>data</strong>&gt; or &lt;<strong>struct</strong>&gt; element can be contained within
another &lt;<strong>struct</strong>&gt; element that is defined as an array.</p>
<p>Furthermore,
a &lt;<strong>data</strong>&gt; or &lt;<strong>struct</strong>&gt; 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 &lt; 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 &lt; 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>