The Kaptain on … stuff

10 May, 2009

Gracelets and Seam – a DSL for Facelets and Groovy with easy integration

Posted by: TheKaptain In: Development

Over the last year I’ve done a lot of work with JBoss Seam, and while it’s not Grails it’s also not that bad for a web framework. Facelets is the view technology of choice, and it’s certainly better than many alternatives, but at the heart it is still xml and all those brackets make me dizzy after awhile. Along comes Gracelets to provide a nice builder DSL and Groovy integration as a replacement for my xml woes. Yay! It also brings some great simplification to the creation of component libraries – including hot deployment. But enough of the sales pitch, let’s see if it works.

In order to test drive Gracelets, I took an existing Seam web-app and configured the web.xml with the GraceletsViewHandler in place of the standard SeamListener. I generally use Maven for dependency management, and I couldn’t find a repository hosting Gracelets so I installed the downloaded jars into my local repository and adding them to the web-app. The JBoss Seam Extension is also required.
[bash]
mvn install:install-file -Dfile=gracelets-api-2.0.0.jar -DgroupId=gracelets -DartifactId=gracelets-api -Dversion=2.0.0 -Dpackaging=jar -DgeneratePom=true
mvn install:install-file -Dfile=gracelets-impl-2.0.0.RC2.jar -DgroupId=gracelets -DartifactId=gracelets-impl -Dversion=2.0.0.RC2 -Dpackaging=jar -DgeneratePom=true
mvn install:install-file -Dfile=jboss_seam_2.0.0_all-1.0.11.jar -DgroupId=gracelets -DartifactId=jboss-seam-extension -Dversion=1.0.11 -Dpackaging=jar -DgeneratePom=true
[/bash]

[xml language=”true”]
<dependency>
<groupid>gracelets</groupid>
<artifactid>jboss-seam-extension</artifactid>
<version>1.0.11</version>
</dependency>
<dependency>
<groupid>gracelets</groupid>
<artifactid>gracelets-api</artifactid>
<version>2.0.0</version>
</dependency>
<dependency>
<groupid>gracelets</groupid>
<artifactid>gracelets-impl</artifactid>
<version>2.0.0.RC2</version>
</dependency>
[/xml]

The application was deployed as usual and fired up without a problem. For a test page I just created an index.groovy file in the root directory. According to the docs, a .groovy extension trumps .xhtml so that effectively replaced the front page of the app. Here’s the standard first page of a new web-app(straight from the Gracelets examples), with the xhtml builder.
[groovy language=”true”]
xh.html {
head { title("Hello World Example") }

body {
print { "Hello World @ " + new Date() }
}
}
[/groovy]

Not bad, let’s compare to the standard Facelets version, using a file based on the standard seam-gen created index.xhtml file. I’ve bound the instantiation of the Date object to a backing bean, since you can’t make an inline call to do it a standard Facelets view. I seem to recall seeing that Seam kept a component available to provide the present Date/Time, but I couldn’t find it offhand today.

[xml language=”true”]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<f:view contentType="text/html"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a="http://richfaces.org/a4j"
xmlns:s="http://jboss.com/products/seam/taglib">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Hello World Example</title>
<ui:insert name="head"/>
</head>
<body>
Hello World @ #{backingBean.date}
</body>
</html>
</f:view>
[/xml]

Notice I’ve also left the Seam and RichFaces tab library namespaces in the xml declaration. Although the Gracelets docs didn’t seem to easily confirm this, inclusion of the JBoss Seam extension also makes those libraries and their associated builders available by default for Gracelets views. Here’s a final example to leave you with that incorporates a couple of elements from those libraries and a quick and dirty use of .each for rendering, and even a couple of screenshots to show off the progression.
[groovy language=”true”]
def loremIpsum = ”’
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin tempor, mauris sed volutpat consequat, risus tellus ultrices
tortor, at sollicitudin felis erat vitae augue. Pellentesque habitant morbi tristique senectus et netus et malesuada fames
ac turpis egestas. Vestibulum tincidunt egestas viverra. Integer ullamcorper, ipsum id malesuada sollicitudin, nisl velit
ultricies purus, eu aliquet diam mi sit amet eros. Quisque arcu orci, consequat dictum vehicula a, pellentesque eu nisl.
”’
xh.html {
head { title("Hello World Example") }
body {
s.div(id:’aSeamDiv’, rendered:’true’) {
r.panel(header:’A RichFaces Panel’) {
println { "Hello World @ " + new Date() }
a(‘MyBlogLink’, href: ‘http://www.kellyrob99.com/blog’)
}
}
r.separator()
r.spacer()
r.simpleTogglePanel(header:’A RichFaces TogglePanel’){
println loremIpsum
}

def tableModel = loremIpsum.tokenize()[0..10]
def tableModel2 = loremIpsum.tokenize()[11..20]
table {
tr {
td {
tableModel.each { println it }
}
td {
tableModel2.each { println it }
}
}
}
}
}
[/groovy]

Not bad at all. I won’t bore you with the equivalent xml version – suffice it to say it takes up a lot more space. I haven’t even touched on the easy component/library features Gracelets provides yet, but I am already quite impressed simply by the replacement of xml with an equivalent but sparser syntax. And I don’t miss the need for closing tags much either. The documentation for the project is quite complete, rich with examples, at least for the standard jsf components(hint hint – more examples using Seam and RichFaces would be appreciated!) Give it a try and decide for yourself, but if it keeps going this way, it might become a reasonable alternative for Grails.

πŸ™‚

[nggallery id=3]

Reblog this post [with Zemanta]

4 Responses to "Gracelets and Seam – a DSL for Facelets and Groovy with easy integration"

1 | Lewis Gass

May 11th, 2009 at 5:49 am

Avatar

Article nicely done. I’ll try to get some more Seam/RichFaces examples out there in the next two weeks or so.

2 | TheKaptain

May 11th, 2009 at 6:22 am

Avatar

Thanks for the kind words Lewis. Great job on the software!
The initial roadblock I ran into, incidentally, was defining a RichFaces dataTable – could not get it to resolve a locally defined Collection as the model. Mind you, I stubbornly refused to use EL(as it somewhat negates the point of the investigation) so I probably just got the bracketing wrong.
Will look forward to reading your new examples and thanks again!

3 | Shawn Hartsock

May 11th, 2009 at 8:46 am

Avatar

Thanks for writing this up. This just shows off how Groovy is well positioned as a “cross-roads” technology that is ready to bring a lot of different worlds together. Keep on breaking ground!

4 | Gavin King

May 11th, 2009 at 8:27 pm

Avatar

Cool, thanks for the article! πŸ™‚

Comment Form