Welcome to the EGL Rich UI Hub

EGL Rich UI transforms the way Rich Internet Applications (RIAs) and mashups are developed by dramatically simplifying the programming model, hiding the complexities of JavaScript and Ajax, and enabling developers of all backgrounds to quickly build Web 2.0 solutions.

Why EGL Rich UI?

  • Hide complexity of JavaScript, Ajax, JSON, etc.
  • Fully open and extensible
  • Easily integrate/consume any service (REST or SOAP)
  • Single language end-to-end (front-end to back-end)
  • Includes visual composition, libraries of RUI widgets
  • Instant deploy/visualize while you code
  • Extends existing enterprise data and processes to Web 2.0

RUI Thumbnails

For additional information, view the whitepaper or read the official announcement.

How can I get it?
EGL Rich UI is available in IBM Rational Business Developer 7.5.1. Download the trial now.

Popular Blog Posts on EGL Rich UI

2

I am sure that there is many ways to accomplish this task...
But I want to show one that I have done using Web Services and Rich UI.

Do you have an iPhone or iPod touch?

Click here:
For COBOL/CICS/IMS:
http://testiphone.com/?address=on&url=http://zserveros.demos.ibm.com:9080/iPhone/egl.html
(the options 1, 2,3 and 5 were done with EGL Rich UI; the #4 was done by COBOL/CICS only and not discussed in this blog.)
For RPG:
http://testiphone.com/?address=on&url=http://iseriesd.demos.ibm.com:59900/isys/rpg.html(Application Server on System i)
Or
http://testiphone.com/?address=on&url=http://zserveros.demos.ibm.com:9080/isys/rpg.html
Application Server on System z)

I have done all that above (the client and the server piece) in less than 12 hours and I am an old generation guy. I started doing COBOL development punching IBM 029 cards.. Since then I had learned lots of new stuff, but as you all know this is a never ending.... and this is the beauty of EGL: simplifies that learning curve.
I am familiar with the EGL language and Rational Developer for z with EGL (RDz) as well some skill on Rational Developer for system i for SOA Construction(RDi SOA). Using those tools I created these simple demos, reusing existing COBOL/CICS/VSAM, COBOL/IMS and RPG code.

What really impressed me in this small demo is the response time to invoke either CICS, IMS or RPG Services... Try it..
Another surprise.. when the parsing is done by COBOL (CICS demo) I got the same or even better response time compared to parsing done by Java (IMS and RPG demos).

Using the Service Monitor (available here in the EGL Café) when you click in the green icon: http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1195-1546/Green_Icon.gif
The response time to invoke the web services will vary from 0.15 to 2 seconds.. Really impressive. This is like green screens response time.. and remember that we have SOAP XML parsing, etc..

You also can see this in action using the YouTube links below:
CICS: http://www.youtube.com/watch?v=5JyJ0XXR_3c
IMS: http://www.youtube.com/watch?v=c2bGHjCQQZo

I have created those demos using 4 different topologies:

1. Demos #1, # 2, and #3 - All the code was deployed into our WebSphere Application Server (WAS) located in our demo z/OS system in Austin, Texas.
http://zserveros.demos.ibm.com:9080/iPhone/egl.html

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1195-1541/blog_zOS_iPhone.gif

2. RPG Demo #1 - (WAS and RPG Web Service on System i)
http://iseriesd.demos.ibm.com:59900/isys/rpg.html
http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1195-1545/blog_rpg_iPhone.gif

3. RPG Demo #2 (WAS on System z and RPG Web Service on system i)
http://zserveros.demos.ibm.com:9080/isys/rpg.html

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1195-1543/blog_rpg_zOS_iPhone.gif

4. IMS Demo #4 (WAS on System z and the IMS Service deployed as Java - JCA using RAR connectors - in the WAS also)
http://zserveros.demos.ibm.com:9080/iPhone/IMS.html

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1195-1578/blog_+zOS_IMS_topology.gif


1.0 Creating the iPhone Web 2.0 for COBOL/CICS

To explain this code creation I will split in two parts.. Creating the Web Service provider (under CICS) and creating the Web Service requester (iPhone).

Part 1 – Create the COBOL/CICS SOAP Web Service

This was very easy, since I have been doing that since 4 or more years ago.
Basically using an existing COBOL/CICS program and the RDz wizards the CICS SOAP Web Service is created and WSDL is generated. The code is deployed into the CICS also using RDz facilities. The XML parsing is done by the COBOL generated by RDz.

You can see a tutorial as well do it yourself using the System z Sandbox and the tutorial Wrap existing COBOL programs as Web Services with IBM Rational Developer for System z.
This is the same service that I am using in the option # 2 and option #3 of the demo link.
The option of the demo link is also being explained in the article Modernize your CICS applications with SOA and Web 2.0 using Rational tools.

It’s not easy? The service can be created, deployed and tested using RDz and without any change in the existing COBOL/CICS code.

Part 2 – Create the Web 2.0 that will invoke the CICS Web Service

This is my favorite piece.. I can use the latest technologies and deploy the code in the iPhone or iPod touch as well in black berries with Opera Mini browsers, without having to learn JavaScript, AJAX, REST,etc.. Just EGL..
Given the WSDL generated on part 1, I used RDz and the EGL wizards to create the Rich UI piece.
All the code was deployed into our WebSphere Application Server located in a z/OS system in Austin, Texas.

2.0 Creating the iPhone Web 2.0 for RPG

Again to explain this code creation I will split in two parts.. Creating the service provider (under System i ) and creating the service requester (iPhone), that is similar to the CICS piece.

Part 1 – Create the RPG SOAP Web Service.

This is easy and you need the RDi SOA to wrap the RPG existing code into service.This is a bit different that the CICS piece since the Web Service here is deployed in the Application Server, not handled directly by CICS like in the previous example..Using RDi SOA and an existing RPG the SOAP Web Service is created and WSDL is generated. The code is deployed into the System i WebSphere Application Server System i WebSphere Application Server.Again this is very easy, let the tool generated the Java wrapper. The service can be created, deployed and tested using RDi SOA and without any change in the existing RPG code.

Part 2 - Create the Web 2.0 that will invoke the RPG Web Service

Given the WSDL generated on part 1 above, I used RDi SOA and the EGL wizards to create the Rich UI piece.
All the code was deployed into our WebSphere Application Server located in the System i, also located in Austin, Texas.
In this demo I decided to have to different options. In the demo RPG demo #1 this is on System I and in the RPG demo #2the Rich UI and AJAX proxy are located in our z/OS system. In both demos the SOAP Web Service is deployed in the System I Application Server.


3.0 Creating the iPhone Web 2.0 for IMS

I could create Web services as I did with CICS, generating COBOL adapters to do the SOAP parsing, but I decided to have other approach here. I used the Java connectors to create the web services using the JCA adapters (using RAR - J2EE Resource Adapters) and deployed the generated Java web service to WAS on z. The XML parsing here is done by Java, not by the COBOL adapters. The idea was to compare the response time.

Part 1 – Create the Java SOAP Web Service.

This is easy and you need the RDz with Java or RAD (Rational Application Developer) to wrap the existing COBOL/IMS code into Java Web Services.
I used the J2C wizards (part of RDz with Java or RAD). The wizards also generated the WSDL as well the Java code (EAR file) that I deployed into WAS on z. Again, note that this is a bit different that the CICS demo since the XML parsing is done by JAVA (not COBOL as in CICS) and the EAR iss deployed in the Application Server.

Part 2 - Create the Web 2.0 that will invoke the Java Web Service that will invoke the existing COBOL/IMS code.

Given the WSDL generated on part 1 above, I used RDz with EGL as I did before with CICS to create the Rich UI piece.
All the code was deployed into our WebSphere Application Server located in the System z.
To execute this use:
http://zserveros.demos.ibm.com:9080/iPhone/IMS.html-----

4.0 Running the demo

You can demonstrate this using either an iPod touch connected via WI-FI or using an iPhone connected to a network. Also you may demonstrate using Browser emulators for the iPhone.

If you want to use another smart phone like a BlackBerry, you will need to install a better browser than the provided. The default BB browser doesn't have JavaScript enabled, but Opera Mini does. From your BB browser, go to *mini.opera.com*and click on Download Opera Mini. The new browser will be installed under Applications and a large O will be created.

For the demo sequence as well a PDF that you can print, see the attached file.


5.0 Flash movies provided.

I have uploaded two movies that may help you. You must download the *.wmv appended on this blog. Sorry my "Boston" accent.. http://www-949.ibm.com/software/rational/cafe/images/emoticons/happy.gif :

1. How the COBOL/CICS Demo was built using RDz and EGL Rich UI.
Iphone_CICS_Build.wmv

2. The demo in action using an iPhone browser emulator.
Iphone_CICS_RUN_WMV.wmv

3. The demo in action using an iPhone browser emulator.
Iphone_IMS_Run_ONLY_WMV.wmv

2 Comments Permalink
15

EGL Rich UI makes it really simple to invoke REST or SOAP web services and to convert the message parameters and result into EGL Records. However, sometimes, the service does not work and you feel like you are stuck. In this blog entry I will share some best practices we developed on the Rich UI team for dealing with services that don't respond as you expect them to.

Most people start out with using the following syntax to make a service call:

function doit() 
    call foo.bar(...) returning to callback;
end     
function callback(...)
    ...
end

When the foo.bar service is invoked, a response will be returned some time in the future, and then the callback function is called. It gets interesting when the service is not available, or when we pass invalid parameters to the service call. How to deal with exceptions?

When using service calls as shown above, the default error you will see will resemble the following message:

error.png

Admittedly, this message is not very useful. All it says is that something went wrong. However, it also tells you to add an exception handler to get a more detailed explanation. Following this advise, you might be tempted to rewrite your service call to look like this:


function doit() 
    try 
        call foo.bar(...) returning to callback; 
    onException(exception AnyException)
        ...    // service errors never get here!
    end
end     

It would seem like the right thing to do. Call a service. When something bad happens, handle the exception. However, service calls consist of two steps. First, you send out the service request, which is really dealt with in the "call" part of the statement. The service request is sent over the wire, and control immediately continues to the next line. No exceptions will happen at this point, as you can assume we will always be able to send the request over the wire. Now, when the response comes back in the future, the callback is invoked. If the server responds with an error message instead, we have no real place to report the error to the code. This is why we have a special syntax on the call statement looking like this:


function doit() 
    call foo.bar(...) returning to callback onException handleException;
end     
private function handleException(exception AnyException in)
    e ServiceInvocationException = exception;
    writeStdout("OOPS. " + e.message + " " + e.detail3);
end

Now, each time the service is unresponsive, or the server complains about our parameters being incorrect, the handleException function will be called, and we can take evasive actions.

With that in mind, service debugging is already much easier. However, it is still hard to see what request body we sent out, what actual reponse headers we received, etc. In some cases, you actually will need to inspect those to deal with pesky third party services that have a particular way of having to be set up. One example would be a service that establishes a connection in a login screen, and returns a cookie in the response header. In future calls, you are then expected to pass in that same cookie as part of your request parameters. We need a tool to easily inspect and spy upon the services being sent by a Rich UI application. Tools like Firebug help, but it happens to be that it is not too hard to do this directly in Rich UI itself.

To explain our approach to a Service Monitor, let's show the intended end result first:

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1128-1297/monitorBar.png

The Service Monitor shows an extra bar at the top of your application. Each green icon represents a successful service call, and a red icon shows a failed attempt. When you click on one of the green or red icons, a dialog box opens which you can drag around the screen:

monitor.png

The dialog shows the details of the service call. You will see things like the method being used (POST/GET/PUT/UPDATE), the values of the request and response body, the query parameters, and the request and response header. You will also see how long the service took to return. The service monitor is easily added to any application by simply adding a field declaration to your application's RUIhandler:


    monitor tools.ServiceMonitor;

The implementation of the Service Monitor works in two steps. First, we include a bit of extra JavaScript that detects when a service call is made, and when it returns (see ServiceMonitorRuntime.js). As a result, three InfoBus events are generated.

The three InfoBus events that are now generated by the runtime are received by a piece of UI (see ServiceMonitor.egl, implementing the monitor bar shown above). Actions are taken to respond to these events taking place:


function start()
    InfoBus.subscribe("service.monitor.call", serviceCalled);
    InfoBus.subscribe("service.monitor.success", serviceSucceeded);
    InfoBus.subscribe("service.monitor.error", serviceFailed);
    ...
end
function serviceSucceeded(message String in, object any in)
    info ServiceMonitorInfo = object;
    info.setStatus("Service responded successfully (i.e., server actually sent a response)", "tools/ok.png", "#33CC66");
    succeeded += 1;
    showCurrentURL();
end
function serviceFailed(message String in, object any in)
    info ServiceMonitorInfo = object;
    info.setStatus("Service Error: "+info.errorDetail, "tools/error.png", "red");
    failed += 1;
    showCurrentURL();
end    

As you can see, if a service call is successful, we will add an OK icon with green background. Otherwise, we add an ERROR icon with red background.

You will see that our entire implementation is surprisingly small (less than 200 lines of EGL and 100 lines of JavaScript). Yet, we have a powerful yet inobtrusive monitoring tool with a nice looking UI. By using the InfoBus we separate the different concerns of event generation and consumption, keeping things nice and clean.

Have fun using this monitor and hopefully you will find it will greatly improve your ability to call any web service out there....

15 Comments Permalink
0

Let me be the last person to wish you a Happy New Year!

This is a quick post to remind everyone to pay attention to the event handlers you decide to use in your EGL RUI applications. On the surface the event handlers onClick and onChange do the same thing for a ListMulti widget. That said, making sure you use onChange allows your application to function as expected when using the keyboard.

Here is an example to show you what I mean. The following RUIHandler creates a ListMulti widget and prints beneath it the number of items selected. When using the mouse, regardless if I used onClick or onChange the text label would print the correct value. Now, if I select the first element with the mouse, then hold the SHIFT key and use the UP/DOWN keys to select the other list elements, if I had the event handler as onClick those keyboard actions wouldn't be registered. Most of the time you would want them - so be sure to use the onChange event handler.

Handler MultiSel Type RUIHandler { initialUI = [ Box, TextLabel ] }
	TextLabel com.ibm.egl.rui.widgets.TextLabel{ text="TextLabel" };
	Box com.ibm.egl.rui.widgets.Box{ padding=8, children=[multilist] }; 
	
	multilist ListMulti{values = ["One", "Two", "Three", "Four", "Five"], onChange ::= multiSelFunc};

	function multiSelFunc(e event in)
		sz int = multilist.getSelection().getSize(); 
		for(i int from 1 to sz)
			TextLabel.text = "MultiSel: " + i + " selected \n";
		end
	end	
End  

All the best,
George

0 Comments Permalink
1

In an earlier posting I mentioned the importance of using external style sheets to separate look and feel from behavior in EGL Rich UI applications. In practice, some EGL Rich UI users have experienced challenges in keeping the CSS syntactically valid. The CSS editors that come with Eclipse/WTP, and which we use without change in RBD, do not validate the CSS that is being edited inside them. And RBD does not add any extra help either.

Not having CSS validation in our tooling makes CSS error detection and debugging more difficult. The best technique we can come up with is to use Firebug in Firefox, but that requires quite some extra setup and work by the developer. A very useful online service called Jigsaw is also available at w3.org. You simply enter your CSS into a form, and the service will tell if it is valid CSS or not. Here is the service with an intentionally invalid sample:

css-validator.png

After pressing the "Check" button, you will see a result looking like this:

css-validator-result.png

While using the Jigsaw service, I was thinking that the Rich UI application that I was developing could easily validate itself by making a REST service call to the same Jigsaw service, passing its own CSS files as an argument. So, I wrote an EGL Rich UI widget (without needing any JavaScript, of course). It basically does the following:

  1. Inspect the document body, and find all elements with tag name equal to "LINK".
  2. Download each CSS file and send it to the CSS to the Jigsaw service.
  3. Parse the result by finding all the "td" elements with class equal to "parse-error" (which is how Jigsaw reports its errors).
  4. If we find any error, report them. Otherwise, be silent.

After including the widget into our EGL Rich UI application that uses the bad CSS, we now see an error message appear automatically when we run the application:

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1112-1190/css-error.png

The widget itself defines a VEWidget annotation, so you can easily drag and drop it from the palette in the visual editor (make sure to hit the "refresh palette" button on the design toolbar). Here is how the widget can be used:

handler CSSErrorsDemo type RUIhandler { 
		initialUI = [ validator ], 
		includeFile="css/bad.css" // located in WebContent directory!
	}
	validator css.CSSValidator{};
end

The actual widget is shown below. Copy it to your workspace, feel free to rename the package name. Let me know when you find any problems with it.

1 Comments Permalink
1

Many EGL Rich UI applications are migration targets from a legacy desktop application developed in VisualAge Generator, PowerBuilder, VisualBasic, or similar technologies. Personally, I think menus have no place in web2.0 applications. Just go find the menubar in gmail, or in Google Finance. They're not there. However, if you have to maintain superficial compatibility between the old application and the new one, and you really need a menu, EGL Rich UI comes with a powerful menu solution that lets you completely customize and style your menu.

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1130-1303/ourmenu.PNG
Those of you who are already dabbling with menus will discover they are hard to use in the RBD. What is happening here is that our Text UI and Rich UI technologies are fighting over the same types being available for lookup. Namely, we automatically include the Text UI's Menu and MenuItem on the search path. This is for historical reasons. We are looking at IDE solutions to better separate the search paths, without ruining the lives of existing CUI programmers. For now, if you use menus in EGL Rich UI, simply write the import statements by hand. Ctrl-Shift-O, nor Ctrl-Space, will introduce the import statements automatically.

Anyway, back to the power of menus. With all the flexibility that comes with the menus, allowing you to attach behaviors, etc, a price is paid for ease of use. When Jon Sayles and I talked about his upcoming Rich UI training materials he is working on, he mentioned the need for a simpler menu. One with just text, and one event handler. One that is not so flexible perhaps, but one that works quickly.

What you will see below is a Menu implemented using our general solution, including defining a behavior to set styles and handle events. Rather than setting up the menu with MenuItems, and gobble together the entire menu, I tried to make the declaration as simple as possible, using just an array of String. It limits what the menu can do. It has no sub-menus, and no icons in the menu, and all menu item elements look the same. Imagine a virtual slider with on the left side ease of use and abstration, and on the right side full detail with maximum power. SimpleMenu sits way on the left. Our Rich UI menu solution sits way on the right. You may come up with a menu solution called IconNestedMenu that sits somewhere in the middle. I find that aspect of software design the most intriguing: where to put your solution on that imaginary slider.

To create a SimpleMenu, you say the following:

    menuBar SimpleMenuBar { 
        listeners ::= menuSelected, 
        menus = [
            "File", [ "New", "Open...", "Import...", "Export...", "Print..." ], 
            "Edit", [ "Cut",  "Copy", "Paste" ],
            "Help", [ "Welcome", "Search", "About..." ]
        ]
    }; 
 

You specify one or more listeners, and introduce each menu (we add three menu in this sample). Each menu has a number of options that will be shown when the menu is activated. This is what the menu will look like:


http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1130-1301/menu.png
The menubar is grey, and the menus are white. When the mouse is hovered over a menu title or menu item, the background turns to a shade of blue. We handle a few extra events to hide the menu automatically, and close existing menus when hovering to another one on the menubar.

When a menu item is selected, the SimpleMenu will trigger the listeners that have registered:

    function menuSelected(menu String in, item String in)
        case (menu + ">"+ item)
            when ("File>New") 
                WriteStdOut("Create a new File!");
            otherwise
                WriteStdOut("Select: '" + menu + "' , '" + item + "'");
        end
    end

All styling for the menubar and the menu items is done in CSS, so you can control the look and feel easily. This is what the CSS looks like originally:

.EglRuiSimpleMenuBar {
	font-family: Arial;
	background-color: #cccccc;
	line-height: 1.4em;
	font-size: 0.9em;
}

.SimpleMenuTitle {
	padding: 0px 8px 0px 2px;
	background-color: #cccccc;
}

.SimpleMenuItem {
	background-color: white;
}

.SimpleMenuTitle:hover, .SimpleMenuItem:hover {
	background-color: #5a9bd1;
}

.SimpleMenuOptionsBox {
	background: white;
	border: 1px solid gray;
	border-width: 0px 2px 2px 0px;
}	

Changing the look and feel is easy. For instance, if you change the background color to the menu title and item to this:

.SimpleMenuTitle:hover, .SimpleMenuItem:hover {
	background-color: orange;
}

you will get this result:


http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1130-1302/menu-orange.png
The implementation of SimpleMenu uses the existing Rich UI menu, adds a behavior to it, and converts our simplified list of menu item strings into instances of MenuItem and set up the menu.

When a SimpleMenu is created, we use the exsiting menu and set up a behavior:

private menu Menu { menuBehaviors = [ highlightMenu ]};

The hightlightMenu behavior function is called by the Rich UI menu each time a menu is created and allows us to customize the menu as we see fit. In our case, we set up event handlers and styles on the menu as follows:

private function highlightMenu(menu Menu in, titleBar Span, optionsBox Box, options MenuItem[])
    menu.onMenuOpen = menuOpened;
    titleBar.class = "SimpleMenuTitle";
    optionsBox.class = "SimpleMenuOptionsBox";
    titleBar.onMouseOver ::= enterTitle;
end

When we move the mouse around and enter a menu item, we want to show it and also close any menu item that is already open. The enterTitle function takes care of that:

private function enterTitle(e Event in)
    InfoBus.publish("simple.menu.enter.title", menu);         
end

private function switchTitle(event String in, menuOpened any in)
    if (menuOpened != menu)
        menu.hideOptions(false);
    else
        menu.showOptions();
    end
end

The enterTitle function is called whenever the mouse enters a menu item. We now want to inform all the other menus to close themselves. To avoid us having to go back to the menubar and ask it to close the other menus for us, we use the InfoBus to generate an application level event that is broadcasted to all the other menus.

During the SimpleMenu construction we register an InfoBus listener as follow:

InfoBus.subscribe("simple.menu.enter.title", switchTitle);

As a result, each menu will be informed when it should close itself. This is how numerous menus can talk to each other without needing a third party to help out in the communication.

Anyway, try out the SimpleMenu, and feel the power of our Menu architecture allowing you to fully customize the menu's look and feel.

1 Comments Permalink
Bottom Banner