I've been spending a lot of time with EGL lately. I've been out doing seminars (I'll be giving a session on EGL at iSeries DevCon in November), and lately I've been putting the language through its paces. When I first looked at the product, I really didn't see a lot of potential, but I think much of that was due to the powerful design concepts that make it seem almost too easy.
Simplicity Doesn't Have to Cost You Flexibility
There has been a lot of discussion on the Internet about the Ruby language and specifically Ruby on Rails (RoR). Both are superb tools developed by some extraordinarily talented folks. Ruby is a powerful object-oriented scripting language, while RoR is a framework for Ruby that simplifies many of the basic functions of building applications.
RoR's rallying cry is "convention over configuration," which means that if you follow RoR's programming rules, Ruby will do a lot of the work for you. Those rules include things like proper naming conventions for your files and fields. At the same time, if you don't like the conventions, you can override them on an individual basis.
EGL's Rich Data
EGL has a slightly different approach: It believes in configuration, but only at the lowest level. The philosophy is based on the simple concept of rich data. In EGL, every piece of data can have literally dozens of properties defined for it, ranging from simple field attributes to validation to UI characteristics (going so far as to allow you to define characteristics for a text-based interface separate from those for a GUI).
I can start by creating a "field definition file," which is just an EGL source file containing nothing but DataItems. I can then (typically in separate source files) group DataItems into Records, which have their own meta-properties. For example, a Record of type SQLRecord gets intrinsic support for SQL coding. Invoking certain EGL opcodes (such as "get") on an SQLRecord automatically generates the appropriate SQL code. Thus, these Records provide you with a very high-level syntax to access the database.
Note that I don't have to go through a two-step process, first defining DataItems in one EGL file and then creating Records from those DataItems. I can define the fields for a Record and their attributes right in the record itself. Think of the two different techniques as roughly equivalent to using a field reference file to define all your fields and then just referencing them in the DDS for your physical files as opposed to defining the attributes for each field in the physical file. If you use the same basic field type (such as a description) over and over again, you'll save yourself a lot of typing. Another nice thing about using DataItems is that the DataItem statement has a special wizard called the Source Assistant, which makes it very easy to define all the characteristics of a field.
Defining the User Interface
This rich data also serves as a fundamental device for building your user interface. EGL uses JavaServer Faces (JSF) as its primary Web UI. So first I create a new JSF page (also called a Faces JSP). Next, I can drop a Record onto that JSP using the WYSIWYG JSP designer, and it will prompt me for a couple of bits of information (such as whether the record is for display or update). EGL will then generate a nice two-column UI with the right column containing the fields and the left column (this is the cool bit!) containing the prompts that I defined for each field in the metadata. Or I can drop an array of records onto a JSP, and it will automatically generate a table with multiple rows (as many as I load in the array at runtime) and column headings from the metadata. The UI build has a lot more capabilities, which I'll explore in more detail in my next "Weaving WebSphere" column. Today though, I want to talk about EGL and RPG.
Interfacing to RPG
The key to today's discussion is the concept of a BasicRecord. Among its many uses, a BasicRecord can act very much like a data structure in RPG. You can create a BasicRecord either in your project-level EGL definitions or on the fly in your page handler (I'll do the former today). That BasicRecord can contain any number of fields and can then be passed to another EGL function.
EGL provides a very powerful interface to Java, in which you can easily identify the class and methods of an external Java package and then invoke those methods, even passing optional parameters. The biggest drawback today is that only primitive EGL fields can be passed to Java methods, not Records. That means that if I want to update a record that contains a dozen attributes, I would have to invoke the EGL/Java interface a dozen times, whereas if I could pass a Record, I would invoke the interface only once.
The EGL team is providing an even more elegant Java interface in the next release of the tool. I'm trying to convince them that passing Records is important enough to include along with the new syntax. In fact, I consider this to be such a fundamental requirement of using the tool that I have devised a workaround, which I will be using in today's article.
What's All This Java Nonsense Anyway?
You may wondering why I am talking about Java when the article is supposed to be about EGL and RPG. Well, the point is that Java provides an absolutely perfect interface between the two by way of IBM's Java Toolbox for the iSeries. By writing a few lines of Java code, I can create a fast, powerful interface between the two languages. The rest of the article will walk you through the steps required to create a simple interface that allows an RPG program to load an array, with almost no Java.
(Author's Note: Over the years, I have been trying to create a pain-free interface between RPG and the Web using as little Java as possible. For the past several years, I've been promoting a framework of Java and JSPs that, with only a few hundred lines of Java code, allows programmers to create fully functioning RPG-based Web applications but with the power and flexibility of JSPs. The technique I present today uses EGL to reduce that Java interface code to just a handful of lines, most of which can be cloned whenever you want to add another server program.)
Creating the Application
I'll start by creating an interface. And that actually starts in my mind. What I am going to do is create an interface between Java and RPG that uses a data structure. The data structure contains an opcode and a return code and then some data fields. In its simplest form, this data structure allows me to call the RPG program with two opcodes: I for initialize, and G for get. The initialize opcode tells the RPG program to get ready to send data. In this simple example, it will just do a SETLL to the beginning of the file, but in a more complex environment, it could perform an OPNQRYF or create an embedded SQL cursor. Then, each get opcode will return either a record or an EOF condition.
Here's the data structure:
d xsOpcode 2
d xsReturnCode 2S 0
d xsLibrary 10
d xsFile 10
d xsOwner 10
Using that as Step 0, I can now start the EGL design.
Step 1: Creating the Interface Record
Figure 1: This is the same record in EGL. (Click images to enlarge.)
I create a new file called LibraryRecord.egl and add the lines above. The name of the Record is "LibraryMessage", and it is a BasicRecord (meaning it has no other intrinsic behaviors). Note the easy relationship between RPG data types and EGL data types. Also note that I supply display names only for the data fields, not the opcode and return code. You'll see why in a moment.
Step 2: Create the Faces JSP Page
Figure 2: The basic Faces JSP wizard uses two panels to define the page.
This step simply creates the Faces page. I use one of the supplied templates (in this case, the simple blue template) and the Faces page is generated.
Step 3: Add Data to My Page
Figure 3: Add an array of LibraryMessages to the page.
Next, I simply add an array of messages to the page. Note that I didn't check the box marked "Add controls...". This will add the array to my Page Data but not actually generate a UI for it. I will generate the UI in the next step.
Step 4: Define the User Interface
Figure 4: The next step is to drag the array onto the page where I want it.
I changed the test at the top of the page to "Libraries," and now I drag the array of LibraryMessages from my Page Data list to the bottom of the page. When I drop the array on the page, I get a prompt like the one in Figure 5.
Figure 5: This wizard lets me configure the controls of the table as well as the columns.
Now you can see why I added display names for only the three data fields; only those fields will be displayed on the page! You can select fields, move them around, change their input capabilities, and so on.
Step 5: Create the Java Interface
Figure 6: Today, I basically write a placeholder; I have to hack the code later.
The last thing I have to do on the client side is create the interface to the Java, which in turn calls the RPG program. I add two lines of EGL. The first defines a singular element of type LibraryMessage called libraryMessage (note that the array of LibraryMessages named Libraries was created for me back in Step 3). The second line appends this single record to the array of records. Now, that's kind of dumb: The single message is empty, so basically this would create a single empty row in the table. Don't worry; I plan to go into the generated Java code and hack in a call to my Java interface code. The code up until this point has taken a couple of minutes to implement.
Step 6: Hack the Generated Java
Figure 7: This is the hack I make; the original code is inside the box, and I add the additional code.
My entire hack is based on creating an instance of the interface object (called Library) and invoking three routines: init(), get(), and close(). The init() method creates the host connection and calls the program with the I opcode, the get() method calls the program with the G opcode and returns "true" or "false" based on whether it completes succesfully, and the close() method closes the connection with the host. What I'm asking the EGL team for is the ability to define a new Record of type JavaRecord (rather than SQLRecord) in which I can define the Java class in the Record. Then, when I write a simple "get libraries" in my EGL code, it will generate calls to the init(), get(), and close() methods something like what I have done. This doesn't have to be the way they do it, but I need something this simple in order to be able to use EGL as a UI layer for my RPG logic.
The hack, by the way, takes only a minute to implement. The problem is that the next time I generate code for the page (for example, if I have to make some sort of change to the table), I lose the hack. This is a general issue with EGL: It's not really a round-trip 4GL; it's more of a code generator. It generates the code, and then you can update it.
The Result
Figure 8: This is the resulting page—simple, clean, and very fast.
I'm including the Java code and the RPG code that makes this work. If you look at the Java code, you'll find that there's a clever bit of code in there (and remember, when I say "clever," I mean "it works but it could be confusing"). I define the host variable as static, and I also define a static thread called "killer." The thread uses an internal class named Killer, and it's used to kill the connection after a certain period of time elapses. This allows me to use a single connection over and over (which can be lengthy), yet will close it if the user remains idle for a while. It's a great technique in general, but this particular coding style means that all users share the same instance. That can be a problem. Instead, there should be one instance per user stored in the HttpSession object, but since I don't have ready access to the HttpSession object, it's hard to do that. But this code will work for testing.
You may also notice a hack in the RPG program; it has a counter and a hard-coded limit of 20 libraries. Again, I did that for testing purposes. You can remove that limitation if you'd like to see how the interface works with long lists. However, I'll be doing more with this program in the next article (including things like testing the paging controls built into the JSF editor).
So Is It Soup Yet?
Good question. I wish I had a simple, consistent answer. Instead, today my answer depends on how you would like to use the tool. If you're planning to use it as a rapid development environment for generating screens and then interfacing with back-end RPG logic, EGL rates about four out of five stars. On the other hand, if you plan to use it as a complete ground-up development environment, the lack of support for round-trip modifications and the inability to percolate changes automatically through the generated code drops it to perhaps three stars. And some of my perceptions are betting on future enhancements to the language which, if they don't materialize, will adversely affect the tool's usefulness at least in the types of things I am trying to do.
No matter how you look at it, though, EGL has a whole lot of things going for it. It does perhaps the best job of using JSF I've seen and does it with a powerful WYSIWYG front-end. The support for SQL is straightforward and well-thought-out, and the basic JSF tooling in WDSC is superb. A couple of tweaks here or there for the RPG interface and I think EGL may be the thin-client interface I've been looking for.
And most importantly, the real selling point of EGL is that it's free. With EGL, IBM has finally addressed the nagging issue of there being no native graphical language for the System i. WDSC and EGL provide a replacement for 5250 that I believe can give Visual Studio a run for its money. EGL may well be the last piece of the System i puzzle. With its Eclipse heritage, WDSC has always been a fantastic Web application development tool, and the combination of RSE and LPEX make it a very powerful tool for server-side RPG development. But what's been missing is the bridge between the two. As System i developers begin to see the capabilities of EGL, I think they'll start flocking to WDSC in droves.
In fact, about the only thing IBM could do right now to crush WDSC and EGL would be to start charging for it. Remember, one of the reasons that System i customers are willing to pay the rather large premium on the hardware is that we expect a bundled machine. If I pay for 5722WDS (the developer's tools) I expect that to include all the tools I need, especially since IBM is telling me to get off of the green-screen. And we already have a bad taste in our mouths about the interactive tax, and the nasty little bait and switch of WebSphere Application Server 4.0 isn't far in the past. So don't stick it to me yet again in order to develop Web applications.
If it's an issue of wanting to go to a more user-based pricing scheme for the products, then maybe IBM can do this: figure out a reasonable number of users for each processor tier and then include some bucks in the price of 5722WDS. Kick that back to the WDSC development group, and if I as a user outgrow that number, I can buy more licenses. I suppose having 100 WDSC licenses running on a low-end model 520 is overreaching the spirit of the tool. But at the same time, don't make me pay for every copy of WDSC, or chances are I won't buy any, and the momentum of the box stalls.
Please drop a note in the forums! I'd really like to hear your opinion on WDSC and whether or not you plan to use the tool, whether you might consider EGL, and whether an additional charge for the tools would affect your decision.
Anyway, stay tuned for the next installment. This column was dedicated to making sure I can use EGL with an RPG back-end. Next time, I want to focus on the front-end and see just how capable the tools are for creating good-looking user interfaces.
Joe Pluta is the founder and chief architect of Pluta Brothers Design, Inc. and has been extending the IBM midrange since the days of the IBM System/3. Joe uses WebSphere extensively, especially as the base for PSC/400, the only product that can move your legacy systems to the Web using simple green-screen commands. He has written several books, including E-Deployment: The Fastest Path to the Web, Eclipse: Step by Step, and WDSC: Step by Step. Joe performs onsite mentoring and speaks at user groups around the country. You can reach him at
LATEST COMMENTS
MC Press Online