|
|||||||
|
|
![]() |
|
|
iSeriesMonitorME: A Real-World Wireless iSeries Application by Marc Logemann [The code for this article is available for download.] In this last article of our series about wireless programming, I will show you the steps to create your first application, known as MIDlet. It's assumed that you merely know how to create simple menus and commands in the MIDP API. This application is not a ten-liner describing raw ToolboxME ProgramCall usage, but a complete application that can be extended later on. The application will call a system API on the iSeries in order to query such information as which users are currently signed on or what is the number of batch jobs running. Figure 1 shows the navigation tree of the application. The application has two major areas. The first manages the preferences for connecting to the MEServer and the iSeries, including fields like username, password, and TCP/IP data. The other area is the execution of commands after a successful connection to the machine.
Start the MEServer of the ToolboxME Package Whatever you want to do with the ToolboxME package, starting the MEServer is mandatory. As I described in "iSeriesMonitorME: An Intro to Wireless Programming with iSeries ToolboxME," the MEServer is a kind of proxy server for your wireless device; all of the communication to the iSeries will be tunnelled through it. But before we can start the MEServer, we have to explore the world of Program Call Markup Language (PCML). Because we will call a program--in fact a system program of the iSeries--we have to define input and output parameters. IBM created an XML-based language for defining those parameters called PCML. There is also the chance to declare the parameters inside the program, but I personally like declarative programming, so I focus on an external PCML file. Click here to see the PCML file. You can see that we call a program in the QSYS library called QWCRSSTS. This is a system program for retrieving the current iSeries status. You also could define a user-written RPG, CL, or COBOL program. The <data> tag allows you to define input and output parameters. This specific program expects 5 parameters; the most important one is the receiver parameter, a structure that will be filled with data after the program call. The structure was defined in the first few lines of the pcml file, which is only partially displayed here. The remaining question you might have is, where do we find the details of the structure and the needed program parameters? IBM supplies information about all system programs on the iSeries Information Center Web site. For the sake of simplicity, just copy the PCML file into the root of the Integrated File System (IFS) on your iSeries. You can place it elsewhere, but then you also have to change the start up command of the MEServer shown below. For more information on PCML, check out Kevin Vandever's article, Calling a Program Using the iSeries Toolbox for Java. Now we are ready to start the MEServer. The start up itself is quite simple. If you are on the iSeries, just write a CL program like this:
0007.00 SBMJOB CMD(STRQSH CMD('java +
0008.00 -Dcom.ibm.as400.access.Trace.category=pcml +
0009.00 com.ibm.as400.micro.MEServer -v -pc +
0010.00 QWCRSSTS.pcml -po 4444')) JOB(MESERVER) +
0011.00 JOBQ(QSYSNOMAX) CPYENVVAR(*YES) +
0012.00 ALWMLTTHD(*YES)
0013.00 ENDPGM
You can see that we submit a Qshell instance with an inline java command. Let's examine this java command in more detail. The -D parameter means that we provide a runtime property to the virtual machine; the value of the parameter is pcml. Then we provide the java class name to start, com.ibm.as400.micro.MEServer; the next parameters belong to the MEServer class itself and are described here:
The following parameters are, of course, those of the Submit Job (SBMJOB) command, and should be known to iSeries programmers or administrators. It's advisable to start the MEServer in Qshell manually the first time to be sure that everything is OK. The advantage is that you can see the console output in real time, without digging through spool files; you can automate the start up later on. You should have a recent version of JTOpen installed on your iSeries. Otherwise, refer to the IBM documentation on the JTOpen Web site to do this. If everything is OK, you should see a job called MEServer in one of your subsystems. If you started it in the Qshell manually, you have your own display session associated with the server. The Important Pieces of Our Application We will now look at the most important classes of the application in order to communicate with the iSeries. We won't cover the preferences section, because this has no direct link to the iSeries. First, we'll look at how a connection to the iSeries will be established, and then we will see how to call a program on the iSeries and get data from it. Click here to see the partial source code that performs the log in after submitting a form with the necessary parameters. As you can see, we extended the Form class of the MIDP API in order to create a custom form, which you can see in the log in path on the second screen in Figure 1. When we entered the correct data--like the iSeries IP address and the MEServer address--and the necessary authentication fields--like the user name and password--we hit the OK button on the device and get into the commandAction method, which checks if we hit the OK button and initiates the connection to the iSeries, with this code:
AS400 as400 = new AS400(remoteSystemIP.getString(),
loginUserName.getString(),
loginPassword.getString(), meServer+ ":"+ mePort);
as400.connect();
In fact, we create an AS/400 object with these parameters. If the connection can be established, as400.connect() returns true. After this, we pass the AS/400 object to the next menus, where we will need it in order to run programs on the iSeries. In the program flow, we reached the commandMenu, which you can see in Figure 1. When the user selects the SystemStatus menu item, the application will reach the following lines of code:
// some imports
public class CommandMenu extends List implements CommandListener {
// we omit the creation of the CommandMenu in this article, its
boring overall
[..]
public void commandAction(Command command, Displayable
displayable) {
if (getSelectedIndex() == 0) doSysStatus(as400);
}
private void doSysStatus(final AS400 as400) {
PgmGetSysStatus pgmGetSysStatus = new PgmGetSysStatus(as400);
String[] strings = pgmGetSysStatus.run(null);
if (strings != null) {
SysStatusForm sysStatus = new
SysStatusForm(display, strings);
display.setCurrent(sysStatus);
}
}
This piece of code is the commandMenu itself. When the user selects SystemStatus, we will again enter the commandAction method; from there we will call the doSysStatus() method and pass our AS/400 object. Now the interesting parts will occur. Because we are good programmers, we have done an abstraction to the program call in the form of the class PgmGetSysStatus The doSysStatus() just creates an object of that kind and triggers its run method. But click here to take a look what PgmGetSysStatus is about. As you can see, the run method will do all the work of calling the program and defining what parameters to get from the iSeries system call. Because we defined all possible return parameters for the QWCRSSTS program on the iSeries, we can predefine, in the Java program, what data is really important to us and must be given back. We do this by creating a string array with all the names we want to get back. Look at the PCML for the naming convention. Because this program also expects an input parameter, we provide it with a filled hash table; in our case it's only one and it's not too exciting. After defining two more variables, which hold the PCML name that should be used and the name of the program (apiName), we are ready to trigger the call, with this code: valuesToGet = ProgramCall.run(system, pcmlName, apiName, parametersToSet, parametersToGet); The result of the ProgramCall.run() method is a string array with all the important data from the iSeries. From here it's plain MIDP programming in order to display the data we got back. Now You're Ready to Develop Your Own Apps You now should have some basic understanding how to develop iSeries-based MIDP applications. In this series of articles, we covered all major parts of an MIDP project. The complete application can easily act as a starting point for your own projects with the JTOpen Micro Package. Marc Logemann is a senior e-business consultant at Spirit/21 AG, a German consulting company that focuses on iSeries services and development. He is involved in several Java- and PHP-based open-source projects and likes reading books about new technologies. Marc can be reached at marc@logemann.info. Related Articles "iSeriesMonitorME: An Intro to Wireless Programming with iSeries ToolboxME" "iSeriesMonitorME: Set Up a Wireless Development Environment "
|
Editors
Contact the Editors |
| Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved. |