Monday, April 28, 2008

Using IUI in Grails

So the first package I used in reviewing phone based UI's from Grails was CIUI. The other popular one that I found was IUI. This one seems a bit more advanced or at least feature rich than CIUI. I should point out it will be interesting to see how move advanced iPhone and HTML 5.0 features are going to play out in all this. That aside, implementing IUI was only marginally harder than CIUI. Again we download and place the CSS and JS files into the css and js directories located in [project]/web-app. In the case of IUI I did have to edit the CSS file to have it correctly locate the images folder (where I placed all the images that come with IUI). You could make a separate directory for these images as a sub-directory of images and alter the CSS file as you see fit in that case. Note, this package didn't render well for me outside of the webkit engine. I did a post on Webkit javascript performance on Ubuntu that also links to resources for compiling this package on Linux (Mac and Windows builds are available at the webkit site )

For the case of IUI I used the samples that came with the package as a guide to for all this. My GSP files looks like:

<%@ page contentType="text/html;charset=UTF-8" %> 
<html>
<meta name="layout" content="iuiLayout"/>

<head><title>IUI test</title>
<meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
</head>

<body onclick="console.log('Hello', event.target);">
<div class="toolbar">
<h1 id="pageTitle"></h1>
<a id="backButton" class="button" href="#"></a>
<a class="button" href="${createLink(controller: 'iui', action: 'search')}">Search</a>
</div>

<ul id="home" title="Home" selected="true">
<li><a href="${createLink(controller: 'iui', action: 'category1')}">Category 1</a></li>
<li><a href="${createLink(controller: 'iui', action: 'category2')}">Category 2</a></li>
<li><a href="${createLink(controller: 'iui', action: 'stats')}">Stats</a></li>
<li><a href="${createLink(controller: 'iui', action: 'settings')}">Settings</a></li>
<li><a href="${createLink(controller: 'iui', action: 'about')}">About</a></li>

</ul>
</body>
</html>


Here I just linked into my IuiController.groovy file to various methods to demonstrate some of the different features IUI has. The only interesting points in this are that it does demonstrate how to use the render method for cases like this where you need to include attributes and such. One interesting note was that the render method refused to provide a node named "form" in the XML return. I assume this is perhaps related to a keyword issue or some such. However, MarkupBuilder has no issues so where this does NOT work:

    // shows a form but doesn't work due to keyword issue with "form'? 
def searchDoesNotWork = {
render(contentType: "text/xhtml") {
"form"(id: "searchForm", class: "dialog", action: "foo") {
fieldset {
h1("Search the records")
a(class: "button leftButton", type: "cancel", "Cancel")
a(class: "button blueButton", type: "submit", "Search")
label("First Name")
input(id: "fname", type: "text", name: "fname")
label("Last Name")
input(id: "lname", type: "text", name: "lname")
}
}
}
}
this method will:
    def search = { 
def mywriter = new StringWriter()
def xml = new MarkupBuilder(mywriter)

// had to do this since the render method seemed to not want to return form (key word?)
// this is really how they should dbe done anyway... but I am too lazy to change all the
// examples

xml."form"(id: "searchForm", class: "dialog", action: "${createLink(controller: 'iui', action: 'doSearch')}") {
fieldset {
h1("Search the records")
a(class: "button leftButton", type: "cancel", "Cancel")
a(class: "button blueButton", type: "submit", "Search")
label("First Name")
input(id: "fname", type: "text", name: "fname")
label("Last Name")
input(id: "lname", type: "text", name: "lname")
}
}
render mywriter.toString()
}

In point of fact it's likely better form in most cases to use the MarkupBuilder as you can incorporate it into code logic easier. Though for simple cases there seems to be nothing wrong with render. As with the CIUI example I'll just post up the whole controller file for people to look at (IUI Controller ).

Note, I did modify the iui.js file line:

req.open(method || "GET", href, true);

to

req.open(method || "POST", href, true);

in order to get the search call to work to my controller. For some reason the URL encoding version would not send back the variables. I may contact the IUI people about this and see if I can resolve why this occured.

I was not able to wire up the toggle button to a controller method.. I got the error:

console message: http://localhost:8080/phoneUIGarden/iui#_Settings @35: Can't find variable: settingCallBack

Likely this is something simple (a guess) but I didn't bother to track it down since this was just a "for fun exploration" project.

It's easy to see how this could all be extended into a secured area of a site via Acegi or jsecurity and perhaps even attached to webflow . All fun stuff if I was paid to do that. This is by no means and in depth review, it's just my 4am feeding hacking to see what is involved in using IUI and CIUI. I thought I would share since I haven't seen much on using these in the Grails framework.

It's obvious that
A) it's simple
B) Groovy and Grails are a wonderful language/framework environment to do this in.
C) Someone with more time for this could flesh it all out rather quickly

enjoy...
Doug


Using CIUI in Grails

So this past weekend I needed a fun yet mindless task one morning during at 4 am. I have been looking at both CIUI and IUI and knew they would lend themselves well to being implemented in Grails what with it's oh so easy REST/AJAX style call to the controller layer. In fact this was ever so easy and so I thought I would mention it here so people would know of these nice packages and add these as tools to their Grails toolbox. If you are doing this from Linux (Ubuntu in my case) like I am, you may want to use the webkit engine (Ref: Webkit on Ubuntu performance ). Especially for the IUI package since it seems to render best in Webkit even over the latest FF3 engine.

Starting with CIUI the approach is easy. Place the CiUI.css in your [project]/web-app/css and the CiUI.js into the [project]/web-app/js directories. You may need to scan the CSS file and change image paths and such if you are using images from an other than default location.

I created a simple controller CiuiController.groovy and an associated GSP page index.gsp. Into the GSP page be sure to place:

<link rel="stylesheet" href="${createLinkTo(dir:'css',file:'CiUI.css')}" />
<g:javascript library="CiUI"/>

to load the CiUI css and js files. Obviously you can alter the directory paths and such to keep your application file structure in whatever order you wish.

My whole GSP pages looks like:
<html><head> 
<title>Grails and CiUI Demo</title>
<meta name="viewport" content="width=320"/>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
<link rel="stylesheet" href="${createLinkTo(dir: 'css', file: 'CiUI.css')}"/>
<g:javascript library="CiUI"/>
</head>

<body>
<div id="iphone_header">
<div id="iphone_backbutton">
<img src="images/back-button-tip.png" border="0" align="left"/>
<a id="iphone_backbutton_text" href="#" class="go_back">Back</a>
</div>
<div id="iphone_title"></div>
</div>

<div id="iphone_body" style="clear:both;">
<ul class="menu">
<li><a href="${createLink(controller: 'ciui', action: 'page', id: '1')}" class="go_forward" title="Feeds">
Groovy and Grails Feeds
</a>
</li>
</ul>
</div>

<div id="iphone_footer">My footer for CiUI demo</div>

<div id="iphone_loading_page">
<div id='loading' class="info_msg">
<img src="images/loading.gif"/><br/>
loading...
</div>
</div>
</body>
</html>




Next it's just a few simple method calls in the controller. I decided to have a little fun and used the Groovy XML features to pull down RSS feeds from Groovy Blogs, Groovy on Grails and Groovy Zone. There are really only a couple of comments:

1) This whole effort is made very easy by use of the Grails "render" call. It means that we can do things like:

   def page = { 

// you would make this more dynamic in a real app
def feedMap = ['Groovy Blogs': 'http://feeds.feedburner.com/groovyblogs', 'Grroovy on Grails': 'http://feeds.feedburner.com/groovyongrails', 'Groovy Zone': 'http://feeds.dzone.com/zones/groovy']

render(contentType: "text/xhtml") {

// If there are some menu items to show.. show them
ul(class: "menu") {
for (i in feedMap.keySet()) {
li {
a(class: "go_forward", title: "${i}", href: "${createLink(controller: 'ciui', action: 'getFeed')}/?url=" + feedMap[i]) {
div("${i}")
}
}
}
}
}

}

Check out more on the render method at http://grails.org/Controller+Dynamic+Methods. For sake of a short blog entry I have just placed the whole controller file on-line (Ref: CIUI Controller ) It's all just a simple zero'th order pass at using CiUI. There are many extensions that one could do with this (more with templates, webflow, etc.). I didn't implement the search interface or anything fancy here as this is just a review to see what is involved (practically nothing) in using CIUI in Grails. I will likely go back and add something like that in and see if I can call back with parameters to my controller.

Note however that when generating the mark up in the controller it's likely a bit more "proper" to do something like the following MarkupBuilder example. This is actually an example from the IUI test I did and not used in this CIUI example, however the principle is the same.

    def search = { 
def mywriter = new StringWriter()
def xml = new MarkupBuilder(mywriter)

xml."form"(id: "searchForm", class: "dialog", action: "${createLink(controller: 'iui', action: 'doSearch')}") {
fieldset {
h1("Search the records")
a(class: "button leftButton", type: "cancel", "Cancel")
a(class: "button blueButton", type: "submit", "Search")
label("First Name")
input(id: "fname", type: "text", name: "fname")
label("Last Name")
input(id: "lname", type: "text", name: "lname")
}
}
render mywriter.toString()
}

Here we used the Groovy MarkupBuilder to generate our XML outside the render method and then just pass it along. This means we can push this logic down into a service or at least have a bit better logic to our controller code designs.

This youTube video shows what it looks like in action

Implementing these JS/CSS packages inside Grails is trivial. As the iPhone and Google Android phones become more and more a mechanism for people to obtain information from the web the ability for developers easy represent data in appropriate formats will be more important. Grails is a wonderfull platform for addressing that.

enjoy
Doug

Friday, April 25, 2008

xrandr with Ubuntu 8.04 and external monitors on laptops

So I installed Ubuntu 8.04 onto my Dell Inspiron 700m. I was impressed with everything it is doing well right out of the box (display, power management, wireless, etc.).

However, one item I was really looking forward to was xrandr and the ability to dynamically plug in external monitors or projection units. In trying this I failed to get my external monitor to dynamically configure via xrandr. However, the solution to this was simple.

The default xorg.conf was:

Section "Screen"
Identifier "Default Screen"
Monitor "Configured Monitor"
Device "Configured Video Device"
EndSection

I modified this by adding in the subsection display:

Section "Screen"
Identifier "Default Screen"
Monitor "Configured Monitor"
Device "Configured Video Device"
SubSection "Display"
Virtual 2560 1024
EndSubSection
EndSection

Next restart X (logout and in, or cntrl-alt backsapce). Note that for me the entry was 2560 1024 since my internal display is 1280x800 and the external is 1280x1024 so 1280 + 1280 = 2560 and 1024 > 800 so use 1024. You will need to do the math for your case.

At this point the "Screen Resolution" application works correctly to set up the displays. Readers may also be interested in the article at http://www.thinkwiki.org/wiki/Sample_Fn-F7_script which shows a nice shell script that can be connected to key combinations for all this.

take care
Doug

UPDATE April 28th:

Just a follow up to this posting. It turns out that in several cases (and low end laptop graphics like mine among them) that doing this will

disable DVI and thus not allow you to run compiz

For me nice graphics vs dual monitor is a no contest. I'll take the dynamic xrandr over compiz any day.

Tuesday, April 22, 2008

Sorting multidimensional arrays in Groovy

I didn't find this solution as quickly as I thought I would so I thought I would post about it here to provide some search engine fodder.

If you are dealing with multidimensional arrays in Groovy (ref: http://groovy.codehaus.org/JN1025-Arrays ) and want to sort them you can expand on the sorting concepts for collections in Groovy (ref: http://groovy.codehaus.org/JN1015-Collections ).

If you look in the last reference you will find the example:
def mc= [
compare: {a,b-> a.equals(b)? 0: Math.abs(a)<Math.abs(b)? -1: 1 }
] as Comparator
We can modify this for a multidimensional array. So some excerpts from my code:
println "Pre sort: ${uniqueAges}"
def mc = [
compare: {a, b -> a[0].equals(b[0]) ? 0 : a[0] < b[0] ? -1 : 1 }
] as Comparator
println "Post sort: ${uniqueAges.sort(mc)}"
results in
Pre sort: [[11.2, 5.32], [1.77, 0.01], [3.58, 1.77], [5.32, 1.77], [5.32, 3.58]]
Post sort: [[1.77, 0.01], [3.58, 1.77], [5.32, 1.77], [5.32, 3.58], [11.2, 5.32]]
or
 println "Pre sort: ${ageZoneList}"
def mc2 = [
compare: {a, b -> a[0][0].equals(b[0][0]) ? 0 : a[0][0] < b[0][0] ? -1 : 1 }
] as Comparator
println "Post sort: ${ageZoneList.sort(mc2)}"
results in
Pre sort: [[[5.32, 11.2], [163.5, 189.62, "Late Miocene"]], [[0.01, 1.77], [0.05, 105.58, "Pleistocene"]], [[1.77, 3.58], [114.82, 123.68, "Late Pliocene"]], [[1.77, 5.32], [103.13, 163.53, "Pliocene"]], [[3.58, 5.32], [137.16, 156.19, "Early Pliocene"]]]
Post sort: [[[0.01, 1.77], [0.05, 105.58, "Pleistocene"]], [[1.77, 3.58], [114.82, 123.68, "Late Pliocene"]], [[1.77, 5.32], [103.13, 163.53, "Pliocene"]], [[3.58, 5.32], [137.16, 156.19, "Early Pliocene"]], [[5.32, 11.2], [163.5, 189.62, "Late Miocene"]]]


Note that in Groovy multidimensional arrays need not have the same exact length at each level as noted in the Array reference above. This does mean that you need to take care with respect to iterating your indexes if your array is triangular. This is not likely the most efficient search for a large multidimensional array, but for simple sorts on smaller examples its working well for me. I would appreciate references for quicker sorts if people have them.

take care
Doug

Monday, April 21, 2008

Spaces in REST URLs

So I need to deal with spaces in REST URL's. Something like:

.../timescale/Late Jurassic

I'd rather not allow these types of URL's (since I don't think the spec even allows them) and was thinking about the programming and also community practices issues this raises. If a person wants a space they likely should use "%20", however this just doesn't look good and I believe gets confusing.

I could simply allow the community to create such URL's even though I believe them wrong and then attempt to resolve them in my Grails application with:

someString.replaceAll("%20", " ")

since firefox and I suspect other browsers will convert the spaces to "%20" for the user.

This seems a poor approach though since if someone puts two spaces into the URL or somehow a tab gets in things get ugly fast. A person just has far too many bad issues to deal with.

Forcing the community to use camel case (here I will use lower camel case but one could use upper camel case) would require a URL like:

.../timescale/lateJurasic

where I could split the parameter in Groovy with:

someString.replaceAll("([A-Z])", " $1").trim()

so "lateJurassic" becomes "late Jurassic" which is what is in my database (actually "Late Jurassic" but I can case insensitive search) since that is the "proper" form of the name.

This puts the burden of creating a camel case representation of "Late Jurassic" on the client end of the application (ie, make this someone else's problem, which is always a good thing).

I suspect this is just a case where the best resource identifier in the database is not always the best resource identifier for the REST URL representation. It would seem then that apply a best practice approach one would use a camel case representation. This might be a situation where using upper camel case is better yet since the proper cases on the name is "Late Jurassic" resulting in a URL:

.../timescale/LateJurassic

That is still fine since the .trim() call will remove the leading space still in the above code. I'd love to hear other thoughts on such mappings.

take care
Doug

Monday, April 14, 2008

Javascript comparison of WebKit and Firefox 3 Beta 5 on Ubuntu

This weekend I had a small pet project I did that gave me a need for a webkit based browser on Linux (Ubuntu 7.04). While I could have used Konqueror I was more interested in a later source base and so downloaded the WebKit r31738 source from http://www.webkit.org. Actually, after a couple simple apt-get install for the development library this source package will compile just fine on a rather stock Ubuntu 7.04 and runs well (Ref: http://live.gnome.org/WebKitGtk ). The default UI shell for the webkit core is ultra basic but all I need for testing against this rendering engine. One can use webkit as the engine for Epiphany (http://live.gnome.org/Epiphany/WebKit ) if you want a nicer wrapper.

I was curious to try this new engine (more specifically it's javascript aspect) against my current favorite browser Firefox in the form of Firefox 3 Beta 5 (http://www.mozilla.com/en-US/firefox/all-beta.html ). A tried both the Dromaeo test suite (still in early release, review notes at: http://wiki.mozilla.org/Dromaeo ) and Sunspider from: http://webkit.org/perf/sunspider-0.9/sunspider.html. My platform is rather paltry Athlon 64 3200+ and 2 gigs of memory running the afore mentioned Ubuntu 7.04.

Firefox 3 Beta 5:
http://dromaeo.com/?id=5552 (3282.80ms)
http://dromaeo.com/?id=5560 (3287.60ms)
SunSpider: 6794.0ms

WebKit
http://dromaeo.com/?id=5556 (3260.60ms)
http://dromaeo.com/?id=5563 (3225.40ms)
SunSpider: 5794.8ms


In the Dromaeo test there is for all practical purposes no difference between the two javascript engines. Sunspider showed a 1.17 factor favor toward the Webkit engine. There has been a lot of recent new traffic over acid3 testing and other performance metrics (http://ajaxian.com/archives/where-is-firefox-on-acid-3-here ). The Firefox ecosystem around its amazing set of add-ones (https://addons.mozilla.org/en-US/firefox/ ) is without question a key factor for me. The Mozilla foundations strong effort on standards, highly open and extensible platform win over a few percentage points from a Javascript benchmark. The acid3's focus on DOM scripting is important to me and so I would like to see that arrive in the Gecko engine though some of the comments of Mike Shaver (http://shaver.off.net/diary/2008/03/27/the-missed-opportunity-of-acid-3/ ) and Rob Sayre (http://blog.mozilla.com/rob-sayre/2008/03/26/acid3-is-basically-worthless/ ) regarding this do make sense to me.

I'm a loyal Firefox user and nothing I have seen from the Webkit camp has yet to give me any pause, though I am glad they are there. We need competition and pressure to drive development forward. It's always good to compare and I am still in a situation where as a developer I need to have various engines around for testing. I also played around with the new Next-Generation Java Plug-in (https://jdk6.dev.java.net/plugin2/ ) and was very impressed with it as well. Especially the easy javascript to applet communication the new plugin delivers.

take care
Doug