Tuesday 23 December 2008

Grails: OpenSearch in Fainit

This week I've been improving Fainit. One of the features that I've added is OpenSearch, it's really easy in Grails.

The result is that you can add a search engine in firefox, and search in the site like in this screenshot:

First you have to create a controller to server XML for OpenSearch:
def site_osd = {
render(template: '/common/site_osd', contentType:"text/xml")
}
To be more user friendly add a mapping in URLMappings.groovy
"/site_osd"(controller:'home', action: 'site_osd')
Next you have to do a template _site_osd.gsp to server XML descriptor
<?xml version="1.0"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>${message(code:'search.opensearch.title')}</ShortName>
<Description>${message(code:'search.opensearch.description')}</Description>
<Url type="text/html" method="get" template="${createLink(controller: 'search', absolute: true)}?q={searchTerms}"/>
</OpenSearchDescription>
And the last step is add Opensearch descriptor to your main layout (main.gsp) in the head section,, like this:
<link rel="search" href="${createLink(controller:'home',action:'site_osd')}" type="application/opensearchdescription+xml" title="${message(code:'search.opensearch.title2')}"/>
And that's it, really easy and good result.

Monday 1 December 2008

Coming Soon Fainit


Have you ever looked for a plumber? Do you know the best restaurant in your city? Do you ask your friends to know the best services and places?

I've been working the whole past month in a collaboratively site to share the best places and services with your friends and with the world. Now I have the first beta, the chosen name is fainit.com, it's a really beta service and for this period I have a limited number of users, try to register and start to share your recommendations.

Behind fainit there is a grails project, and great experience developing my first social network.

Enjoy the site and send me feedback.

Monday 20 October 2008

Grails: Hacking JSecurity plugin to supports OpenId

I'm currently developing an application for my new brand company and I'd like that supports authentication with username and password , and OpenId.

I could install Acegi Grails Plugin, but I'm very happy using JSecurity, ok no problem let's hack.
First, I have to install OpenId Plugin to support OpenId authenticantion, with this plugin I can manage login process and get openid identifier for OpenId users.

With JSecurity installed and done QuickStart, I need to pass Openid identifier in auth process, for this I've created class OpenIdContextHolder to save in a ThreadLocal context.
class OpenIdContextHolder{

private static final ThreadLocal openIdContextHolder = new ThreadLocal();

static void resetContext() {
openIdContextHolder.set(null);
}

static def getOpenIdIdentifier(){
openIdContextHolder.get()
}

static void setOpenIdIdentifier(id){
openIdContextHolder.set(id)
}

}
Now I have to hack AuthController to manage openid issues. The trick is when a user try to signIn, if I recive an OpenId identifier from OpenId Plugin then I put it in OpenIdContextHolder.

def login = {
if(openidService.isLoggedIn(session)){
return redirect(action:'signIn')
}

return [ username: params.username, rememberMe: (params.rememberMe != null), targetUri: params.targetUri ]
}

def signIn = {
// if is logged with openid set contextholder
if(openidService.isLoggedIn(session)){
def openId = openidService.getIdentifier(session)
OpenIdContextHolder.setOpenIdIdentifier(openId)
params.rememberMe = true
params.username = openId
params.password = "nullpass"
}
def authToken = new UsernamePasswordToken(params.username, params.password)

// continues the default generated code...
// ...
}
Next step is update JsecDbRealm generated. I have to retrieve OpenId identifier from ContextHolder, and lookup in my domain objects. I use the trick to register my openId users in JScecurity with the password 'secret' but if anyone try to access with username and password in this kind of users, I throw an Exception.
def authenticate(authToken) {
log.info "Attempting to authenticate ${authToken.username} in DB realm..."

// experimental!!
def openid = OpenIdContextHolder.getOpenIdIdentifier()
OpenIdContextHolder.resetContext()
log.info "OpenIdContextHolder request with openid: ${openid}"
if(openid){
def openidUser = User.findByOpenid(openid)
if (!openidUser)
throw new UnknownAccountException("No account found for user [${username}]")
log.info "Jsecurity with Openid ${openidUser.username} : ${openidUser.openid}"
authToken.password = 'secret'
authToken.username = openidUser.username
}else {
def openidUser = User.findByUsername(authToken.username)
if(openidUser?.openid?.trim()){
// trying to access with password for openid user
log.info "Jsecurity: Trying to access with password for user: ${openidUser.username} : ${openidUser.openid}"
throw new IncorrectCredentialsException("Invalid password for openid user '${authToken.username}', try to use openid instead user:password")
}
}

def username = authToken.username
// continues the default generated code...
// ...
The last step is redirect, openid users to signIn controller after logged (you only have to change it in OpenId Plugin).

And that's all folks.

Saturday 6 September 2008

New hopes and expectations

I've been very busy those months, because I have a lot of work to do. The main reason is that I quit my old job and I've started the adventure to work in my own company.

Now I work for the best company in the world Heralsoft, and of course the best company only can use the best technology, Grails :D.
To start, I eat my own food because the company website is a Grails application. In less than one week of development, I did a professional site with i18n (English and Spanish), blog (only English), feeds, authentication, searchable.

Visit my company home page and contact to me if you have any comment, or business oportunities.

Wednesday 18 June 2008

Script to deploy Grails Applications Remote

I spent some time this week doing a script to deploy my grails applications in remote Jetty container.
To do my deploy script I use Gant, with Grails support. To deploy War in Jetty you have two options:
  • Static. To do in static way you only have to copy your War to "webapps" directory and restart container.
  • Hot deploy. I prefer hot deploy to avoid restart container and I have to copy War in "webapps" directory and generate XML with context description.
To copy War remote, Ant.scp is the best way, make sure that you have Ant optional task and and jsch.jar in classpath (you can copy from Eclipse to GRAILS_HOME/lib for example).

To generate XML, Groovy is fantastic I mix some withWriter closure to generate the head of the document, and MarkupBuilder to do the hard work.

And this is the script:
import org.codehaus.groovy.grails.commons.GrailsClassUtils as GCU
import groovy.xml.MarkupBuilder

grailsHome = Ant.project.properties."environment.GRAILS_HOME"

includeTargets << new File ( "${grailsHome}/scripts/War.groovy" )

target('default': "Deploy war in server") {
depends(war)

// avoid War with dots (problems with static deploy)
def warTmp = "${grailsAppName}.war"
Ant.copy(file:warName, tofile:warTmp)

def dir = "/opt/jetty"

def host = "myhost.com"
def port = "22"
def user = "myuser"
def dsa = "${basedir}/scripts/key/id_dsa"


def swriter = new StringWriter()
def xml = new MarkupBuilder(swriter)

xml.Configure('class': "org.mortbay.jetty.webapp.WebAppContext") {
Set(name: 'contextPath','/')
Set(name: 'war'){
SystemProperty(name: 'jetty.home', default: '.')
mkp.yield("/webapps/${warTmp}")
}
Set(name: 'defaultsDescriptor'){
SystemProperty(name: 'jetty.home', default: '.')
mkp.yield("/etc/webdefault.xml")
}

}
def xmlDescriptor = "${basedir}/${grailsAppName}.xml"
new File(xmlDescriptor).withWriter{ writer ->
writer << '<?xml version="1.0" encoding="ISO-8859-1"?>\r\n'
writer << '<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">\r\n'
writer << swriter.toString()
writer << '\r\n'
}

echo "Deploying files to remote: ${host}"
scp(file: warTmp, todir: "${user}@${host}:${dir}/webapps", keyfile:"${dsa}", port:"${port}", passphrase:"", trust:"true")
scp(file: xmlDescriptor, todir: "${user}@${host}:${dir}/contexts", keyfile:"${dsa}", port:"${port}", passphrase:"", trust:"true")
echo "Finished :)"
}

I have an issue with hot deploy in Jetty and Grails (if anyone can help?) , but the script works well :D

Saturday 17 May 2008

The advantage of Grails

This week Spring Source have released, Spring Web Flow 2, I've read release notes and this make me think about the advantage of Grails.

Let's see release notes:
DSL to define flows the fact is XML+EL. I think is much readable Grails DSL to define WebFlows and less verbose.
  • Spring Javascript is a JavaScript abstraction framework that allows you to progressively enhance a web page with behavior.
Spring Javascript is built over Dojo to provide Ajax abstractions and rich widget behavior, and Grails do it, with tags, and Ajax agnostic calls (Prototype, Dojo, YUI, etc).
  • The Spring Faces module contains Spring's support for JavaServerFaces.
Who cares JSF? The EJBs in the view layer, jeje.
  • Using Spring Security to secure your flows in a declarative manner
A lot of security plugins for Grails.
  • Using Tiles for JSP page composition and Ajax partial-rendering
Grails layouts, templates and content negotiation are fantastic to do this.

And the best, Grails can be updated to use Spring Webflow 2.

But, the advantage goes further, with Servlet 3.0 and generation of web.xml, I can do it with Grails plugins, and really futher with Java 7 and closures.

Monday 12 May 2008

Great feedback in Grails Course

In last week I've been teaching in Groovy and Grails course, around 15 students, some people from Struts 1.x, some people from PHP, some portal developers with Vignette, and newbie people from University.

The people were very interested in Grails, and all said that is very easy learn, and create Web apps.

Great experience.

Thursday 17 April 2008

Grails course in Asturias, Spain

I'm pleased to annonce a Grails course in Asturias, Spain. The course is organized by the College of Engineers of Principado de Asturias, from 5th to 10th of may, around 15 hours training in Groovy and Grails technologies.

The title of course can be translate as "Agile Development in Java EE with Grails". If any one is interested, can contact to me by mail.

Here the slides (in Spanish) for my first class.

Monday 7 April 2008

Grails: Plugglabe Service, Reloaded

Yesterday I've read, the post from Josh Creed about a pluggable service in Grails and I've been thinking the way to do with IoC and wire provider with Spring.

Let's do it, with small test.

First my service class GreetService:
class GreetService {

def provider

def sayHello(String name){
provider.sayHello(name)
}

}
Now, two Providers:
class DevProvider {
def sayHello(String name){
println "DevProvider: hello ${name}"
}
}


class TestProvider {
def sayHello(String name){
println "TestProvider: hello ${name}"
}
}
Now I'm gonna use Spring DSL, in resources.groovy, to define provider bean that depends of environment:
import grails.util.*
beans = {
switch(GrailsUtil.environment) {
case "test":
provider(TestProvider)
break
case "development":
provider(DevProvider)
break
}
}
And that's all with Groovy and Grails magic, here the test:

class GreetServiceTests extends GroovyTestCase {

def greetService

void testGreet() {

greetService.sayHello("World!!!!!!")
}
}
// output: TestProvider: hello World!!!!!!
And in Grails console, another test:

def service = ctx.getBean("greetService")
service.sayHello("world")

// output: DevProvider: hello world

Thursday 13 March 2008

Grails: JettyStatic plugin released

The past month I did a plugin to server static content with jetty for grails, now I publish the plugin for anyone that could be useful.

Thursday 28 February 2008

Grails: Hacking paginate tag to make Ajax way

I one thing I miss in Grails is a remotePaginate Taglib (you can vote in Jira), today I'm going to hack paginate tag to make an Ajax paginate.

For this I have various options, I can modify the actual paginated taglib or the option I've chosen, hack with prototype observe the links generated by paginate tag.

To make easy, I've used observe tag, to capture clicks events, let's go with the example of list.gsp:

You have to wrap your list with div for this example 'ajax_wrap' to refresh with Ajax calls.
<div id="ajax_wrap">

<div class="list">
<g:render template="archive" collection="${archiveList}" var="archive"/>
</div>

<div class="paginateButtons">
<g:paginate action="list" total="${Archive.count()}" />
<g:observe classes="${['step','prevLink','nextLink']}" event="click" function="clickPaginate"/>
</div>

</div>
I've used g:observe to capture click events in generated links by g:paginate, and define a function handler clickPaginate that performs the Ajax calls.

Here function handler defnition:
function clickPaginate(event){
event.stop();
var link = event.element();
if(link.href == null){
return;
}

new Ajax.Updater(
{ success: $('ajax_wrap') },
link.href,
{
evalScripts: true
});
}
The Ajax call update the element 'ajax_wrap'.

With this you have an elegant way to make your list paginated effortlessly

Monday 18 February 2008

Grails: Tip for scaffolding required fields

Scaffolding is one of the most useful features of grails and customizing scaffolding it's basic for increase your productivity.

One thing I've customized is render a '*' for required fields, for this you have to install scaffolding templates with grails install-templates.

This is a fragment of the original templates/scaffolding/create.gsp,

props.each { p ->
if(p.type != Set.class) {
cp = domainClass.constrainedProperties[p.name]
display = (cp ? cp.display : true)
if(display) { %>
<tr class="prop">
<td valign="top" class="name">
<label for="${p.name}">${p.naturalName}:</label>
</td>
<td valign="top" class="value \${hasErrors(bean:${domainClass.propertyName},field:'${p.name}','errors')}">
${renderEditor(p)}
</td>
</tr>
<% } } } %>


I'm going to introduce a line, to check if the field has a constraint blank:false, and in this case render as a required field.

if(!cp?.blank) { %><span class="req">*</span><% } %>

The updated version complete:
   props.each { p ->
if(p.type != Set.class) {
cp = domainClass.constrainedProperties[p.name]
display = (cp ? cp.display : true)
if(display) { %>
<tr class="prop">
<td valign="top" class="name">
<% if(!cp?.blank) { %><span class="req">*</span><% } %>
<label for="${p.name}">${p.naturalName}:</label>
</td>
<td valign="top" class="value \${hasErrors(bean:${domainClass.propertyName},field:'${p.name}','errors')}">
${renderEditor(p)}
</td>
</tr>
<% } } } %>

That's all folks.

Monday 11 February 2008

My first Grails plugin

The grails plugin architecture it's fantastic, I've spent one afternoon doing a static content plugin, yeah there is a oficial static plugin, but I use jetty for development and production, and the static content it's uploaded by the users.
With Jetty servlet to server static content is enought for me, and with some configuration parameters, if required can be disabled.

Another advantage is that this way you can protect your static content with the Acegi plugin.

The first step it's create plugin:
grails create-plugin jettystatic
The project looks like a normal grails project, excepts that you have a plugin descriptor file.
In the JettystaticGrailsPlugin.groovy I've updated the web.xml generated:

def doWithWebDescriptor = { webXml ->
log.info "Jetty Static Initializing servlet"
def dir = application.config?.jettystatic.dir
if(!dir){
dir = './static'
}

if(application.config?.jettystatic.ignore){
log.info "Jetty Static: No jetty static servlet inicialized"
return
}

log.info "Jetty Static dir '${dir}' and mapping '${mapping}'"
def mapping = '/resources/*'
def servlets = webXml.'servlet'

servlets[servlets.size()-1] + {
'servlet' {
log.info 'Jetty Static generating <servlet> for static content'

'servlet-name'("jettystatic")
'servlet-class'("org.mortbay.jetty.servlet.DefaultServlet")

'init-param' {
'param-name'("resourceBase")
'param-value'(dir)
}

'init-param' {
'param-name'("dirAllowed")
'param-value'("false")
}

'init-param' {
'param-name'("gzip")
'param-value'("true")
}

'load-on-startup'("1")
}
}

def mappings = webXml.'servlet-mapping'
mappings[mappings.size()-1] + {
'servlet-mapping' {
'servlet-name'("jettystatic")
'url-pattern'(mapping)
}
}
}
The other thing I need, is a taglib to make links to static content, and I'd like that the tag transform from absolute path of static content to a relative web path, this make easy upload content, and server the content uploaded.

def resource = {attrs ->
def url = grailsApplication.config?.jettystatic.absolute.url
def dir = grailsApplication.config?.jettystatic.basepath
def file = attrs.file
def baseUrl = ""

if(dir){
if(!dir.endsWith('/')){
dir = dir + '/'
}
file = file.replaceFirst(dir,"")
}
if(url){
baseUrl = url
}else{
baseUrl = g.createLinkTo(dir:'resources')
}

def env = GrailsUtil.environment
if(env && env == "development"){
baseUrl = g.createLinkTo(dir:'resources')
}


if(!baseUrl.endsWith('/')){
baseUrl = baseUrl + '/'
}
out<< "${baseUrl}${file}"
}
At this point the only thing I have to do is package my plugin (grails package-plugin) to use in any project.

I can't imagine doing something like this in java and spend this time.

Wednesday 30 January 2008

Grails: Tag for Prototype observe

Continuing with Grails taglib, now I'm going to do a taglib to easy capture and group javascript events. I'll use prototype element observe method. Here the code:


def observe = {attrs ->
if(!attrs.noScript){
out << '<script type="text/javascript">'
}
if(attrs.element && attrs.element instanceof String){
printObserve("\$('${attrs.element}')", attrs.event, attrs.function, out)
}
if(attrs.element && attrs.element instanceof List){
attrs.element.each{it -> printObserve("\$('${it}')", attrs.event, attrs.function, out)}
}
if(attrs.classes && attrs.classes instanceof String){
printObserveClass(attrs.classes, attrs.event, attrs.function, out)
}
if(attrs.classes && attrs.classes instanceof List){
attrs.classes.each{ it -> printObserveClass(it, attrs.event, attrs.function, out)}
}
if(!attrs.noScript){
out << '</script>'
}
}

def printObserveClass(className, event, function, out){
out << "var classes = \$\$('.' + '${className}');"
out << "for(i = 0; i < classes.length; i++) {"
printObserve("classes[i]", event, function, out)
out << "}"
}

def printObserve(element, event, function, out){
if(event && event instanceof String){
out << "${element}.observe('${event}', ${function});"
}
if(event && event instanceof List){
attrs.event.each{ it -> out << "${element}.observe('${it}', ${function});"}
}
}




Now, some examples.

Simple use:

<g:javascript>
function testing(event){event.stop();alert('hello');}
</g:javascript>

<a id="idTest" href="http://grails.org">Grails Rulez</a>

<g:observe element="idTest" event="click" function="testing"/>


With a list of elements:

<g:observe element="${['id1','id2','id3']}" event="click" function="testing"/>


With a list of events:

<g:observe element="${['id1','id2','id3']}" event="${['click','load']}" function="testing"/>


With a list of classes:

<g:observe element="${['id1','id2']}" classes="${['class1','class2']}" event="change" function="testing"/>

Sunday 27 January 2008

Grails: Easy tags (remoteDiv)

TagLibs in Grails are extremely easy, you have some tags for Ajax like remoteField, remoteFuntion, remoteLink. But this time I need to get div asynchronous when page loads, this is very useful for example to show the users connected.

There isn't remoteDiv tag in Grails but in five minutes I've got my tag:


def remoteDiv = { attrs,body ->
def complete = ""
if(attrs.onComplete){
complete = ",onComplete: ${attrs.onComplete}"
}

out << """
<script type="text/javascript">
new Ajax.Updater(
{ success: '${attrs.id}' },
'${attrs.url}',
{
method: 'get',
evalScripts: true
${complete}
});
</script>
"""
}


An example of use:

<div id="testAjax"></div>
<g:remoteDiv
id="testAjax"
url="${createLink(action: 'show', id:'1')}"
onComplete="new Effect.Highlight('testAjax')"
/>


I've use prototype AjaxUpdater to do asynchronous request, it's not library agnostic like others remote tags in Grails but it's simple :D

Saturday 19 January 2008

Grails, be agile my friend

This month I've been testing Grails, (it was in my Todo list some time ago).
First I've read some about Groovy, and it's really easy the syntax and I like it.

Then, I've read about Grails architecture and the User Guide.

Impressions.


My impresion it's Grails is not much diferent than Appfuse, step by step:
  • GORM and Domain Model, is based in JPA and Hibernate. (domain centric approach explained by icoloma)
  • Controllers are based in Spring MVC.
  • IoC with Spring (of course).
  • Layouts based in Sitemesh.
  • Also you have Web Flow with Spring Web Flow.
  • Both are a simple WAR file.
This similars are very good for me, because I'm an old user of Appfuse and maybe can adapt Appfuse applications to Grails, I and can achive more agility.

Enterprise Ready?

Graeme Rocher gave a kick ass to someone that say no :D. I think it's ready, you have to take care about your code like in any other language.

The only thing I miss, is better support for Groovy and GSP in Eclipse (autocompletion, refactor) and manage the dependencies.

update: Guillaume Laforge thoughts about Enterprise Ready