Saturday, June 7, 2008

Programming with closures

Recently I caught myself thinking that my programming habits are changing while programming in Groovy. In particular, I started using closures more and more to clean up my code, make it more DRYer, e.g. by not just merely using existing closures provided by libraries such as GDK, GORM, etc., but by creating my own closures.

Here's a small example from GrailsCrowd. The idea here is to either 'accept project participation invitation' or 'reject project participation invitation'. So, in the Controller, I factored out the common code of retrieving the Member, Project, redirecting to the appropriate action afterwards, etc. to a private method which takes a closure, and calling that closure for the actual action of 'acceptance' or 'rejection':


private def withProject(callable) {
def invitee = freshCurrentlyLoggedInMember()
def creator = Member.findByName(params.creator)
def project = GrailsProject.get(params.projectId)
//Call the closure
callable([project:project,creator:creator,invitee:invitee])
redirect(controller: 'mailbox')
}

def acceptParticipationInvitation = {
withProject {projectMap ->
projectMap.project.acknowlegeParticipationAcceptance(projectMap.creator,
projectMap.invitee, params.messageId.toLong())
}
}

def rejectParticipationInvitation = {
withProject {projectMap ->
projectMap.project.rejectParticipationInvitation(projectMap.creator,
projectMap.invitee, params.messageId.toLong())
}
}


IMO, this makes code cleaner, reusable, and more maintainable. Also, this style of programming with closures kind of replaces good old Template Method design pattern.

Keep on Groovying, folks!

Later...

Friday, May 2, 2008

Spice things up

I'm gonna do an unusual departure from posting work-related and technology-related stuff here.

You know that things between you and your significant other are starting to "spice up" again (the busy schedule at work for both, 16 months old at home, the daily routine, etc., cause some tension between spouses, etc) when you receive [funny] email like this from your spouse:

Dear Mr Kopylenko,
I'm writing you to inform that I will require some private time in order to complete the required documentation in order to process my Medicaid and Medicare applications , as well as some other paper work
Your full cooperation will be greatly appreciated and rewarded that same night.
Thank you in advance,
Dr Z Kopylenko
I did enjoy it :-)

Later...

Tuesday, April 15, 2008

Access RESTful API in 2 LOC

Today I was playing with json-lib and FriendFeed API in Groovy console and was able to fetch feed's JSON representation and do a simple result filtering in 2 lines of code! So, for example, here are all my recent twitter entries (filtered from all the other content e.g. different services like flickr, amazon, etc.):


import net.sf.json.*

def friendFeedJsonResponse = new URL('http://friendfeed.com/api/feed/user/dima767').text
JSONObject.fromObject(friendFeedJsonResponse).entries.
findAll { it.service.id == 'twitter' }.
each { println it.title }
I know it is a very simple example, but IMO, with an 'expressiveness' and 'compactness' of Groovy, in the majority of cases, there is no need for a 'wrapper' library and various web APIs could be used 'as is'

Later...

Thursday, April 10, 2008

Grails in a 'Cloud'

These days, the new generation of computing, so called 'cloud computing', where the infrastructure of the entire data centers is outsourced, abstracted, and hosted somewhere in the 'cloud' (on the Internet), is getting hugely popular. In a nutshell, it provides a so called 'low barrier to entry' for smaller internet companies to make their presence on the Internet market place without spending a fortune and ridiculous amount of time and energy buying their own hardware and maintaining their own data centers.

Amazon EC2 service hugely popularized this type of computing and early this week, Google jumped on the bandwagon with their App Engine exposing the power of their computing infrastructure, as well as the entire web development stack (Python-based - what else did you expect from Google) :-) to the army of ordinary, but creative software development minds.

After the announcement, Google has received feedback from developers requesting support for different programming languages/frameworks, and among Perl and Ruby, the requests for Java/Groovy/Grails are overwhelming.

Now that we have a rock-solid RAD web framework for Java (Grails that is), we are just missing the last piece of the puzzle: a rock-solid and affordable Grails hosting in a 'cloud'. The demand seems to be there. Hint, hint for ambitious start up companies :-)

Later...

Friday, April 4, 2008

So enjoyable

While hacking GrailsCrowd today, I caught myself thinking that programming in Groovy is such an enjoyable experience (for me). Take this method for example:


// Social feature: gets a list of 'colleagues' working on the same projects as *this* member
def getProjectColleagues() {
getActiveProjects().collect
{it.participants}.flatten().findAll
{it.participant.id != this.id}.collect {it.participant}
}
Is it possible to navigate "deep" object graph and express the same intent with the similar compactness in 'raw' Java code? I think not :-)

Later...

Sunday, March 16, 2008

Simple "Feedback" service

At our organization, I keep observing a recurring struggle to gather requirements and design public facing products. I mean, for example, when development teams are tasked to design systems that are targeted for students, all the requirements come from deans (supposedly 'product managers') without any kind of usability study and feedback from real users e.g. students. Also, the growing amount of 'phantom use cases' is being pushed into public facing products by our internal IT management without any real analysis of what the actual users would want and how they would actually use the system in question (or so it seems to me).

I was just discussing with my colleagues the fact that it would really be beneficial to gather feedback about systems from our student users, analyze it and then derive use cases from it for future product developments. IMO, that would really be more useful than simply coming up with those 'phantom requirements' ourselves.

To realize that, I'm thinking of creating a simple generic "Feedback" web application/service that would contain a 'rating', 'feedback/suggestions/comments' that users can submit. This should be a generic service that could gather feedback/reviews/ratings from students and/or internal corporate users for any systems, etc. (think Amazon reviews). And once we have all the data, we would be able to do all kinds of "collective intelligence' (data mining) analysis with it which would hopefully help us improve our products and make our product development more 'user-centric' instead of 'corporate-centric'.

I'm planning using Grails for the first prototype.

Later...

Tuesday, February 12, 2008

Hidden gem: grails.war.resources

In the process of packaging up the Grails application as a WAR in preparation for deployment to Tomcat, I needed to figure out a way to exclude the Oracle JDBC drver from WEB-INF/lib (we use 'shared' Oracle driver for our web apps which gets loaded by the Catalina's common ClassLoader). So I was thinking of a way to provide an "event hook" script, and while reading Grails' War.groovy I found a "hidden gem". That is a closure which is defined in the application's Config.groovy. So when this closure is defined, the War.groovy calls it with "staging directory" as a parameter and sets Ant as its 'delegate' right before zipping it up as a war.

So I was able to do the following (... from Config.groovy):


//Closure to customize the packaging of a war. In particular it excludes the Oracle JDBC driver
//from the war as it is loaded by the Catalina common ClassLoader when deployed to Tomcat
grails.war.resources = {stagingDir ->
delete(file: "$stagingDir/WEB-INF/lib/ojdbc14-10.2.jar")
}

This is real nice, but I don't think this feature is documented anywhere.

Later...