Announcement:

New version of EGL Dojo widgets now available! by will.smythe at Nov 18, 2009 6:21 PM

A new version of the EGL Dojo widgets for Rational Business Developer is now available! This new version includes many bug fixes and a few new widgets.
View the live gallery or download code

Announcement:

Accelerating Modernization of CICS with EGL Rich UI event on December 15 by will.smythe at Oct 20, 2009 10:17 AM

Join us for a 1/2 day virtual event on extending and modernizing CICS applications with EGL Rich UI and Web 2.0 techniques. More information

Blog Posts

Statistics: Blogs: 14 Blog Posts: 124
Items per page Filter: 1 2 3 ... 9 Previous Next
0

When developing Rich Internet Applications, it is important to make the applications accessible to everyone. Due to the fact that EGL Rich UI applications are generated into standard HTML and Javascript, the applications comply with accessibility standards and can be used with utilities such as screen readers, etc. The following are some specific details on working with screen readers, tab indices, and relative sizes in an EGL Rich UI application.

Screen Readers
When working with widgets that map directly to basic HTML controls (e.g. button, checkbox, etc), no additional work is required to enable a screen reader, as the readers are already able to interpret standard HTML tags. In addition to the basic widgets provided by the HTML specification, Rich Internet Applications commonly contain more complex widgets that are rendered using generic HTML tags such as the DIV tag. To make these complex widgets accessible to a screen reader, the W3C organization has defined the Accessible Rich Internet Applications (WAI-ARIA) specification (http://www.w3.org/TR/wai-aria/). This specification defines the 'Role' attribute for all tags, which can be used to instruct a screen reader on how a widget should be interpreted (e.g. "checkbox"). All widgets found in an EGL Rich UI application contain the fields "ariaRole", which can be used to instruct a screen reader on how to interpret the widget.

An example application that uses the "ariaRole" field is provided as part of the attached project, in the file AraiaRoleDemo.egl.

Another common aspect of Rich Internet Applications is the usage of widgets that update their content as the application is running, without re-rendering the entire page (e.g. stock prices, etc). To support these widgets, the ARIA specification defines the 'Live' attribute, which can be used to instruct a screen reader to re-read a widget's content after it has been updated. All widgets found in an EGL Rich UI application contain the fields "ariaLive", which can be used to instruct a screen reader on how often to re-read a widget after its content has changed.

An example application that uses the "ariaLive" field is provided as part of the attached project, in the file LiveRegionDemo.egl.

Tab Index
When developing an application, it is important to consider a user that does not have a mouse or other pointing device. To support these users, the application should enable tabbing so that the application can be used with only a keyboard. All widgets found in an EGL Rich UI application contain the field "tabIndex", which can be used to indicate the Tab order for the widget in the running application.

An example application that uses the "tabIndex" field is provided as part of the attached project, in the file TabIndexDemo.egl.

Relative Sizes
When developing Rich Internet Applications, it is a good idea to size elements using relative values, so that the application will render correctly on different size monitors or at different resolutions. To specify that a widget should take up a certain percentage of the screen in an EGL Rich UI application, you can set size attributes using a value with a percentage (e.g. width = "50%").

Font sizes should also be specified using relative units (e.g. em) instead of fixed units (e.g. px), so that the browser can adjust the font size to the users preferences. You can specify font sizes with different sizes and units (e.g. em, pt, etc) using the "fontSize" attribute found on all widgets in an EGL Rich UI application.

An example application that uses relative sizes and units is provided as part of the attached project, in the file RelativeSizeDemo.egl.

Note: The attached project, AccessibilityDemo, requires the com.ibm.egl.rui_1.0.2 project.

Attachment: AccessibilityDemo.zip

0 Comments Permalink
0

EGL programs are transformed (we call the process "generation") to Java, COBOL, or JavaScript programs for deployment in a target runtime environment.

If performance of the generated program is significant to you, then it is important to understand the performance characteristics of EGL syntax alternatives in the different runtime environments.


A new white paper, EGL Best Practices: Coding For Performance, provides insight into this topic for EGL programs destined for Java or COBOL environments.

Please feel free to use this document. Comment on information that you feel was especially important to you or point out issues or scenarios that you would like addressed with more detail.

0 Comments Permalink
0

Today we released the (0.7.1.1) EGL Dojo Widgets for RBD 7.5.1.4. These are the same widgets that were released in the EGL Community Edition (CE), just for RBD. Not to worry though, from this point forward all releases of EGL Dojo Widgets will work in both RBD and CE. We also made available a great Gallery Sample showcasing all Dojo widgets in a single sample! Take a look at it here.

Our apologies for this, but any existing EGL applications using the 0.6.0 version of the Dojo Widgets will most likely require changes to bring them forward. That said, the current API has been firmly defined and will not experience significant changes in future releases.

To download the EGL Dojo Widgets for RBD click here. Be sure to also take a look at the great documentation attached to the page to get a feel for the API.

0 Comments Permalink
11

(updated for V7.5.1.4 and 7.1.0.4 - 11/10/09)

A question I frequently get is what is the current maintenance is for the Rational COBOL Runtime for z/Series V6.0.1 product. Well the answer is it depends on what level of RBD you are using. Here is the list of PTFs by RBD release and the minimum PTF per release. Note that all have to be installed, up to the level of RBD you are using.

Also, the support website has now been updated as well. See:

Rational COBOL Runtime PTF List

and

For RBD in general:

RBD Fixes by Version

Level / PTF #


v6010 : /
v7000 : UK24108
v7100 : UK29575
v7101 : UK40726
v7102 : UK42718
v7510 : UK42740


V7511: UK43754
V7512: UK45676
V7513: UK46879


V7104: UK48413

V7514: UK51729 <-- This PTF will support all other levels of EGL as well (V7.5 .x and


with these important install notes

* UK24108 requires that the base product is accepted
  • UK24108 and UK40726 must be applied in two different steps
    (doing both in the same steps breaks SMP/E and the product must be installed again

11 Comments Permalink
4

Fix pack 7.5.1.4 is now available. It includes fixes in many areas of the
product, as well as significant runtime performance improvements in both Java and COBOL environments. Everyone using RBD 7.5.x should install it. See IBM Rational Business Developer 7.5.1.4 Release Information for more info, including installation instructions and the list of APARs which are fixed. The download instructions are here.

If you generate COBOL for System z, you should also install PTF UK51729.

Rational Business Developer version 7.5.1.4 includes these enhancements:

  • Improvements in COBOL runtime performance affect the following kinds of processing:
    data-table access, dynamic-array access, assignments, SQL statements,
    exception handling, calls, string handling, and other memory usage. Consider re-generating existing applications, especially if they access SQL databases extensively or access data tables.
  • Improvements in Java runtime performance affect the processing of system libraries
    sysVar, vgVar, and converseVar. Re-generate existing applications only
    if you notice a problem with performance.
  • An EGL-generated Java wrapper can now call an EGL main program that is
    generated to Java and can share a database connection with that
    program.
  • EGL-generated Java code and the EGL debugger can now access z/OS batch programs and DL/I databases.
  • A new preference exists to change the behavior of SQL Retrieve at
    development time, so that you can define EGL fields of type CHAR in
    relation to SQL table columns that are of type DATE, TIME, or
    TIMESTAMP. The new preference is Use EGL type char for SQL date, time, and timestamp in SQL Retrieve.
  • The sysvar.remoteSystemID function can be used to dynamically specify the
    system name of a remote program, data file, asynchronous transaction,
    or transient data queue. The function now supports 256 characters if
    the EGL code is generated to Java.
  • In regard to COBOL or Java generation, the new blanksAsZero
    build descriptor option helps control the runtime behavior when a
    program assigns text to a numeric variable. The default value is NO,
    which matches the previous behavior for Java generation. If you
    generate COBOL and currently set v60NumWithCharBehavior to NO, you should also set blanksAsZero to YES if the program compares character data to numeric data.
  • Several new COBOL symparms are in place; for example, WRITEFUNCTIONDETAILS and WRITESTATEMENTDETAILS support the debugging of EGL-generated CICS COBOL programs.
  • The Rich UI widgets were upgraded to version 1.0.2 and now match those that became available in EGL Community Edition.
  • JavaScript code is now compressed when you deploy Rich UI code in the Workbench. Re-deploying existing Rich UI applications significantly reduces the size of the application code.
  • In relation to widget-type creation in Rich UI, the @VEWidget complex
    property now includes a field named container. If you create a widget
    type and indicate that it represents a container, an EGL developer can
    place a container on the Design surface, drag a widget of another type
    from the palette, and drop that widget into the container.
  • An EGL-generated VG Web transaction can now call another with parameters,
    such that the called transaction can interact with the browser. This
    capability is available if the target for each Web transaction is a
    Java platform. Also, you can use a new program property, enableJ2ee, to
    specify whether a VG Web transaction that runs completely in a JEE
    application server uses these JEE capabilities: data sources rather
    than direct database connections, and the JEE deployment descriptor
    rather than a Java properties file.
  • The JSONName property can be used to copy a JSON string to or from a
    record, when the JSON field name is an EGL-reserved word or is not
    valid in EGL. Similarly, the FormName property is available when you
    develop an Interface part for accessing a service and are prevented
    from sending form data to the service because a field name in the form
    is not valid in EGL.

Enjoy!

4 Comments Permalink
0

Rational Business Developer (RBD) and EGL Community Edition (EGL CE) both allow you to more easily develop Web 2.0 applications using a single language, EGL. With EGL, you can create a rich internet application (RIA) without having to learn a multitude of technologies like JavaScript, Java, HTML, or PHP. To develop RIAs using RBD or EGL CE, you write your application in EGL, and the tool generates JavaScript and Java. You'll need RBD, the enterprise level big brother of EGL CE, if you want to create COBOL, JSF, text or console applications.

If you have been using Rational Business Developer (RBD), you'll notice a few things are different in EGL CE. First, you'll probably notice that EGL CE has a single EGL perspective. For developing EGL, there is a single EGL editor that determines whether to show the Design and Preview tabs based on the content of the file opened. To create an EGL project, you are required to enter only a project name. Because it combines features from the General and Rich UI project types from RBD, a single EGL CE project can contain Rich UIs, Web services, or both. By default, each EGL CE project depends on the EGL Rich UI widget project and a Dojo runtime project. Simply drag-and-drop any of the widgets from the palette onto the visual editor in Design view. Use the Properties view to customize each widget and define events.


Like RBD, you can use EGL CE to code, preview, and debug RIAs before you deploy them to an application server. In EGL CE, services can be tested in Preview or debug using the service's source code if it's in your workspace or using the deployed version for existing services. Being able to see your application in action using Preview and Debug, make quick changes, and test again speeds up the development process a lot. Once you're happy with your application, you can deploy it.


Deployment in EGL CE is somewhat different too. EGL CE removed the need to switch between deployment and development modes since code is automatically generated for debug and target deployment (see the EGL CE Project Structure and Code Generation blog). For deployment in RBD, you select a single Rich UI handler to serve as the entry point to your application. In EGL CE, you can better control how your application is deployed using the Deployment Descriptor editor. By default, all Rich UI handlers create an HTML endpoint for each specified locale in EGL CE. You can edit the application's deployment descriptor (.egldd) to pick each Rich UI handler you want to have an HTML endpoint, and therefore you control the entry point URLs for your application. In the deployment descriptor, you can also determine what types of services to create such as SOAP or REST, and the service client bindings that tie your front-end user interfaces with the back-end services. Each deployment descriptor has one Web project as the target. If you want parts of your application to run on different targets, you can create multiple deployment descriptors, for example a descriptor to deploy Rich UIs to one target and another descriptor to deploy services to a second target. Currently, EGL CE supports deployment to Apache Tomcat.


So if you want to develop Web 2.0 applications quickly and efficiently, try EGL CE. We think learning a single language like EGL will make your life easier, as well as reduce the strain on your bookshelf since you won't need a bunch of reference manuals. And it's free, so you can try it without asking your boss for a purchase order.


And remember, the C in EGL CE stands for community. We encourage comments and feedback from you, the EGL community. Feel free to ask questions in the forum, comment on blog posts, or contact us to write a blog post yourself. Let us know what you think! We'd love to hear from you.

0 Comments Permalink
0

In EGL CE you are able to debug both the Rich UI front-ends, as well as the Service back-ends. All debug sessions must begin with the Rich UI application. There are several ways to initiate a debug session, such as right-clicking a RUIHandler file and selecting Debug EGL Rich UI Application:

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1271-1763/blog1.png

Or if you have the editor open, switch to the Preview tab and click on the Debug icon:

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1271-1771/blog2.png

Once your debug session begins, the Rich UI application will be loaded in an external Web browser. Your default system Web browser will be used, but this can be changed in Window > Preferences > General > Web Browser.

Another preference page worth mentioning is EGL > Debug. The EGL CE help system has detailed descriptions about the debugger preferences, as well as which preferences apply to Services and which apply to RUIHandler parts.

If you're not familiar with developing in Eclipse, breakpoints can be added to your EGL source files by double-clicking inside the left margin of the source editor. If a breakpoint marker doesn't appear, that means it's not a valid location for a breakpoint. You can also right-click inside the left margin to add/remove/disable breakpoints.

As an example, let's use the ServiceDemo.egl sample, inside project com.ibm.egl.rui.samples.ce. Place a breakpoint at line 59, which is the first line of function sayHello. Now start the debug session for this handler. After the page is loaded in the external browser, enter your name and click the Say Hello button; the EGL CE workbench should be activated and you'll be prompted to switch to the Debug perspective. Click OK, optionally checking the box to automatically take this action in the future, and you should see the following:

blog3.png

I have highlight two sections in the screenshot above.

Section 1: The Debug view contains the debug stack, which is the stack of funtions currently being executed, and is only visible when you're suspended. The toolbar in this view can be used for the typical debugging commands: step into, step over, step return, resume, terminate, and suspend.

Tip: If you accidentally coded an infinite loop, or something is taking an incredibly long time to execute and you're curious why, you can click on the suspend button blog8.png to pause the debugger. If no code is currently running when you click suspend (e.g. browser is waiting for a user event), then the debugger will immediately pause the next time any of your code is run.

Section 2: The Variables view will display all the variables currently in scope. The variables have been divided into two sections: Global variables ("ServiceDemo" in the screenshot) and local variables ("sayHello" in the screenshot); these will be the name of the main part and the name of the function, respectively.

The Breakpoints view displays all the breakpoints in your workspace. One thing worth noting is you can disable breakpoints without deleting them, and there's also a "Skip all breakpoints" option that you might find quite useful.

Tip: Hover the mouse over a variable that's in scope while suspended, and you'll get a tooltip containing its value:


http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1271-1772/blog4.png


Picking up where we left off in our example, click on the resume button http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1271-1767/blog5.png to continue execution. You'll be presented with a popup dialog; this dialog is presented when a Service invocation via an Interface part is encountered.

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1271-1768/blog6.png

If you have the source code for the target service in your workspace, and you want to be able to step through its code, specify "Use source code", otherwise specify "Use deployed version". If you are invoking a deployed service, then you will need to make sure your EGL deployment descriptor contains a Service client binding which provides information on how to reach the Service. If you don't want to be prompted again for this binding key in the future, you can check the box to save your decision.

Now would be a good time to set a breakpoint in the Service part. Put a breakpoint on line 18 in SayHelloService.egl, which is the first and only line of function hello. Click OK and you should be suspended inside the Service, which runs as a separate process. Click on the resume icon like before and the Service will complete, returining a string back to the Rich UI client.

Tip: You can step into a Service invocation just like you would step into a function. This will kick off the service and immediately continue to the next line of the Rich UI code. The Rich UI code can be run in parallel with the Service code, since they are in separate processes, and the Service callback function (or error function) will be run once the Service completes and the Rich UI function stack is empty.

After the Service has returned data to the client, switch back to your browser to see the results:

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1271-1769/blog7.png

Feel free to login and add a comment or question about the debugger.

Justin

0 Comments Permalink
4

While you are developing your EGL project, you can run it using the Preview tab and using the debugging tools. You can even try out services that you have written or ones from third parties. Testing your application this way saves a lot of time and effort over other development tools that require you to deploy to confirm any changes behave as you expect.

When you are satisfied with your application, you can deploy it to a Web application server such as Apache Tomcat version 6. EGL projects aren't directly deployed to an application server; EGL projects are deployed as dynamic Web projects. EGL source code is generated as Java and JavaScript in the Web project.

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1268-1747/deploy.gif
To create your target Web project, open the deployment descriptor file (.egldd) located in the EGLSource directory of your EGL project. The deployment descriptor specifies where to deploy - the target Web project (including the target runtime server), and what to deploy - the Rich UI handlers and services.

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1268-1750/Deploydescriptor.JPG
In the deployment descriptor editor, click New next to the Target name field to open the New Dynamic Web project wizard. Enter the name of your Web project. Select Apache Tomcat v6.0 as the target runtime. If you haven't created a server, you can click New next to the Target runtime field, which opens the New Server Runtime Environment wizard. Select Apache Tomcat v6.0 from the list of servers and click Next. If you have Tomcat installed, you can browse to the installation directory. If you don't have Tomcat installed, you can click Download and Install, accept the license agreement, and click OK. (Note: watch the lower right-hand corner of the workbench for progress. If for some reason you get an error, I recommend going to the Apache site and downloading and installing Tomcat then just point to it.)

After you enter the target Web project, you can specify what to deploy. By default, all Rich UI handlers are listed to deploy, meaning each handler generates an HTML file for each locale specified. If you don't want an HTML endpoint created for a particular handler, since you might not want users to be able to go directly to that URL, click the Rich UI Deployment tab and select which handlers you want to deploy. If you have EGL services that you want to expose as Web services, add them under the Services Deployment tab. We have more on services in a later blog post.

When you finish editing the deployment descriptor, save it. To deploy to the target Web project, click the Deploy the EGL descriptor icon on the top right of the editor window or right-click on the .egldd file and select Deploy EGL descriptor from the menu.

You can view the results in the EGL Deploy Results tab near the bottom of your workspace. Your target Web project should contain JavaScript and Java generated from your source EGL project. For instance, if your EGL project had a Rich UI handler that you selected to deploy, you should see a corresponding HTML file in the WebContent folder. To see the application in action, right-click on the HTML file, select Run As>Run on Server, and select Tomcat 6. The server will start and the file should open running on localhost (or the hostname you specified).

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1268-1751/RunAs.JPG

Deployment descriptors let you customize the deployment of your EGL applications. You can create more than one deployment descriptor for each EGL project. For instance, you may want to specify a Web project to deploy your Rich UI handlers and a second one to deploy your services. Each descriptor can be deployed individually (using the Deploy EGL descriptor option) or all at once by right-clicking on the EGL project name and selecting Deploy EGL project.

We hope this helps you understand some of the basics of deploying EGL projects to the Web. We would love to see your EGL applications out there!

Theresa

4 Comments Permalink
10

I have posted a video walkthrough demonstrating how to call an RPG program using EGL Community Edition. The video is available here. (Make sure you watch in full-screen, HD mode.)

Using this video you can learn:

  • Setup steps required to call RPG from EGL/CE
  • Construction of a service to call the RPG program
  • Construction of a Rich UI to invoke the service
  • Debugging client and service code

I welcome your questions and feedback.

10 Comments Permalink
2

Today, I wrote a game in EGL Rich UI inspired by the well-known web game called "Escape", "Escapa", "The Red Box Game", or whatever name the latest inspired copier decided to give before hosting it on their own homepage. I am still trying to find out who really wrote the original.

Anyway, it looks like this:

escape.jpg
See http://eglplanner.com/escape

The intent of the game is simple. You drag the red box labelled "EGL" around with your mouse. All you need to do is avoid the blue boxes and the walls.

How does the game work?

The game essentially consists of two parts: the UI that draws the boxes and let you drag the red box and a service component that can show the top 10 scores. I will describe the two parts in more detail now.

How to avoid Java, C, PHP, and JavaScript

The main algorithm for this game is the following:
  • place a red box in the middle and allow the user to drag it
  • place four blue boxes elsewhere and give each a unique motion vector
  • start a new job to run each X milliseconds to move each blue box
  • when the red box goes outside the white box or overlaps with a blue box, stop
  • every 10 seconds decrease the value of X so the blue boxes will move faster

The blue boxes shown in the UI are positioned absolutely using a syntax like this:
    new Div {
        position = "absolute", x = 300, y = 330, 
        width = 100, height = 20, 
        color = "white", background = "navy", font = "Arial", 
        innerHTML = "<center style='margin-top: 1px'>JavaScript</center>"        
    }


By making the boxes positioned absolutely, we can place them at any place we want. For this box, the initial location is at x=300 and y=330.

Each time the game timer goes off, we move the blue boxes in a given direction:
    moveEnemy(enemies[2], -12, -20);


For each blue box, we remember its x and y direction. For instance, when it bounces against the right wall, we make its x direction -1. The box is moved simply by giving it a new x and y coordinate. After moving the box, we check to see if we now touch the red box. If so, we stop the game.
    function moveEnemy(enemy Div, x int in, y int in)
        directionX int = enemy.getAttribute("directionX");
        directionY int = enemy.getAttribute("directionY");
        if (touchesVerticalWall(enemy))
            directionX *= -1;
            enemy.setAttribute("directionX", directionX);
        end
        if (touchesHorizontalWall(enemy))
            directionY *= -1;
            enemy.setAttribute("directionY", directionY);
        end
        enemy.x += x * directionX;
        enemy.y += y * directionY;
        if (enemyTouches(enemy))
            stop("a blue box");
        end
    end


The red box itself has drag and drop handlers define on it:
    red Div {
        onStartDrag = startDrag, onDrag = drag, onDropOnTarget = endDrag, 
        cursor = "pointer", 
        position = "absolute", x= 205, y = 205,    width = 40, height = 40, 
        background = "darkred", color = "white", font = "Arial",
        innerHTML = "<center style='margin-top: 9px'>EGL</center>"
    };    


This allows us to start the game and drag the red box while the user moves the mouse:
    function startDrag(widget Widget in, x int in, y int in) returns(boolean)
        dx = x - red.x;
        dy = y - red.y;
        start();
        return (true);
    end
    function drag(widget Widget in, target Widget in, x int in, y int in)
        if (!stopped)
            red.x = x - dx;
            red.y = y - dy;
        end
        if (outsidewhite())
            stop("the black border");
        end
    end
    function endDrag(widget Widget in, target Widget in, x int in, y int in)
    end


Finally, when the game stops, we inform the user and display the top 10 scores:
    function stop(reason String in)
        message.text = "You touched "+reason+". Drag the red box to start.";        
        reset();
        stopped = true;
        top10.score = (browser.currentTimeMillis() - startTime)/1000;
    end


Keeping a Top 10 List

Our top 10 list consists of a little bit of UI, and a service call to report the current score and receive an answer back with the total number of games played and the top 10 games.

The UI is nothing thrilling, other than using a cookie to remember your name:
    nameLabel TextLabel { text = "Your Name: " };
    cookie Cookie { key = "name" };
    nameField TextField { width = 80, text = cookie.value, onKeyUp ::= setName };


That same cookie is updated when the user enters a new name, and stored in the browser's cookie jar. Next time the user returns, the stored value will be automatically picked up. Updating a cookie value is as easy as giving it a new value:
    function setName(e Event in)
        if (nameField.text != "")
            cookie.value = nameField.text;
        end
    end 


The service calls a REST service with 2 URL parameters. It returns a record with inside it an array of top scores. Notice from the definition below that it is not relevant if the service is using XML or JSON to encode its contents. The EGL runtime will determine at runtime how to parse the result.

The service definition looks like this:
    interface HighScores
        function getTop10(name String in, score float in) returns(HighScoresRecord) 
           {@GetRest {
                   uriTemplate="http://eglplanner.com/escape/highscore.php?name={name}&score={score}"
           }};
    end    
    record Result
        total int;
        top10 ScoreRecord[0];
    end
    record Score
        name String;
        value float;
    end


To call the service, we use the EGL call statement identifying the service we want to call and what function we want to use when the response arrives in the future:
    function setScore(score float in)
        this.score = score;
        scoreField.text = "Score: "+score;
        call svc.getTop10(nameField.text, score) returning to handleTop10 onException ServiceLib.serviceExceptionHandler;
    end


The top 10 scores are stored in a div that is given an opacity of 0.8, so it is a little bit transparent:
    top10 Div { 
        position = "absolute", x = -100, y = 5, 
        *opacity = 0.8*, padding = 10, background = "black", 
        borderColor = "red", borderWidth = 12, borderStyle = "solid" 
    };


When the answer comes back from the top10 service it is converted automatically by EGL into a set of nested records and we simply add them to our top10 div. Finally, we show the top10 div in the right position:
    function handleTop10(result HighScoresRecord in)
        s String = "Total plays: <b>"+result.total + "</b>. " +
            "Your score: <b>"+score+"s</b>.<p>" +
            "Here are the Top 10 scores:

" + "<table border=1 width=300 cellpadding=3 style:'margin:10px; opacity: 1.0'>"; for (n int from 1 to result.top10.getSize()) score ScoreRecord = result.top10[n]; s += "<tr><td>" + n + "</td><td>" + score.value + "s</td><td>   " + score.name + "</td></tr>"; end s += "</table>"; top10.innerHTML = s; top10.x = scoreField.x + scoreField.pixelWidth + 15; ui.table.setAttribute("valign", "top"); showTop10(true); end function showTop10(value boolean in) if (value) ui.appendChild(top10); else ui.removeChild(top10); end end



Using PHP to implement the backend service

All the client code is done in EGL. I decided to place the game on an ISP where I took the cheapest plan available. The plan comes standard with PHP and MySQL. So, I decided to try and use MySQL and PHP to store the high scores to see how that worked.

The MySQL table structure is pretty simple:
    name    varchar(64)           
    score    float          
    ip        varchar(32)


I added and IP field to remember where the service came from (which is of course a very limited approach to authentication). I created the table using the phpMyAdmin client that my Internet provider offers.

Then I wrote some PHP and placed it right next to my game's index.html file. Here is what the (insecure) PHP looks like:
<?
   $host = "localhost";
   $user = "*********";
   $pass = "*********";
   $db      = "highscores";

   $name = $_REQUEST['name'];
   $score = $_REQUEST['score'];
   $ip = $_SERVER['REMOTE_ADDR'];

   $connection = mysql_connect($host, $user, $pass) or die ("Unable to connect!");
   mysql_select_db($db) or die ("Cannot open database $db");
 
   if (isset($name) && isset($score)) {      
      $query = "INSERT INTO highscores(name, score, ip) VALUES('$name', '$score', '$ip')";
      $result = mysql_query($query);
   }

   $query = "SELECT * FROM highscores";
   $result = mysql_query($query);
   $total = mysql_num_rows($result);
   $query = "SELECT * FROM highscores ORDER BY score + 0 DESC LIMIT 10";
   $result = mysql_query($query);
   echo "<result><total>$total</total>";
   if (mysql_num_rows($result) > 0) {
      while($row = mysql_fetch_row($result)) {
         echo "<score><name>$row[0]</name><value>$row[1]</value></score>";
      }
   } 
   echo "</result>";
   mysql_close($connection);
?>


Security

My PHP code is highly insecure for various reasons. First, anyone can simply call the URL above and assign any score they like:

Hack your own score

Note that I added some sanity checks so that the above URL no longer works :-)

Using a REST service with URL parameters makes it trivial to call in a browser. Tools like Rational AppScan know this and run a huge number of "worst practice" scenarios on a website to find holes like the one I inserted here.

Some ways of making service hacking more difficult would be:
  • Use a POST and place the arguments in the message body, instead of on the URL.
  • Use some "secret" encoding for the message that only the client and the service know about.
When you use SOAP messages, you already use POST and a secret encoding (in this case a SOAP envelope).

One complicating problem is that our client is written in easy to read JavaScript (compiled from our EGL). That gives hackers a lot of leverage. However, even extreme obfuscation of the JavaScript won't help as hackers can easily use Firebug in Firefox to watch the network traffic and derive what services are used and how to call them. Then they can play the man-in-the-middle game to make the server believe they are the client.

Maybe JavaScript obfuscation combined with service obfuscation has a higher degree of chance of making hackers give up and look for an easier target to hack.

Of course, obscuring thing stops the really silly hacks and even the accidental ones. However, as Andy Tanenbaum used to say when I was stil back in school attending his class on Operating Systems: obscurity is the worst form of security.

Always use SLL and proper authentication to increase security.

Securing the channel and authentication helps to a certain degree. In the end, however, services have to be extremely defensive, paranoid, trace everything, apply statistical analysis, and allow for easy human intervention. Think of your credit card company calling you on your cellphone to verify a suspicious transaction. Also, most comment sections on website have a button to report spam messages or abuse. Any system that runs over the Internet should be assuming the worst and be able to easily recover from abuse.

SQL Injection

One special form of disruptive hacking is to try and make the service run arbitrary code on the hacker's behalf. In our PHP example shown above, we allow for SQL injection very easily.

Then main attack vector in our example is given here:
   $name = $_REQUEST['name'];
   $score = $_REQUEST['score'];
   ...      
   $query = "INSERT INTO highscores(name, score, ip) VALUES('$name', '$score', '$ip')";


We retrieve $name and $score from the request URL, and compose a query out of it. If we pass in 'name=Chris' and 'score=32.351', the resulting query would be:
    INSERT INTO highscores(name, score, ip) VALUES('Chris', '32.351', '192.168.0.1')";


Now, assume someone passes the following parameters to the REST service:
    name=x',1,foo); DROP TABLE highscores; --


Our query would then look like this:
    INSERT INTO highscores(name, score, ip) VALUES('x',1,foo); DROP TABLE highscores; --', '32.351', '192.168.0.1')";


As "--" starts a comment in SQL, the query now becomes the following two separate SQL statements:
    INSERT INTO highscores(name, score, ip) VALUES('x',1,foo); 
    DROP TABLE highscores; 


By naively allowing any arguments to be passed to us we allowed random SQL code to be executed on our database. Hackers do not need access to the PHP to come up with this, as automated tools are available to try random fragments until they find one that works.

The simplest solution is to not allow for the script to insert the ';' character. Namely, without that the SQL injection cannot insert a second statement. To avoid further unintentional modifications to the original select statement, we can also check for the single quote character.

To help fight SQL injection, there is a simple PHP trick to sanitize URL parameters. It looks like this:
   $name = mysql_real_escape_string($_REQUEST['name']);
   $score = mysql_real_escape_string($_REQUEST['score']);


I added that to the PHP that is currently used by the published game.

Monitoring

In our sample above, we do not monitor client access, other than storing the IP address. Additional information may be collected and stored, such as host name, referer page, browser agent, timestamp, etc. Basically, you should record anything that may help the FBI solve your case once someone drained your server from all its data.

How to really solve security problems

Basically the advise is: Don't try this at home, kids!

Enterprise organizations should not use adhoc security models, of course. The recommendation is to use something like Tivoli Access Manager to control access to, and monitor, their services.

Furthermore, instead of using PHP, you should really write your services in EGL, compile them to Java, and run them on WebSphere, which is proven to be much more secure for Enterprise applications. Using EGL will also make it easier for you to write the service as you will not have to struggle with the quirky syntax of both PHP and MySQL.

Download

To take a look at the client code yourself, download the following attachment and import it as an existing project into your workspace.

Attachment: escape.zip

2 Comments Permalink
9

Why Portals?

One of the most inspiring video games I have ever seen is the Aperture Science Enrichment Center, also known as Portal. It bends the law of physics in very interesting patterns:

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/1735/portal.jpg
Image/article source: Wired Magazine

Now, I am kind of tricking you, as this is not the kind of Portal this blog entry will discuss. However, I cannot help thinking of this game whenever someone asks me if you can do "portals" in EGL Rich UI.

So seriously, when people ask me about Portals there are asking two different questions:

  1. How can I write an EGL Rich UI application and use it inside a WebSphere Portal? In essence a Rich UI application is really an HTML file with some JavaScript embedded inside it. That can be produced by a JSR 286 portlet. We may have time to dive deeper into that in a future blog. What I really want to discuss is the next question...

  1. How can I write a Rich UI application that has a main Rich UI handler and that downloads other RUI handlers on demand and make them appear as being a integral component of the larger application. In other words, how can I make a client-side Portal? That question is really the topic of this blog entry.

How to build a client-side Portal?

Our starting point is the GadgetContainer sample that comes with EGL CE and that can be found in the Dojo samples project that EGL CE automatically creates for you:

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/1736/GadgetContainer.jpg
First step is to reduce that sample to something a bit simpler, and then use other applications (preferably done in EGL Rich UI) to occupy the various portlets.

Here is our most reduced version of our Portal:

Handler Portal Type RUIHandler{ initialUI = [ ui ] }    
    ui GadgetContainer { columns = 2, columnWidth = 150, gadgets = [
        new Gadget { title = "Portlet1", column = 1, children = [] },
        new Gadget { title = "Portlet2", column = 2, children = [] },
        new Gadget { title = "Portlet3", column = 1, children = [] },
        new Gadget { title = "Portlet4", column = 2, children = [] }
    ]};
end


This produces a portal with 4 empty portlets:

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1264-1737/portal1.jpg
Now, we will place an iframe into one of the portlets and insert another EGL Rich UI application inside it:

Handler Portal Type RUIHandler{ initialUI = [ ui ] }    
    ui GadgetContainer { columns = 2, columnWidth = 150, gadgets = [
        new Gadget { title = "Portlet1", column = 1, children = [
            new IFrame {
                width = 135, height = 150, src = getURL("Portlet1")
            }
        ] },
        new Gadget { title = "Portlet2", column = 2, children = [] },
        new Gadget { title = "Portlet3", column = 1, children = [] },
        new Gadget { title = "Portlet4", column = 2, children = [] }
    ]};
    
    function getURL(name String in) returns(String)
        pkg String = "com/ibm/egl/demos";
        baseURL String = document.location;
        baseURL = baseURL[1 : strlib.indexOf(baseURL, pkg)-1];
        return (baseURL + pkg + "/" + name + ".html");        
    end
end


We deployed the second application, in this case Portlet1 in the same location as the main handler, so we use the same base URL to compute the URL for the nested handler. The portlet itself works like a standalone application and can be developed normally using EGL CE. Nothing special is required in its implementation:

handler Portlet1 type RUIhandler {initialUI = [ html ] }
    html HTML {
        padding = 2,
        text = 
"This <b>portlet</b> contains <i>just</i> some HTML. That's it.<p>" +


"Visit <a target=_blank href=http://ibm.com>ibm.com</a>."

    };


The portlets can be dragged around, and here is the result after dragging all the empty ones to the second column:

portal2.JPG
Now let's add a more interesting portlet, such as one where two portlets communicate with each other. We will use the EGL InfoBus, which is based on the standard OpenAjax Hub to send messages between the portal and its portlets.

Our second portlet shows an entry field and a button. Here is the source:

handler Portlet2 type RUIhandler {initialUI = [ html, numberField, goButton ] }
	
	html HTML { 
		margin = 7, font = "Arial", text = "Enter a number:"
	};
	numberField TextField { 
		margin = 7, marginTop = 4, onKeyPress ::= checkEnter, text = "2" 
	};
	goButton DojoButton { 
		text = "Go", margin = 7, onClick ::= go 
	};
	subscription any = InfoBus.subscribe("calculator.result", showResult);
  
	function go(e Event in)
		InfoBus.publish("calculator.calculate", numberField.text);
	end

	function checkEnter(e Event in)
		if (e.ch == 13)
			go(e);
		end
	end
	
	function showResult(msg String in, result any in)
		numberField.text = result;
	end

	fix CrossIFrameInfoBusFix{};
end


Notice it is waiting for calculator requests by subscribing to "calculator.result" messages on the InfoBus. Whenever any handler on the current page does a publish with that message key, Portlet 2 will be notified in its "showResult" function. When the user presses Enter or clicks the Go button, a multiplication request is published on the InfoBus again, to be picked up by Portlet 3 (see below).

Our third portlet implements a calculator that multiplies a number with 2. Here is the source:

handler Portlet3 type RUIhandler {initialUI = [ html ] }
    
    html HTML { font = "Arial", text = "Waiting for Portlet 2..." };
        
    subscription any = InfoBus.subscribe("calculator.calculate", calculate);
    
    function calculate(msg String in, data any in)
    	try 
	    	value bigint = data;
	    	result bigint = 2 * value;
	    	html.text = "2 * " + value + " = " + result;
	    	InfoBus.publish("calculator.result", result as String);
	    onException (e AnyException)
	    	html.text = "Oops: '" + e.message + " " + data + "'";
	    end
    end

    fix CrossIFrameInfoBusFix{};

end


Again, it defines a subscription to the InfoBus, and handles them in its "calculate" function. Once a result is known, we publish it on the InfoBus again. When something unexpected happens, such as arithmetic overflow or the user enters an invalid number, we print a message.

Finally, portlet 4 simply shows another URL, in this case http://ibm.com/

handler Portlet4 type RUIhandler {initialUI = [ frame ] }
	
	frame IFrame { width=1000, height=1000,  src = "http://ibm.com" };
  
end


The end result looks like this:

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1264-1738/portal3.jpg
Inter-portlet Communication

You may have noticed declarations to the following field in some of the portlets:

    fix CrossIFrameInfoBusFix{};


What this does is include a fix for InfoBus to allow it to work across iframes. Normally a parent and its nested iframes are completely isolated from each other. What the fix allows for is communication between these two different documents.

What if I don't want a Portal?

The above sample shows how to build a client-side Portal using iframes for the individual portlets and InfoBus for communication. You can use the same technique for other compositions of multiple "modules". One example could be having a main handler with a tab folder. As that is all it contains, it will start up quickly. Then as tabs are opened over time, more and more sub-modules are downloaded on demand (using the above IFrame approach).

The nested handlers can be kept around (as in the Portal), but a different policy could be to do some form of "garbage collection" by unloading the iframes from the document, and recreating them from scratch again when the user likes.

By decomposing modules into separate application level URLs, complexity goes down, individual files get smaller, and things will faster initially and will benefit usage patterns where a limited breath of functionality is actually activated by the end user. Some application have hundreds, even thousands of "screens", and putting them all in one single mega-application makes little sense as during any session only a few dozen may be actually activated.

To try this out in your own workspace, import the attached archive as "General > Existing projects into Workspace". Open the Portal.egl application and load it in the preview.

To try out the non-Portal approach, check out "AppSwitcher.egl".

Attachments: Portal.zip

9 Comments Permalink
2

Since 1997 I have been licensing a version of the card game Klondike Solitaire to online gaming sites. I originally wrote the game in 1997 as a learning exercise. It was, for all intents and purposes, my first Java application. Earlier this year I worked for about a month in my spare time to port the Java version of my game to EGL Rich UI. You can play the game here.

While there may be potential commercial clients for my new game, this is less likely today than when online gaming sites were first springing up. Instead of looking for a commercial audience for the EGL version of my game I have placed the source code in the public domain and it is available here on SourceForge.

Perhaps my code can serve as a learning tool for people entering the EGL programming world. Who knows, there might even be people who want to improve upon the game or use it as the basis for other, similar games.

Over the next few weeks I hope to blog more about the experience of porting solitaire from Java to EGL. Here are some of the topics that I think might be of interest to readers:

  • Migrating software from an OO language to a non-OO language. You may be interested to hear just how close EGL is to an OO language and how reasonably it adapts to an OO design model.

  • UI elements that are easier to implement in EGL than in Java. For example, using lowest-common-denominator Java technologies required creating my own drag and drop mechanism. In EGL, drag and drop is a fact of life and it is dead easy to code.

  • Localization on a budget: How I was able to get reasonable translations for next to nothing.

While some might scoff at this effort being a mere game -- and not "serious" software like order entry applications or something (but you know, I write those too) – I would be quick to point out that I've made money from the Java version of this game for more than a decade now. In my book that makes it business software.<grin> If nothing else though, the same user-interface elements that one finds in games today manifest in all modern web applications and most modern back-office applications. You may not care about games as such but as a learning tool I hope my work is still helpful to you.

Dan Darnell, Consultant

2 Comments Permalink
6

In EGL CE, the EGL project structure has been changed to combine and extend the features of the General Project and the Rich UI Project types found in Rational Business Developer (RBD). In RBD, a General Project would be used for Java, and a Rich UI project would be used for JavaScript. In EGL CE, one project can now be used for both languages. Also, when working with Rich UI in RBD, a user had to set the workspace for Development or Deployment mode, depending on whether or not the code was still being written and debugged or if it was being prepared for deployment.

To remove the switch that controls Development mode and Deployment mode, all generated content is now placed into two directories at the root of the project; debug and target. All code that is used for development and debugging will be placed in the debug directory, and all code that will be used for deployment is placed in the target directory. To support the use of multiple languages in one EGL project, the debug and target directories contain a subdirectory for each language being generated; Java and JavaScript.

In addition to the project structure changes found in EGL CE, the way that code is generated has also been changed. In EGL CE, the only parts that are considered 'Generatable' are Handlers and Services, and these parts are now generated whenever the EGL source for the part is built. Any parts that are referenced by a Handler or a Service will be generated whenever the Handler or Service is generated, and they will be generated into the same language as the Handler or the Service. For example, assume a Library is used by both a RUIHandler and a Service. When the RUIHandler is saved, both the Handler and the Library will be generated into JavaScript and placed in the appropriate JavaScript output directories (e.g. debug/JavaScript, target/JavaScript). When the Service is saved, both the Service and the Library will be generated into Java and placed in the appropriate output directories (e.g. debug/Java, target/Java). To support the generation process, each EGL resource in an EGL CE project can now specify 4 different Default Build Descriptors: Debug/JavaScript, Target/JavaScript, Debug/Java, Target/Java.

It was mentioned above that an EGL Part is generated whenever its source is built. In Eclipse, a build usually happens when a file is saved or when a Clean Build is invoked. When a Clean Build is invoked in EGL CE, the root debug and target directories are deleted, and all of the parts in the workspace are regenerated as they are built. Due to the fact that the generation output directories will be 'cleaned' during this process, it is not recommended that you place your own Java code in these directories. If you have your own Java code that you would like to reference using EGL External Types, it is recommended that you add another Java Source folder to your EGL Project and place the Java code in this directory. When you deploy your project, you will also need to copy the Java code into the Java Source folder for that project as well.

6 Comments Permalink
0

EGL CE has recently shipped, and I decided to write a sample that showcases some of the useful features this new and exciting technology offers.

In short, my sample downloads a workitem from jazz.net and shows it in a UI. Of course, my intent is not to replace the Jazz Web UI, rather I highly simplified it into a small sample that shows off aspects found in many rich web applications.

When the JazzUI handler is loaded, it makes a couple of service calls. The following picture shows what components in the UI are created how (it happens to show Darin Swanson, the creator or workitem 33551):

info.jpg

Use of EGL CE Features

My Jazz workitem UI showcases the following EGL CE features:

  • authentication and session management
  • calling asynchronous services (Ajax)
  • decomposition of complexity by composing reusable handlers
  • Dojo Widgets for some of the UI elements
  • browser cookies for storing userid+passwords
  • XML DOM parsing to efficiently deal with large XML files
  • EGL Jobs to manage future work and improve responsiveness
  • an EGL library to implement the singleton pattern (see LoginForm.egl)
  • the EGL InfoBus to decouple producers and consumers of application events
  • the EGL History support to manage the back button and allow for bookmarkability
  • a Service Monitor to trace and debug service calls
  • aggressive compression and optimization when deploying the application

The code is heavily annotated with comments, so I won't show too much sample code in this blog entry and refer simply to the source code that can be found in the attachment.

Deployment and Compression

When I deployed my application in my workspace, I selected the project and used the context menu to deploy it. Then I create a new target project and deployed it on TomCat 5.5.
After it was deployed, I located the generated HTML file in the target project's WebContent folder.

I then used the context menu to run it on TomCat and used Firefox with Firebug to inspect the size of the end-result.

The following picture shows my Dojo files are cached in the browser already (except for jsapi!). Note that the picture shown for the 'creator' is completely random and really comes from bing.com when you search for Bill :-).

firebug.jpg


The 68K for our application HTML file includes the following:

  • all of the EGL runtime,
  • all the EGL widgets I used and that got compiled into JavaScript,
  • all the EGL code I wrote that is compiled into JavaScript,
  • all my hand-written JavaScript that I wrote to implement a few external types,
  • all EGL-specific JavaScript used by the Dojo widgets

As you see in the image above, the dojo widgets themselves come from Google's CDN.

All EGL debugging information has been stripped from the JavaScript, and then we reduced the left-over JavaScript using Dojo ShrinkSafe. This is all done automatically by the EGL CE tooling. Finally, when the application is deployed on TomCat, we tell TomCat to use gzip encoding to further compress the text. All this is automatic without me needing to think about it at all.

Try it for yourself

To try the sample for yourself, follow these instructions:

  • download the attached archive (do not unzip it)
  • in EGL CE, use the menu option File > Import...
  • select Existing Projects into Workspace
  • select the jazz.net.workitem project
  • open EGLSource/ui/JazzUI.egl and select the Preview tab
  • click on the links How's this done? and Source Code

The import dialog should look something like this:

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1261-1732/import.jpg


Attachments

jazzui.zip (make sure to apply the DojoDialog fix: DojoDialog may be incorrectly sized)

0 Comments Permalink
0

iSeries DevCon Podcast in EGL and i

Posted by JoePluta Sep 15, 2009

I have presented session at iSeries DevCon pretty much since the conference's inception, and this year is no exception. Of course, I'll be doing the heavy lifting on EGL and some other related topics, but there are lots more great speakers and sessions. In my humble opinion, there isn't another conference that better provides both true nuts and bolts programming techniques with a solid application of future-proofing technologies.

Trevor Perry and I have recorded podcasts about what you can expect; click on the link to go to my podcast.

You'll have to enter an email address to get the real link, though.

0 Comments Permalink
RSS feed of this list 1 2 3 ... 9 Previous Next

RSS Feed

Bottom Banner