EGL Community Edition

14 Posts
0

EGL CE for RBD users

Posted by tdramsey Nov 9, 2009

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
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
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
1

This blog post serves to keep an up-to-date list of known issues, observations, and feature requests reported by users of EGL CE.

Make sure you watched the introduction video at http://www-949.ibm.com/software/rational/cafe/community/egl/ce.

For troubleshooting, check Troubleshooting EGL Community Edition issues

CE Version Date Type Summary Details
1.0.0 09/14/09 Defect DojoDialog DojoDialog may be incorrectly sized
1.0.0 09/14/09 Defect Error Messages Dojo Google provider does not print error messages during startup
1.0.0 09/14/09 Enhancement Ajax Proxy Web Security and why EGL Rich UI needs an Ajax Proxy

1 Comments Permalink
0

Getting Started with Dojo in CE

Posted by gpapayia Sep 11, 2009

I thought I'd take a moment and build upon Theresa's post Getting started with Rational EGL Community Edition and talk a little about the new Dojo Widgets in the EGL Community Edition (CE). For those that don't know, the Dojo Toolkit is an open source JavaScript library for developing web-based applications. It's available for free from the Dojo website and provides an array of widgets including menus, tabs, tables, dynamic charts and more. Takes this from me: Dojo is extreamlly powerful - but with power (in this case) comes a fair amount of complexity.

One of the best parts of EGL is that your not restricted to a single widget library. You can create your own custom widgets using any JavaScript your heart desires. With that in mind, back in April we launched an early version (0.6.0) of the EGL Dojo Widgets. Since then, the Dojo Widgets have come a long way and I'm very excited at what we've done for the 0.7.1 release. Unfortunatly the API has changed for certain widgets, but I assure you major changes like that won't happen again.

http://www-949.ibm.com/software/rational/cafe/servlet/JiveServlet/downloadImage/38-1255-1726/projects.jpg

Of the 5 projects that are loaded by default when you start CE, 3 of them are related to Dojo. These are the Dojo Widgets, Samples and Runtime. You'll notice when using the Visual Editor the palette has the Dojo Widgets populated automatically. We encourage you to jump right into using Dojo in your EGL applications, go ahead and take a look at the Dojo Samples and see just what you can do. A great place to get started is the Gallery sample. This includes all the 0.7.1 Dojo widgets in a single sample.

Remoate vs Local Dojo

As I mentioned above, Dojo is extreamly powerful. What I didn't mention was that power brings not only complexity, but size. Luckily Dojo allows for their runtime to downloaded remotly through content providers like Google, Yahoo or AOL. This paradigm is widely on numerous sites including hpn.to & TechCrunch to name a few. This means you don't need to have the Dojo runtime in your local filesystem, instead Dojo will download the necessary files as your application is loading.

Sounds great, doesn't it? For the most part - but what if you don't have an internet connection or you want to deploy your application with Dojo available locally? Not to fear, we make it easy for you to switch between the remote version of Dojo to a compressed local version. Just follow these steps:

1) Click on the Help Menu -> Search
2) Search for 'Local Dojo'
3) Click on 'Loading the Dojo Toolkit into your local environment'
4) Click 'Get the Dojo Toolkit Project' under 'Import Projects'

At this point you'll see the new project in your worksapce holding the local Dojo Runtime (dojo.runtime.local). All you need to do now is update your EGL Build Path for the Projects you want to use the local Dojo. So in my case, I'll just update the Dojo Samples.

buildpath.jpg

I think that's enough for now, I hope everyone enjoys CE!

0 Comments Permalink
0

Why EGL

Posted by will.smythe Sep 11, 2009

Over the last few days, I have been asked several times - "Why EGL?". It's a good question. For those of us that have been around EGL, the answer is obvious: spend more time innovating and less time fighting with technology. For those of you that are not familiar with EGL and the new EGL Community Edition tool, here are some of the key benefits. These benefits should resonate if you've ever fought with JavaScript :)

  1. EGL does not replace HTML, JavaScript, or Java, but makes development of HTML, JavaScript, and Java easier. EGL code is compiled (on the fly) based on where it needs to run. EGL code that is expected to run in the browser is compiled into JavaScript and HTML. EGL code that is expected to run on an application server (like Apache Tomcat) is compiled into Java.
  2. Build a complete application in one language (EGL). So, instead of coding server-side logic in one language (like Java or PHP) and client-side logic in another (HTML and JavaScript), with EGL CE, you can code the entire application in EGL. This allows you to learn just one language and not several. Another major benefit of this approach is that data is represented the same way in both server-side and client-side EGL code. So, for example, you can define a Record (a record is an EGL concept similar to a Java bean for representing some data object) once and reference in both your server-side code and client-side code. The record is automatically compiled into Java and JavaScript as needed. EGL handles the serialization and parsing of the actual data being transported (between the server and browser) so you don't have to worry about it.
  3. Completely code, test, and debug without deploying anything to an application server. The Preview tab of the EGL editor provides a running version of your application. When you switch to this tab in the editor, your EGL code is compiled on-the-fly. You can also set breakpoints in your code for easier debugging (EGL CE uses the standard Eclipse Debug tools and perspective). Best of all, you don't have to deploy services to a server to debug them.
  4. Transparent client/server development. With EGL CE, all code - both code that will eventually run as JavaScript in a browser and Java on the server - is developed in the same Eclipse project (of course, you can always develop in separate projects if needed). From within your UI code, you can directly reference and call services. Under the covers, EGL will create a REST service for your services and take care of the bindings necessary at runtime.
  5. Integrating with existing services. EGL supports calling existing SOAP and REST (JSON or XML) services. So, if you already have Web services up and running, you can use EGL to build a new UI. Within your EGL code, input and output to the service is represented as EGL variables or records. In the case of SOAP services, EGL will automatically create the input and output records for you - all you need to do it import the WSDL file.
  6. Data access. EGL makes interacting with databases simple. EGL provides simple keywords (get, add, delete, etc) to easily work with a database.
  7. Easy deployment. With EGL, you can fully develop and test your application before ever deploying it to a server. Once you are ready to deploy, however, EGL CE deploys code into a standard Eclipse Dynamic Web project. This project can be run on Apache Tomcat or packaged as a .WAR file and deployed to an external application server.

0 Comments Permalink
0

In the following picture we show how easy it is in EGL CE to change visual attributes for any widget using the visual editor. In this case we show 4 buttons, each with different attributes defining distinguishing features.

styling.png

To add styling to your Rich UI applications, EGL CE offers the following three modes:

  1. Direct Attributes. Edit fields on a widget directly, using the visual editor or in the source editor. This allows you to set things like borderWidth, backgroundColor, font, etc. The source editor comes with content assist and the visual editor has a property editor to choose the attributes from. Advantage of this approach is that you do not need to learn CSS. Disadvantage is that the styling is hard-coded in the widget, which makes global changes more difficult to implement.
  2. Style Setting. Set the 'style' field on a widget (using the source editor) to assign multiple CSS styles directly on a widget. An example is widget.style = "border: 2px solid black; color: blue; overflow-x: hidden". Advantage of this approach is to allow you to quickly test out a given CSS fragment. Disadvantage is the same as with direct attributes, and that the styling is hard-coded in the widget.
  3. CSS Classes. Set the 'class' field on a widget to a given CSS class name. Add a 'cssFile' parameter to the main handler and refer to a CSS file. In the WebContent directory, create a CSS file and edit the class definitions you want to have applied. Advantage of this approach is that it uses widely accepted CSS styling. You can have a designer in your team who never gets involved in actual EGL development write a CSS style sheet and define a company branding that is inherited across all the applications you develop. A disadvantage is that UI definition and styling are detached now, and may be harder to debug and/or get right. See below for more on that topic.

In practice, we advise people that are just learning EGL to start with mode 1. and use direct attributes. This will give them an idea of the possible attributes and their effects most directly. Once a development process matures, we recommend stepping to mode 3, and use CSS classes.

Note that the EGL widgets and the Dojo widgets use various styles for each of their widgets (and the subcomponents inside those widgets). This means that without any EGL coding, you can make widgets look differently by simply adding a new stylesheet to your application. Use the xray tool described below to figure out what styles are used, or consult the source for each widget by selecting the typename and hitting F3.

In two blog postings that were published before we launched EGL CE, in the EGL Rich UI blog, I talked about two tools that can help develop and debug your CSS.

The first posting, Writing with Style, shows the xray tool, which allows you to inspect any given element in the browser's document, so you can find out what CSS class, padding, margin, and borders it has. This is useful for making sure you did not make any typos when referring to certain style classes, for instance.

The second posting, A CSS Validator written in EGL Rich UI, discusses a CSS Validator which can be used to verify the CSS you are entering in your CSS files is conforming to the W3 standards. For this purpose we wrote a widget in EGL Rich UI that calls services to the W3 Jigsaw validator.

Have fun with styling your EGL CE programs and share your tips and experiences in a comment below...

0 Comments Permalink
0

Introduction to EGL Projects

Posted by alicec Sep 11, 2009

For those of you who are learning about EGL, here is an overview of EGL projects to help you get started...

A project is a container for a group of related files. An EGL project is an enhanced project that you will be using to hold EGL source files in your application.

The structure of an EGL project is simple. By default, it contains two top-level folders, EGLSource and WebContent. You should create all EGL source files under the EGLSource folder. EGL will generate these source files into JavaScript or Java, depending upon whether the code will run in a browser or on an application server. You should create all Web resources such as cascading style sheets, images, and icons under the WebContent folder. EGL will deploy these Web resources with your HTML file.

You can use EGL to develop both client-side and server-side code by doing the following:

  • Define a Web page that runs in a browser by creating an EGL Rich UI handler part
  • Define business logic that runs on an application server such as Apache Tomcat by creating an EGL service part
  • Define data and logic in EGL records and libraries that can be used by both Rich UI handlers as well as by services.
Within an EGL project, we recommend that you use packages to separate your client from your server code. At deployment time, you can use EGL deployment descriptors to control which parts to deploy and which Web projects to deploy to.

You can define your Web application code in either a single EGL project or in multiple ones. If your application is small and will probably not contain code that will be shared by other applications, putting your code in a single project provides simplicity and ease of use. On the other hand, if your application is complex, you can use multiple projects to help organize your code and allow parts such as libraries, records, and services to be easily shared across projects.

When programming in EGL, you only need to be concerned about EGL code, not about generated Java, JavaScript, or HTML. Therefore, resources containing generated code do not show up in your project when using the Project Explorer. If you want to see these resources for some reason, you can do so by using the Navigator view.

Creating an EGL project

When you are ready to develop some code, begin by creating an EGL project to hold your files. There are several ways to invoke the New EGL Project wizard:

  • Click on the New EGL Project icon newegl_wiz.gif, fourth in the toolbar
  • Click on File > New > EGL Project
  • Right click in the Project Explorer. Then click New > EGL Project.
NewProjectDialogL.JPG

In most cases, you can specify a project name in the New EGL Project dialog, and click Finish.

Setting project dependencies

When you create a new project, the New EGL Project wizard adds two project dependencies - com.ibm.egl.rui_1.0.2 and com.ibm.egl.rui.dojo.runtime.google_1.3.2 - by default. These projects are already loaded into your workspace; you can see them in the Project Explorer. These dependencies allow the EGL Rich UI and Dojo widgets to be accessible from your project when you develop a Web page using an EGL Rich UI handler.

If you need to reference additional EGL code in another project, you need to add a dependency on that project. To do so from the New EGL Project wizard,

  • Click the Next button after specifying a project name.
  • On the EGL Settings page, select the additional project that this project will reference. In this example, it is reallyUsefulProject.
  • Click Finish.
EGLSettingsL.JPG

Your new project can now access code in reallyUsefulProject.

You can add a new project dependency in an existing project as well. To do so,

  • In the Project Explorer, right click on your project name, like myProject, then click Properties.
  • Click EGL Build Path.
  • Select the project that myProject will reference, like reallyUsefulProject.
  • Click OK.
EGLBuildPathL.JPG

In myProject, you can now use code from reallyUsefulProject.

I hope that you have found this introduction to EGL projects helpful in getting started. Stay tuned to this blog for upcoming posts on useful topics such as developing with Dojo widgets, defining and calling services, and deploying EGL projects. Have fun trying out EGL CE!

0 Comments Permalink
1

Once you download and run Rational EGL Community Edition, you'll notice the Welcome page which provides useful information about the product and links to tutorials, samples, and Web resources.

You'll also notice some projects are loaded into your workspace. These projects contain the widgets for EGL Rich UI and Dojo, as well as samples of how to use the widgets. Explore the com.ibm.egl.rui.samples.ce project, by opening the contents.egl file under EGLSource>gallery and clicking on the Preview tab. Similarly, you can start exploring the com.ibm.egl.rui.dojo.samples project by opening Gallery.egl under EGLSource>dojo.sample. The Preview tab allows you to interact with the running application. You can make changes and see them in action, without having to deploy to a Web application server. Using the Preview can really help speed up your development.

Once you've had a chance to explore the samples, create your own EGL project. More on EGL projects in a later post...

We hope you'll find EGL easy to learn and use!

1 Comments Permalink
0

Welcome to the official developer community site for EGL Community Edition! The goal of this site is to provide you with the information you need to download and successfully use EGL Community Edition.

If you run into a problem, visit the Support and Help page to find out where to get help.

Thanks for visiting! And happy programming ...

Will Smythe

0 Comments Permalink

Blogs at a Glance

Can't find a specific blog? Try using the Blog page to browse and search blogs.

Request a Blog

Interested in blogging on EGL Cafe? Contact us!

Bottom Banner