<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6974641895376633181</id><updated>2012-01-30T05:08:20.487-05:00</updated><category term='Unix'/><category term='AOP'/><category term='Aspects'/><category term='JVM'/><category term='use cases'/><category term='Closure'/><category term='personal'/><category term='refactoring'/><category term='web'/><category term='REST'/><category term='books'/><category term='development'/><category term='Amazon'/><category term='web development'/><category term='FriendFeed'/><category term='event'/><category term='internal'/><category term='wife'/><category term='resolution'/><category term='newyear'/><category term='Java'/><category term='Acegi'/><category term='API'/><category term='Groovy'/><category term='Dates'/><category term='Google'/><category term='Gant'/><category term='CAS'/><category term='HTTP'/><category term='Grails Crowd'/><category term='GORM'/><category term='feedback'/><category term='plugin'/><category term='family'/><category term='&quot;open source&quot;'/><category term='Grails'/><category term='summary'/><category term='Spring'/><category term='JSON'/><category term='closures'/><category term='Design Patterns'/><category term='usability'/><category term='scripts'/><category term='hook'/><category term='Cloud computing'/><title type='text'>myThoughts.each { println it }</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>53</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-4388737108844149624</id><published>2009-05-17T16:51:00.002-04:00</published><updated>2009-05-17T16:53:32.409-04:00</updated><title type='text'>Moving to wordpress.com</title><content type='html'>It's been a while since I posted. I've been busy. But, I'll continue to blog. I will be moving the blog to wordpress.com under kopylenko.com domain name. Will see you there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-4388737108844149624?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/4388737108844149624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=4388737108844149624' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4388737108844149624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4388737108844149624'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2009/05/moving-to-wordpresscom.html' title='Moving to wordpress.com'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-7942437053706554386</id><published>2008-12-31T09:35:00.005-05:00</published><updated>2008-12-31T09:55:38.233-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='resolution'/><category scheme='http://www.blogger.com/atom/ns#' term='summary'/><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><category scheme='http://www.blogger.com/atom/ns#' term='newyear'/><title type='text'>The year 2008 is done</title><content type='html'>That's it. The year 2008 has come to an end. Overall it was a very tough year - endless presidential election in the US (it felt like it), the global financial crisis, economic recession, etc. Personally, all of this didn't effect me that much (knock on the wood). Quite the opposite - it was more or less successful year for me:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Despite all of the political bullshit at work, I was able to go through it and successfully accomplish the given tasks, projects, etc.&lt;/li&gt;&lt;li&gt;I became a better Groovy and Grails hacker&lt;/li&gt;&lt;li&gt;I was able to finish and launch GrailsCrowd (which I really wanted to do)&lt;/li&gt;&lt;li&gt;I learned and therefore could "speak" Python, Erlang, and Scala&lt;/li&gt;&lt;li&gt;I started diving deep into FP (Functional Programming) via Erlang and Scala and started to appreciate its power and benefits&lt;/li&gt;&lt;li&gt;And last but not least, I became a better father!&lt;/li&gt;&lt;/ul&gt;My resolution for 2009 will be simple: I'd like to have a healthier lifestyle, work hard and care more for my family. Everything else will come.&lt;br /&gt;&lt;br /&gt;Happy NEW 2009 YEAR!&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-7942437053706554386?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/7942437053706554386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=7942437053706554386' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/7942437053706554386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/7942437053706554386'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/12/year-2008-is-done.html' title='The year 2008 is done'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-1225930495014554688</id><published>2008-11-26T07:54:00.005-05:00</published><updated>2008-11-26T08:26:17.834-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unix'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Dates'/><title type='text'>Groovy script as a *nix command line utility</title><content type='html'>I was having some fun with Groovy the other day as I created quick and dirty simple script to find out the duration between 2 dates. I've always wanted a handy utility that could answer more or less precisely questions like 'how much time has passed since I bought my MacBook pro?' or 'how old was I when I moved to the United States?', etc.&lt;br /&gt;&lt;br /&gt;So, without doing much research on what's available, I set out to use an excellent Joda time library in the Groovy script setting. And after 'shebanging' it (#!/usr/bin/env groovy) and installing it for example into /usr/sbin (provided that I have Groovy installed, $GROOVY_HOME set, and joda jar available ~/.groovy/lib), it's now available as a handy CLI utility where I could use it like this (how old was I when I started working at Rutgers): 'duration oct-9-1976 dec-9-2002' and the answer is: 26 years 2 months :-)&lt;br /&gt;&lt;br /&gt;I like Groovy's seamless integration with Java and its libraries as well as 'low ceremony' approach such as simple script without 'main method noise' requirement, implicit availability of the args array, etc.!&lt;br /&gt;&lt;br /&gt;There could be better ways to do this, but I had fun nevertheless :-)&lt;br /&gt;&lt;br /&gt;Here's the script:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/29050.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-1225930495014554688?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/1225930495014554688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=1225930495014554688' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/1225930495014554688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/1225930495014554688'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/11/groovy-script-as-nix-command-line.html' title='Groovy script as a *nix command line utility'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-4024080136935812102</id><published>2008-09-18T11:40:00.004-04:00</published><updated>2008-09-18T11:50:04.356-04:00</updated><title type='text'>Trying out Gist widget</title><content type='html'>Ok, I've been a user of Git distributed SCM system for a few months now. The Grails Crowd lives on GitHub as an open &lt;a href="http://github.com/dima767/grails-crowd/tree/master"&gt;source project&lt;/a&gt;. I must say I've been pretty happy so far with Git and GitHub. Few months ago GitHub guys introduced 'Gist' - a GitHub backed directory of code snippets (yes, versioned in Git repo, so all the benefits of Git apply).&lt;br /&gt;&lt;br /&gt;Here I'm just trying out an embeddable Gist widget:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/11440.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;When Gist will officially release an API, I might think about integrating it with Grails Crowd.&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-4024080136935812102?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/4024080136935812102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=4024080136935812102' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4024080136935812102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4024080136935812102'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/09/trying-out-gist-widget.html' title='Trying out Gist widget'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-4874887358841460003</id><published>2008-08-18T17:02:00.002-04:00</published><updated>2008-08-18T17:08:40.298-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Grails Crowd'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Grails Crowd has launched</title><content type='html'>After working on this project on and off for around 9 months (funny coincidence with pregnancy time frame :-) [life took precedence], I was finally able to finish and launch &lt;a href="http://grailscrowd.com"&gt;Grails Crowd&lt;/a&gt; - "the friendly online community (or directory) for Grails developers Worldwide".&lt;br /&gt;&lt;br /&gt;I will most likely open source the code and let the community drive the innovation and the future direction of the site. I have pretty much decided that the home of the code will be GitHub :-)&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-4874887358841460003?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/4874887358841460003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=4874887358841460003' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4874887358841460003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4874887358841460003'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/08/grails-crowd-has-launched.html' title='Grails Crowd has launched'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-4529913745294764775</id><published>2008-07-18T13:53:00.006-04:00</published><updated>2008-07-18T14:18:01.604-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='closures'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails Crowd'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Getting closer</title><content type='html'>As I'm getting closer to finishing up the essential code for GrailsCrowd, I noticed that I'm doing on the fly refactorings more seamlessly than I was able to do when I first started hacking with Groovy/Grails. And Groovy Closures are my friends these days :-)&lt;br /&gt;&lt;br /&gt;Here's a small example from the GrailsCrowd code base - 2 simple controller actions to query for Grails projects by tags, only with the difference that the first action gets all  the projects within a system for a specified tag (globally) and the other one gets projects for a tag for a specific member. Both actions operate on the Tag instance, so I refactored the common functionality of querying for Tags into a method which takes a closure:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;class GrailsProjectController {&lt;br /&gt; &lt;br /&gt;  ...&lt;br /&gt;  private def withTag(callable) {&lt;br /&gt;       if (!params.selectedTag) {&lt;br /&gt;           redirect(uri: '/notAllowed')&lt;br /&gt;       }       &lt;br /&gt;       def tag = Tag.findByName(params.selectedTag)&lt;br /&gt;       callable(tag)&lt;br /&gt;   }&lt;br /&gt;   ...&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And then the above mentioned actions became:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;class GrailsProjectController {&lt;br /&gt; &lt;br /&gt;  ...&lt;br /&gt;  def findByTagGlobally = {&lt;br /&gt;       def total = 0&lt;br /&gt;       def projects = []&lt;br /&gt;       withTag {tag -&gt;&lt;br /&gt;           if (tag) {&lt;br /&gt;               total = Tagging.countByTag(tag)&lt;br /&gt;               //Using CrieteriaBuilder here, so we could query by 'taggings' association&lt;br /&gt;               projects = GrailsProject.createCriteria().list(params) {&lt;br /&gt;                   taggings {&lt;br /&gt;                       eq('tag', tag)&lt;br /&gt;                   }&lt;br /&gt;               } //Criteria builder&lt;br /&gt;               //Sort by name since GrailsProject implements Comparable and the name property is its natural order&lt;br /&gt;               projects.sort()&lt;br /&gt;&lt;br /&gt;           } //if&lt;br /&gt;       } //Closure&lt;br /&gt;       render(view: 'list', model: [projects: projects, navMenu: 'discoverNavigationByTag',&lt;br /&gt;               paginatingController: controllerName, paginatingAction: actionName, total: total,&lt;br /&gt;               menuContext: [tag: params.selectedTag]])&lt;br /&gt;   }&lt;br /&gt;  &lt;br /&gt;   def findByTagForMember = {&lt;br /&gt;       def total = 0&lt;br /&gt;       def projects = []&lt;br /&gt;       def member = Member.findByName(params._name)&lt;br /&gt;       withTag {tag -&gt;&lt;br /&gt;           if (tag) {&lt;br /&gt;               if (!member) {&lt;br /&gt;                   redirect(uri: '/notAllowed')&lt;br /&gt;               }&lt;br /&gt;               total = Tagging.countByTagAndMember(tag, member)&lt;br /&gt;               //Using CrieteriaBuilder here, so we could query by 'taggings' association&lt;br /&gt;               projects = GrailsProject.createCriteria().list(params) {&lt;br /&gt;                   taggings {&lt;br /&gt;                       eq('tag', tag)&lt;br /&gt;                       eq('member', member)&lt;br /&gt;                   }&lt;br /&gt;               } //Criteria builder&lt;br /&gt;               //Sort by name since GrailsProject implements Comparable and the name property is its natural order&lt;br /&gt;               projects.sort()&lt;br /&gt;           } //if&lt;br /&gt;       } //Closure&lt;br /&gt;       render(view: 'list', model: [projects: projects, navMenu: 'memberProjectsNavigationByTag',&lt;br /&gt;               paginatingController: controllerName, paginatingAction: actionName, total: total,&lt;br /&gt;               menuContext: [tag: params.selectedTag, member: member]])&lt;br /&gt;   }&lt;br /&gt;   ...&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Also notice the use of GORM CriteriaBuilder which allowed to nicely query m:n 'Tagging' association class!&lt;br /&gt;&lt;br /&gt;Keep Groovying.&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-4529913745294764775?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/4529913745294764775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=4529913745294764775' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4529913745294764775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4529913745294764775'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/07/getting-closer.html' title='Getting closer'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-3645233945287406863</id><published>2008-06-07T07:40:00.007-04:00</published><updated>2008-06-07T08:04:22.070-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Closure'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails Crowd'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Programming with closures</title><content type='html'>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.&lt;br /&gt;&lt;br /&gt;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':&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;private def withProject(callable) {&lt;br /&gt;    def invitee = freshCurrentlyLoggedInMember()&lt;br /&gt;    def creator = Member.findByName(params.creator)&lt;br /&gt;    def project = GrailsProject.get(params.projectId)&lt;br /&gt;    //Call the closure&lt;br /&gt;    callable([project:project,creator:creator,invitee:invitee])&lt;br /&gt;    redirect(controller: 'mailbox')&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def acceptParticipationInvitation = {&lt;br /&gt;    withProject {projectMap -&gt;&lt;br /&gt;        projectMap.project.acknowlegeParticipationAcceptance(projectMap.creator, &lt;br /&gt;        projectMap.invitee, params.messageId.toLong())&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def rejectParticipationInvitation = {&lt;br /&gt;    withProject {projectMap -&gt;&lt;br /&gt;        projectMap.project.rejectParticipationInvitation(projectMap.creator, &lt;br /&gt;        projectMap.invitee, params.messageId.toLong())&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Keep on Groovying, folks!&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-3645233945287406863?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/3645233945287406863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=3645233945287406863' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/3645233945287406863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/3645233945287406863'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/06/programming-with-closures.html' title='Programming with closures'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-665597975394483267</id><published>2008-05-02T08:05:00.002-04:00</published><updated>2008-05-02T08:15:04.703-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='family'/><category scheme='http://www.blogger.com/atom/ns#' term='wife'/><title type='text'>Spice things up</title><content type='html'>I'm gonna do an unusual departure from posting work-related and technology-related stuff here.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;blockquote&gt;&lt;div id="1ez4" class="ArwC7c ckChnd"&gt;&lt;div&gt;Dear Mr Kopylenko,&lt;/div&gt; &lt;div&gt;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&lt;/div&gt; &lt;div&gt;Your full cooperation will be greatly appreciated and rewarded that same night.&lt;/div&gt; &lt;div&gt;Thank you in advance,&lt;/div&gt; &lt;div&gt;Dr Z Kopylenko&lt;br /&gt;&lt;/div&gt; &lt;/div&gt;&lt;/blockquote&gt;I did enjoy it :-)&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-665597975394483267?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/665597975394483267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=665597975394483267' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/665597975394483267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/665597975394483267'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/05/spice-things-up.html' title='Spice things up'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-4853757005142159123</id><published>2008-04-15T18:05:00.003-04:00</published><updated>2008-04-15T18:20:27.953-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FriendFeed'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='API'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Access RESTful API in 2 LOC</title><content type='html'>Today I was playing with &lt;a href="http://json-lib.sourceforge.net/"&gt;json-lib&lt;/a&gt; and &lt;a href="http://code.google.com/p/friendfeed-api/wiki/ApiDocumentation"&gt;FriendFeed API&lt;/a&gt; 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.):&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;import net.sf.json.*&lt;br /&gt;&lt;br /&gt;def friendFeedJsonResponse = new URL('http://friendfeed.com/api/feed/user/dima767').text&lt;br /&gt;JSONObject.fromObject(friendFeedJsonResponse).entries.&lt;br /&gt;  findAll { it.service.id == 'twitter' }.&lt;br /&gt;      each { println it.title }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;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'&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-4853757005142159123?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/4853757005142159123/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=4853757005142159123' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4853757005142159123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4853757005142159123'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/04/access-restful-api-in-2-loc.html' title='Access RESTful API in 2 LOC'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-9102778413288299797</id><published>2008-04-10T06:02:00.005-04:00</published><updated>2008-04-10T06:32:00.999-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Cloud computing'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><category scheme='http://www.blogger.com/atom/ns#' term='Amazon'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Grails in a 'Cloud'</title><content type='html'>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.&lt;br /&gt;&lt;br /&gt;Amazon EC2 service hugely popularized this type of computing and early this week, Google jumped on the bandwagon with their &lt;a href="http://googleappengine.blogspot.com/"&gt;App Engine&lt;/a&gt; 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.&lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://code.google.com/p/googleappengine/issues/detail?id=1&amp;amp;colspec=ID%20Type%20Status%20Priority%20Stars%20Owner%20Summary"&gt;overwhelming&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;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 :-)&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-9102778413288299797?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/9102778413288299797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=9102778413288299797' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/9102778413288299797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/9102778413288299797'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/04/grails-in-cloud.html' title='Grails in a &apos;Cloud&apos;'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-4631253598573293491</id><published>2008-04-04T16:25:00.005-04:00</published><updated>2008-04-04T16:36:48.917-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails Crowd'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>So enjoyable</title><content type='html'>While hacking &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;GrailsCrowd&lt;/span&gt; today, I caught myself thinking that programming in Groovy is such an enjoyable experience (for me). Take this method for example:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;// Social feature: gets a list of 'colleagues' working on the same projects as *this* member&lt;br /&gt;   def &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;getProjectColleagues&lt;/span&gt;() {&lt;br /&gt;       &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;getActiveProjects&lt;/span&gt;().collect&lt;br /&gt;           {it.participants}.flatten().findAll&lt;br /&gt;               {it.participant.id != this.id}.collect {it.participant}&lt;br /&gt;   }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Is it possible to navigate "deep" object graph and express the same intent with the similar compactness in 'raw' Java code? I think not :-)&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-4631253598573293491?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/4631253598573293491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=4631253598573293491' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4631253598573293491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4631253598573293491'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/04/so-enjoyable.html' title='So enjoyable'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-8155407690558158092</id><published>2008-03-16T11:28:00.002-04:00</published><updated>2008-03-16T11:58:50.896-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='feedback'/><category scheme='http://www.blogger.com/atom/ns#' term='use cases'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Simple "Feedback" service</title><content type='html'>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).&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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'.&lt;br /&gt;&lt;br /&gt;I'm planning using Grails for the first prototype.&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-8155407690558158092?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/8155407690558158092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=8155407690558158092' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/8155407690558158092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/8155407690558158092'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/03/simple-feedback-service.html' title='Simple &quot;Feedback&quot; service'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-6251130585807150217</id><published>2008-02-12T13:06:00.000-05:00</published><updated>2008-02-12T13:19:25.614-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web development'/><category scheme='http://www.blogger.com/atom/ns#' term='Closure'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Hidden gem: grails.war.resources</title><content type='html'>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.&lt;br /&gt;&lt;br /&gt;So I was able to do the following (... from Config.groovy):&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;//Closure to customize the packaging of a war. In particular it excludes the Oracle JDBC driver&lt;br /&gt;//from the war as it is loaded by the Catalina common ClassLoader when deployed to Tomcat&lt;br /&gt;grails.war.resources = {stagingDir -&gt;&lt;br /&gt; delete(file: "$stagingDir/WEB-INF/lib/ojdbc14-10.2.jar")&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This is real nice, but I don't think this feature is documented anywhere.&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-6251130585807150217?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/6251130585807150217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=6251130585807150217' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/6251130585807150217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/6251130585807150217'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/02/hidden-gem-grailswarresources.html' title='Hidden gem: grails.war.resources'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-8259694566547495939</id><published>2008-02-11T15:04:00.000-05:00</published><updated>2008-02-11T15:53:36.085-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='event'/><category scheme='http://www.blogger.com/atom/ns#' term='hook'/><category scheme='http://www.blogger.com/atom/ns#' term='Gant'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Script event hooks are cool</title><content type='html'>Grails has had the so called 'event hooks' for Gant scripts since 0.5. It basically is a way to tap into the Grails Gant scripts execution flow to customize build process, etc. It is elegantly implemented (as everything else in Grails) as a collection of closures in the Events.groovy script. The 'event closures' get called by Grails when the corresponding 'events' get generated in the Gant script e.g. a method 'event' is called with the event name as a parameter. So for example, event("StatusUpdate", [ "Status update event is called"]) would result in eventStatusUpdate { msg -&gt; } closure defined in Events.groovy being called.&lt;br /&gt;&lt;br /&gt;So, at work, for the typical Spring web applications we use Ant-based "common build" system originally created by the Spring guys. The common build uses ivy for the dependency resolution, so we have a custom ivyconf.xml which contains definitions for our local dependency repository, etc.&lt;br /&gt;&lt;br /&gt;Grails has an ivy plugin, but when installing it for each web app, it puts the default ivyconf.xml into the root of the web app. So, I needed a way to 'tap' into the _Install.groovy script of the plugin to copy our local invyconf.xml. Sure enough the script 'statusUpdate' hook did the trick.&lt;br /&gt;&lt;br /&gt;Here is the Events.groovy:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;static final ESS_IVYCONF_FILE_LOCATION = "$userHome/.common-build/ntg/common-build"&lt;br /&gt;&lt;br /&gt;eventStatusUpdate = { msg -&gt;&lt;br /&gt;   if(msg ==~ /.*ivyconf.xml.*/) {&lt;br /&gt;       println "Copying ESS ivyconf.xml from common-build global directory ..."&lt;br /&gt;       Ant.copy(todir: "${basedir}", overwrite: true) {&lt;br /&gt;           fileset(dir: "$ESS_IVYCONF_FILE_LOCATION") {&lt;br /&gt;               include(name: "ivyconf.xml")&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-8259694566547495939?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/8259694566547495939/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=8259694566547495939' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/8259694566547495939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/8259694566547495939'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/02/script-event-hooks-are-cool.html' title='Script event hooks are cool'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-3551005956984085119</id><published>2008-02-11T07:43:00.000-05:00</published><updated>2008-02-11T08:20:01.371-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CAS'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='internal'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Acegi'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Plugins for local needs</title><content type='html'>The Grails plugin system is great not only for creating all kinds of useful functionality available publicly, but also is a perfect framework to extract bits and pieces of reusable logic suitable only for internal corporate projects.&lt;br /&gt;&lt;br /&gt;At our organization we started finally using Grails for internal projects. The first small web application was done in a matter of a few days. But then when it was time to package it up as a 'war', we had a little dilemma and that's where Grails plugin system came to the rescue.&lt;br /&gt;&lt;br /&gt;In a nutshell, we use Spring Security (formerly known as ACEGI) together with JA-SIG Central Authentication Service, for all our auth/authz needs. For Grails applications, I did not choose Grails Acegi plugin as it does not seem to provide CAS authentication support (yet?). So we reverted back to good 'ol Spring resources.xml and dropped all the verbose Acegi bean definitions there (hopefully Spring Security 2 should reduce the 'configuration chaos' dramatically). Works just fine. But we have 3 "String" bean definitions there pertaining to CAS properties, such as 'casServiceUrlPrefix', 'casLoginUrl', and 'casValidateUrl'.  So, for the typical Spring  web app., we define those as JNDI-bound resources, like so:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;bean id="casServiceUrlPrefix" class="org.springframework.jndi.JndiObjectFactoryBean"&amp;gt;&lt;br /&gt;&amp;lt;property name="jndiName"&amp;gt;&amp;lt;value&amp;gt;java:comp/env/casServiceUrlPrefix&amp;lt;/value&amp;gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="casLoginUrl" class="org.springframework.jndi.JndiObjectFactoryBean"&amp;gt;&lt;br /&gt;&amp;lt;property name="jndiName"&amp;gt;&amp;lt;value&amp;gt;java:comp/env/casLoginUrl&amp;lt;/value&amp;gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="casValidateUrl" class="org.springframework.jndi.JndiObjectFactoryBean"&amp;gt;&lt;br /&gt;&amp;lt;property name="jndiName"&amp;gt;&amp;lt;value&amp;gt;java:comp/env/casValidateUrl&amp;lt;/value&amp;gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;So, when packaging application as a 'war' and deploying it to Tomcat, this is fine, but in the 'development' mode, in embedded Jetty, I would have liked to put this config somewhere else. Like conf/Config.groovy for example. That's where Grails plugin system came in, and with its wonderful SpringBeanBuilder I was able easily dynamically create those 3 bean definitions during assembly phase of the ApplicationContext, depending on the environment the application was running in.&lt;br /&gt;&lt;br /&gt;Here's the plugin:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;import grails.util.GrailsUtil as GU&lt;br /&gt;import org.springframework.jndi.JndiObjectFactoryBean&lt;br /&gt;&lt;br /&gt;class CasPropertiesResolverGrailsPlugin {&lt;br /&gt; def version = 0.1&lt;br /&gt; def author = "Dmitriy Kopylenko"&lt;br /&gt; def title = "This plugin is used to provide cas related properties to the Spring beans used for Spring Security config"&lt;br /&gt; def description = ''' The plugin participates in the creation phase of the Spring application context&lt;br /&gt;                       which is used to configure Spring Security related beans and dynamically provides&lt;br /&gt;                       'configuration beans' namely 'casServiceUrlPrefix', 'casLoginUrl', and 'casValidateUrl'&lt;br /&gt;                       depending on the environment in which Grails application is preparing to run.&lt;br /&gt;&lt;br /&gt;                       More specifically, if the environment is 'development' then the value is sourced from&lt;br /&gt;                       Grails Config instance. On the other hand, if the environment is 'production', the value&lt;br /&gt;                       is sourced from standard ess JNDI namespace.&lt;br /&gt;                    '''&lt;br /&gt;&lt;br /&gt; def dependsOn = [:]&lt;br /&gt;&lt;br /&gt; def doWithSpring = {&lt;br /&gt;     switch (GU.environment) {&lt;br /&gt;         case 'development':&lt;br /&gt;             casServiceUrlPrefix(java.lang.String, application.config.casServiceUrlPrefix)&lt;br /&gt;             casLoginUrl(java.lang.String, application.config.casLoginUrl)&lt;br /&gt;             casValidateUrl(java.lang.String, application.config.casValidateUrl)&lt;br /&gt;             break&lt;br /&gt;         case 'production':&lt;br /&gt;             casServiceUrlPrefix(JndiObjectFactoryBean) {&lt;br /&gt;                 jndiName = 'java:comp/env/casServiceUrlPrefix'&lt;br /&gt;             }&lt;br /&gt;             casLoginUrl(JndiObjectFactoryBean) {&lt;br /&gt;                 jndiName = 'java:comp/env/casLoginUrl'&lt;br /&gt;             }&lt;br /&gt;             casValidateUrl(JndiObjectFactoryBean) {&lt;br /&gt;                 jndiName = 'java:comp/env/casValidateUrl'&lt;br /&gt;             }&lt;br /&gt;             break&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;I'm sure there are other ways to do this, but that was fun nevertheless :-)&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-3551005956984085119?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/3551005956984085119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=3551005956984085119' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/3551005956984085119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/3551005956984085119'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/02/plugins-for-local-needs.html' title='Plugins for local needs'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-1334407431182209655</id><published>2008-02-05T11:01:00.000-05:00</published><updated>2008-02-05T11:06:13.856-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web development'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Grails 1.0 is golden!</title><content type='html'>Yes, after more than 2 years in the making, with the development team hard at work, the Grails 1.0 final has been officially released. IMO, this event is historical and a great milestone for "lightweight" web development on the JVM platform.&lt;br /&gt;&lt;br /&gt;Happy Grails hacking!&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-1334407431182209655?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/1334407431182209655/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=1334407431182209655' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/1334407431182209655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/1334407431182209655'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/02/grails-10-is-golden.html' title='Grails 1.0 is golden!'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-8177454028022821939</id><published>2008-02-01T09:46:00.000-05:00</published><updated>2008-02-01T09:49:17.934-05:00</updated><title type='text'>A year of blogging</title><content type='html'>Just a small milestone for me:  a year of blogging. It hasn't been that bad, and I really enjoyed it. I will certainly continue to do so.&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-8177454028022821939?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/8177454028022821939/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=8177454028022821939' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/8177454028022821939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/8177454028022821939'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/02/year-of-blogging.html' title='A year of blogging'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-632638253758174952</id><published>2008-01-08T06:39:00.000-05:00</published><updated>2008-01-24T11:30:10.136-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Aspects'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='AOP'/><title type='text'>Inspektr: open source audit trail and logging aspects for Java</title><content type='html'>After creating a lightweight audit trail and log capturing (for example to capture and log Exceptions in the structured way) "common" library for my organization, we've (2 of my colleagues) reviewed it, cleaned it up, added the statistics capturing module, and released it as an open source under Apache license.&lt;br /&gt;&lt;br /&gt;At its core, the library makes use of Spring's @AspectJ POJO-style aspects together with Java Annotations.&lt;br /&gt;&lt;br /&gt;Check it out, it's called Inspektr, and it's available &lt;a href="http://code.google.com/p/inspektr/"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-632638253758174952?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/632638253758174952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=632638253758174952' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/632638253758174952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/632638253758174952'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/01/inspektr-open-source-audit-trail-and.html' title='Inspektr: open source audit trail and logging aspects for Java'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-7199581569338873716</id><published>2008-01-08T06:32:00.000-05:00</published><updated>2008-01-08T06:36:49.756-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='&quot;open source&quot;'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>The Web has won... through open source</title><content type='html'>Some good and true observations in this &lt;a href="http://www.webware.com/8301-1_109-9843130-2.html"&gt;post&lt;/a&gt; :&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;In other words, open source lets enterprises focus on delivering customer value, rather than on the "overhead" of software (licenses, contract negotiations, closed APIs, etc.). "Old school" enterprises get this. "New school" web properties do, too. In fact, just about everyone is getting on board...except 20th-century software companies.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-7199581569338873716?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/7199581569338873716/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=7199581569338873716' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/7199581569338873716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/7199581569338873716'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2008/01/web-has-won-through-open-source.html' title='The Web has won... through open source'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-5329019083997618359</id><published>2007-12-27T13:35:00.000-05:00</published><updated>2007-12-27T13:43:41.915-05:00</updated><title type='text'>2008 resolution</title><content type='html'>Since it is 'fashionable' to have 'New Year resolutions', here goes mine. Not for the 'publicity', as no one should really care, but just for myself and for my personal record.&lt;br /&gt;&lt;br /&gt;So, in 2008, I would like to not judge anyone for anything. Do what I do best at work, try to help others achieve the level of experience and professionalism. And also, not to bother myself with all the intra-office political bullshit and think and care more about my loved ones, not "pointy-headed' bosses with 'tunnel vision'.&lt;br /&gt;&lt;br /&gt;Here you have it... Happy New 2008 YEAR!&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-5329019083997618359?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/5329019083997618359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=5329019083997618359' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/5329019083997618359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/5329019083997618359'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/12/2008-resolution.html' title='2008 resolution'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-2207456721928672485</id><published>2007-12-15T06:38:00.000-05:00</published><updated>2007-12-15T07:02:30.341-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='GORM'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails Crowd'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Fetch random GORM model</title><content type='html'>Despite busy schedule at work and a year old daughter at home, who now requires constant attention, I was able to get some time to work on the Grails community site (Grails Crowd).&lt;br /&gt;&lt;br /&gt;As a part of it, I wanted to have a feature to display a 'random' user (a 'member') In fact, keep displaying a random user as long as 'Discover users' link is being clicked. You know, kind of like Flickr's "Explore" feature. So with a help of standard JDK library features i.e. 'java.utils.Collections.shuffle()' and Groovy closures, here's what I've come up with:&lt;br /&gt;&lt;br /&gt;MemberController's action:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: #000000; font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;def findRandom = {&lt;br /&gt;        def member = null&lt;br /&gt;&lt;br /&gt;        withMemberIds { memberIds -&gt;&lt;br /&gt;            //Pick the last one&lt;br /&gt;            member = Member.get(memberIds[-1])&lt;br /&gt;            //Then remove it from the list&lt;br /&gt;            memberIds.pop()&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if(member) {&lt;br /&gt;            render(view: 'discover', model: [member: member])&lt;br /&gt;        }&lt;br /&gt;        else {&lt;br /&gt;            //No one is registered yet - just 'go home'&lt;br /&gt;            redirect(uri:'/')&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private def withMemberIds(closure) {&lt;br /&gt;        def memberIds = session.memberIds&lt;br /&gt;        if (!memberIds) {&lt;br /&gt;            memberIds = Member.withCriteria {&lt;br /&gt;                projections {&lt;br /&gt;                    property('id')&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            if (!memberIds.isEmpty()) {&lt;br /&gt;                //Some members are in the database:&lt;br /&gt;                //Shuffle 'em up&lt;br /&gt;                Collections.shuffle(memberIds)&lt;br /&gt;                session.memberIds = memberIds&lt;br /&gt;            }&lt;br /&gt;            else {&lt;br /&gt;                //No members are in the database&lt;br /&gt;                return&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        closure(memberIds)&lt;br /&gt;        if (memberIds.isEmpty()) {&lt;br /&gt;            session.memberIds == null&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It works like a charm.&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-2207456721928672485?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/2207456721928672485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=2207456721928672485' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/2207456721928672485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/2207456721928672485'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/12/fetch-random-gorm-model.html' title='Fetch random GORM model'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-8822876357506933840</id><published>2007-12-09T16:51:00.000-05:00</published><updated>2007-12-09T17:02:00.897-05:00</updated><title type='text'>"Agile" labs environment</title><content type='html'>I was asked by our management to lead the innovative software research of new technologies at our organization. I'm all for it. But personally I think what would be the first step in this undertaking is to have a little bit of freedom for our engineering team. By that I mean it would be great if our management supported and approved to have a some sort of a "labs" environment, consisting of a say Linux box with full root given to the engineering team, so the full freedom of experimentation could be achieved without the usual hurdles and roadblocks of a day-to-day operational and engineering teams interaction.&lt;br /&gt;&lt;br /&gt;If that somehow happens, I would have a hope :-)&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-8822876357506933840?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/8822876357506933840/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=8822876357506933840' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/8822876357506933840'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/8822876357506933840'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/12/agile-labs-environment.html' title='&quot;Agile&quot; labs environment'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-1262150540953552473</id><published>2007-12-07T09:22:00.001-05:00</published><updated>2007-12-07T09:37:20.464-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Why Grails is so 'close to home'</title><content type='html'>Here's another &lt;a href="http://www.nabble.com/RE%3A-jetty-vs-%22proper%22-application-servers---performance-p14212581.html"&gt;[big]&lt;/a&gt; reason why Grails is not a "foreign" technology for Java developers. I know, it's been said before, but this is a real world example of a Java person coming to Grails and experiencing this familiar state of things: 1) Create war; 2) Drop into any of the available Java Servlet container/app server 3) Sit back and relax (in the ideal world) :-)&lt;br /&gt;&lt;br /&gt;I'm not sure if the same is true for JRuby (On Rails), so I'm not going to speculate here ;-)&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-1262150540953552473?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/1262150540953552473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=1262150540953552473' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/1262150540953552473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/1262150540953552473'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/12/why-grails-is-so-close-to-home.html' title='Why Grails is so &apos;close to home&apos;'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-7499538576516932287</id><published>2007-12-05T20:07:00.001-05:00</published><updated>2007-12-05T20:07:37.819-05:00</updated><title type='text'>Web 2.0 "bubble" video</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;p&gt;&lt;object height='350' width='425'&gt;&lt;param value='http://youtube.com/v/fi4fzvQ6I-o' name='movie'/&gt;&lt;embed height='350' width='425' type='application/x-shockwave-flash' src='http://youtube.com/v/fi4fzvQ6I-o'/&gt;&lt;/object&gt;&lt;/p&gt;&lt;p&gt;Here is a great "web 2.0 bubble" video!&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-7499538576516932287?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/7499538576516932287/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=7499538576516932287' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/7499538576516932287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/7499538576516932287'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/12/web-20-video.html' title='Web 2.0 &amp;quot;bubble&amp;quot; video'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-1379660360193582876</id><published>2007-11-28T13:16:00.000-05:00</published><updated>2007-11-28T13:30:37.592-05:00</updated><title type='text'>Gravl - a full-featured Grails-based blogging software</title><content type='html'>Glen Smith, the man who created groovyblogs.org in around 20 hours, is doing it again. This time around, Glen is planning to create a full-featured &lt;a href="http://blogs.bytecode.com.au/glen/2007/11/28/1196248511519.html"&gt;blogging software&lt;/a&gt; and use all the latest "bells and whistles" of Grails like flexible UrlMappings, different plug-ins, tag libs, custom filters, Ajax integration, etc.&lt;br /&gt;&lt;br /&gt;The main motivation is to have it as a learning tool, demonstrating how to implement great web 2.0 (yes, I said it) :-) style of software in Grails. &lt;br /&gt;&lt;br /&gt;And the ambitious plan of Glen's is to have all of that implemented in around 1000 LOC (excluding GSPs, JavaScript, CSS)!&lt;br /&gt;&lt;br /&gt;Way to go, Glen! And I'll be waiting for Gravl.&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-1379660360193582876?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/1379660360193582876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=1379660360193582876' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/1379660360193582876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/1379660360193582876'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/11/gravl-full-featured-grails-based.html' title='Gravl - a full-featured Grails-based blogging software'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-4423867252597018159</id><published>2007-11-26T18:35:00.000-05:00</published><updated>2007-11-26T19:16:47.443-05:00</updated><title type='text'>Flight Level 'three niner zero'</title><content type='html'>If you are fascinated with commercial aviation, like I am, here is an excellent &lt;a href="http://flightlevel390.blogspot.com/"&gt;blog&lt;/a&gt; of the senior captain of the major US airline (Airbus A320 family of aircraft). When I read it, it really feels like I'm right there on the flight deck, flying with him! :-)&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-4423867252597018159?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/4423867252597018159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=4423867252597018159' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4423867252597018159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4423867252597018159'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/11/flight-level-three-niner-zero.html' title='Flight Level &apos;three niner zero&apos;'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-5025107227942592071</id><published>2007-11-23T23:19:00.000-05:00</published><updated>2007-11-23T23:25:03.093-05:00</updated><title type='text'>Rails vs [___]...</title><content type='html'>There is a series of Apple vs PC commercial parodies called Rails vs [PHP, Cold Fusion, Java, .NET, etc.] from railsenvy folks. There is a funny &lt;a href="http://youtube.com/watch?v=PLUS00QrYWw"&gt;one&lt;/a&gt; about Rails vs Django :-)&lt;br /&gt;&lt;br /&gt;I wonder, what Rails vs Grails would look like...?&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-5025107227942592071?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/5025107227942592071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=5025107227942592071' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/5025107227942592071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/5025107227942592071'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/11/rails-vs.html' title='Rails vs [___]...'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-6614130714735123232</id><published>2007-11-10T11:38:00.000-05:00</published><updated>2007-11-10T11:53:45.479-05:00</updated><title type='text'>Dude, where's my plug-in?</title><content type='html'>These are exciting times for Grails community. 1.0 RC1 is out in the wild and 1.0 final is well on its way to the big and long awaited release.&lt;br /&gt;&lt;br /&gt;As Grails core team is hard at work shaping up Grails core to be ready for the big 1.0, the Grails plug-in community has exploded with all kinds of useful &lt;a href="http://grails.codehaus.org/Plugins"&gt;plug-ins&lt;/a&gt; ranging from Rich clients to Security, performance and utility functionality, augmenting the core feature set of Grails.&lt;br /&gt;&lt;br /&gt;For example, the two recent plug-ins that guys at &lt;a href="http://www.cantinaconsulting.com/"&gt;Cantina consulting&lt;/a&gt; have provided are &lt;a href="http://grails.codehaus.org/Amazon+S3+Plugin"&gt;Amazon S3&lt;/a&gt; and &lt;a href="http://www.cantinaconsulting.com/grails-plugins/video-plugin/"&gt;Video&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's definitely a great time to be a "Grails hacker".&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-6614130714735123232?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/6614130714735123232/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=6614130714735123232' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/6614130714735123232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/6614130714735123232'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/11/dude-wheres-my-plug-in.html' title='Dude, where&apos;s my plug-in?'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-2854365674656667310</id><published>2007-10-09T10:05:00.000-04:00</published><updated>2007-10-09T10:17:19.874-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Fun with tags</title><content type='html'>I've been playing with groovyconsole the other day to experiment with some 'tag' (yes, the web2.0 tags) :-) manipulations, etc.  Let's say  I wanted  to build the del.icio.us style 'for:username' tag trickery, to send a message, save bookmark, etc. to any particular user's 'private inbox', etc. Extremely easy with Groovy:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;tags = ['tag1', 'tag2','for:dima','tag4','for:someoneelse']&lt;br /&gt;&lt;br /&gt;usersWhoShouldRecieveSomething = tags.findAll { it[0..3] == 'for:'}.collect { it - 'for:' }&lt;br /&gt;&lt;br /&gt;assert usersWhoShouldRecieveSomething == ['dima','someoneelse']&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-2854365674656667310?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/2854365674656667310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=2854365674656667310' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/2854365674656667310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/2854365674656667310'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/10/fun-with-tags.html' title='Fun with tags'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-8206907085363784762</id><published>2007-09-09T12:08:00.000-04:00</published><updated>2007-09-09T12:13:57.090-04:00</updated><title type='text'>Grailscrowd: open invitation</title><content type='html'>I've mentioned this idea before. I think it would be a great idea to design and develop a Grails community site similar to &lt;a href="http://www.workingwithrails.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;WorkingWithRails&lt;/span&gt;&lt;/a&gt; , which I think is great. So, whoever is interested in joining &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;grailscrowd&lt;/span&gt;.com project (will be built with Grails, of course), you are more than welcome to contact me.&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-8206907085363784762?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/8206907085363784762/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=8206907085363784762' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/8206907085363784762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/8206907085363784762'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/09/grailscrowd-open-invitation.html' title='Grailscrowd: open invitation'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-7303629178906907208</id><published>2007-09-02T10:11:00.000-04:00</published><updated>2007-09-09T10:59:45.379-04:00</updated><title type='text'>Grails is gaining velocity</title><content type='html'>Now that &lt;a href="http://grails.org/0.6+Release+Notes"&gt;Grails 0.6&lt;/a&gt; is out with a development speed improvements and bunch of new and exciting features i.e. &lt;sp&gt;&lt;/sp&gt;a DSL for Spring Web Flow, Joint Java/Groovy compiler, better REST support, etc., and the focus of the Grails team is now shifted towards getting 1.0 out of the door, it's time again for me to allocate some time for some serious hacking of the Grails "side projects"&lt;br /&gt;&lt;br /&gt;My tiny "web 2.0" project I mentioned about several times in the past, is kind of on hold now, pending the web UI design phase, which is going very slowly at the moment.&lt;br /&gt;&lt;br /&gt;I hope to pick up the speed on the development of the &lt;a href="http://code.google.com/p/grails-camelot/"&gt;Grails Camelot&lt;/a&gt; again.&lt;br /&gt;&lt;br /&gt;And I am also seriously thinking of creating a networking site for the Grails community with developer's profiles, sites built with Grails,  Grails projects, etc. i.e. grailscrowd.com. If anyone is interested in this idea, just let me know :-)&lt;br /&gt;&lt;br /&gt;So many things to do, so little time (plus I have a 8.5 months old &lt;a href="http://picasaweb.google.com/dima767/Oksana7MonthsOld/photo#5098891396970610482"&gt;daughter&lt;/a&gt; who needs constant &lt;a href="http://www.youtube.com/watch?v=tAsrY0DtH7g"&gt;attention&lt;/a&gt; at this stage of her life) :-)&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-7303629178906907208?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/7303629178906907208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=7303629178906907208' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/7303629178906907208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/7303629178906907208'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/09/grails-is-gaining-velocity.html' title='Grails is gaining velocity'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-81920821411864469</id><published>2007-09-02T09:47:00.000-04:00</published><updated>2007-09-02T10:06:15.249-04:00</updated><title type='text'>Groovy to the rescue</title><content type='html'>Last week, out of the blue, I was tasked with coming up with an automation of integration of two systems. I was given a week to complete it and bunch of words like "...this is an emergency project", "it needs to be done ASAP", "this is coming from the higher &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;management&lt;/span&gt; and this is very important for us", etc., the usual corporate B.S.&lt;br /&gt;&lt;br /&gt;I was so tired of "fighting" this corporate politics nonsense, so I just got right to it.&lt;br /&gt;&lt;br /&gt;The problem turned out to be quite simple. I needed to automate the daily feed of the photos (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;jpg&lt;/span&gt; files) of the students that our main photo department takes, from their "photo server" (NT, MS &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;SQL&lt;/span&gt; Server to keep student's records) to our main class rosters and &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;grading&lt;/span&gt; web based system (Spring web app &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;deployed&lt;/span&gt; on Solaris).&lt;br /&gt;&lt;br /&gt;I didn't think twice and chose Groovy to do the job. The simple script does query the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;SQL&lt;/span&gt; Server, iterates over the result set, renames the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;jpeg&lt;/span&gt; files (according to the naming scheme required by rosters app) and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;SFTPes&lt;/span&gt; them to the Solaris box.&lt;br /&gt;&lt;br /&gt;Using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;GroovySQL&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;AntBuilder&lt;/span&gt;, it turned out to be a very elegant, expressive and tiny solution. It was done in a couple of days and the script is now doing its job in production!&lt;br /&gt;&lt;br /&gt;Conclusion: I love Groovy! :-)&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-81920821411864469?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/81920821411864469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=81920821411864469' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/81920821411864469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/81920821411864469'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/09/groovy-to-rescue.html' title='Groovy to the rescue'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-5258473702386645179</id><published>2007-08-16T10:21:00.000-04:00</published><updated>2007-08-16T15:59:04.384-04:00</updated><title type='text'>The adoption of JPA</title><content type='html'>I've been meaning to start introducing JPA for the persistence layer of our web applications for a long time, but there was never a "right time". That is, in our organization, every project is "an immediate need", needs to be delivered ASAP, and it always feels like we're in some kind of a "panic mode". So introducing the "new piece" of technology stack to our developers in the middle of projects with high deadline pressures did not feel feasible to me. Plus the relationship with our DBAs and the state of our databases (highly de-normalized "legacy" and even new tables, for the reasons unknown to me, etc.) kind of leaves bad taste in the mouth. But that's all internal corporate politics that I have no control over.&lt;br /&gt;&lt;br /&gt;So, the last week a new such an immediate project came in and I decided to review it. It is a very simple CRUD application to maintain records of "emergency contact" for our students (and later for faculty/staff). It's a simple 1 web form backed by one de-normalized table. One of our developers assigned to this project started hacking (it is a typical Spring MVC app) with a Repository implemented as Spring JDBC (raw SQL - Oracle MERGE statement). It would be OK to leave it as it is, but I decided to "bite a bullet" and do the JPA implementation.&lt;br /&gt;&lt;br /&gt;Thankfully, the JPA spec authors took care of the poor souls like us who have to deal with "legacy DB schemas" and equipped with @Embeddable, @AttributeOverride tools I was able to map this denormilized table structure into our simple model. This eliminated a lot of LOC of manual SQL craft code and manual mapping of result set into the JavaBeans. The solution turned out to be very elegant with only few lines of code! My colleague, who is the assigned developer on the project, really appreciated it.&lt;br /&gt;&lt;br /&gt;Furthermore, with this JPA persistence model, we now could easily rewrite the front end in Grails and totally re-use it! That is my other plan - start introducing Grails to our organization, once 1.0 is out.&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-5258473702386645179?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/5258473702386645179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=5258473702386645179' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/5258473702386645179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/5258473702386645179'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/08/adoption-of-jpa.html' title='The adoption of JPA'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-9201238636495964130</id><published>2007-07-26T23:39:00.001-04:00</published><updated>2007-07-26T23:48:19.764-04:00</updated><title type='text'>Need a web designer</title><content type='html'>As I mentioned previously, I was doing my little side Grails based web 2.0 fun project on and off (time permitting). I've reached the point where the very basic set of essential features are implemented and I need to "dress it up" nicely. I was hoping that our web guru at work would be able to take care of that for me, but it didn't work out. So now, I'm looking for someone with great web design skills to transform the "beast" into the "beauty". I really like the layout and look and feel of flickr and want something similar. &lt;br /&gt;&lt;br /&gt;Again, my little web app is not intended to be a "next big thing", but I really want to finish it and deploy it in "wild".&lt;br /&gt;&lt;br /&gt;So, are there any web designers out there willing to help/participate? :-)&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-9201238636495964130?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/9201238636495964130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=9201238636495964130' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/9201238636495964130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/9201238636495964130'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/07/need-web-designer.html' title='Need a web designer'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-2715466292539812559</id><published>2007-07-09T16:23:00.000-04:00</published><updated>2007-07-09T16:43:41.868-04:00</updated><title type='text'>My web 2.0 application progress report</title><content type='html'>Just wanted to say that even though I do not have a lot of time to spend working on my little web 2.0 Grails based site, I've made quite a good progress with it. I must say that even though I have tons of ideas for new features as I go along with it, I need to draw a line and scope out the feature set for the initial release. Also I'm building it on the development SVN snapshots versions of Grails, so in this respect the ride is a little rougher, but I personally like to "live on the edge" :-)&lt;br /&gt;&lt;br /&gt;I'm almost at the point where I need to turn it over to a web designer for the best layout/UI possible (I just want it to look beautiful, as the site itself might not serve a great purpose other than be a nice looking "social time waster") I will speak to our Web designer guru at work to see if he could help me out, but if that doesn't happen, I'd be willing to seek help from "outside".&lt;br /&gt;&lt;br /&gt;I have some other plans e.g. build some cool web apps with Grails i.e. work on &lt;a href="http://code.google.com/p/grails-camelot/"&gt;Grails Camelot&lt;/a&gt; , build a social web app for the Grails development community (grailscrowd.com) similar to the &lt;a href="http://www.workingwithrails.com/"&gt;one&lt;/a&gt; for the Rails community, etc.&lt;br /&gt;&lt;br /&gt;If anyone else is interested in building something cool with Grails, just let me know :-)&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-2715466292539812559?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/2715466292539812559/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=2715466292539812559' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/2715466292539812559'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/2715466292539812559'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/07/my-web-20-application-progress-report.html' title='My web 2.0 application progress report'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-232933871464732278</id><published>2007-06-09T10:08:00.000-04:00</published><updated>2007-06-09T10:18:37.791-04:00</updated><title type='text'>Grails Camelot - the open source project</title><content type='html'>After a good &lt;a href="http://www.nabble.com/Idea%3A-Grails-based-open-source-project-tf3866576.html"&gt;discussion&lt;/a&gt; on the Grails users list, the exciting Grails-based open source project was &lt;a href="http://code.google.com/p/grails-camelot/"&gt;born&lt;/a&gt;. The vision is to have a web 2.0 style application for community generated software ideas. I hope that a great development team would form around this project and it would become a successful Grails "show case" application.&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-232933871464732278?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/232933871464732278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=232933871464732278' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/232933871464732278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/232933871464732278'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/06/grails-camelot-open-source-project.html' title='Grails Camelot - the open source project'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-2118092440151584579</id><published>2007-05-28T12:14:00.000-04:00</published><updated>2007-05-28T21:31:29.088-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP'/><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>RESTful web services - the book</title><content type='html'>Few days ago I've received a copy of the &lt;a href="http://www.amazon.com/RESTful-Web-Services-Leonard-Richardson/dp/0596529260/ref=sr_1_1/104-4093342-6740715?ie=UTF8&amp;s=books&amp;amp;qid=1180368894&amp;sr=1-1"&gt;RESTful web services&lt;/a&gt; book. As far as I understand, this is the very first comprehensive text on the subject matter. Since REST seems to be the "hot" topic these days, the book immediately drew my attention. I bought it, so I could learn in-depth about this topic.&lt;br /&gt;&lt;br /&gt;I just started reading it and all I could say that the book is excellent (IMO). Authors give "no bullshit" explanations about the "architecture of the world wide web", what are the advantages of using simple, yet powerful and ubiquitous architecture of HTTP to deliver lightweight services. They also define some architectural patterns (they call it ROA for Resource Oriented Architecture), show the comparison between "The big web services" (WS-*) and give plenty of examples (in Ruby, which is actually fine with me, since Ruby is a very easy to read and understand language). The examples include real world RESTful services from Amazon (S3 storage service), the various incarnations of the Atom Publishing Protocol, Google Maps, and del.icio.us.&lt;br /&gt;&lt;br /&gt;I like the foreword by DHH:&lt;br /&gt;&lt;br /&gt;"A renaissance of HTTP appreciation is building and, under the banner of REST, shows a credible alternative to what the merchants of complexity are trying to ram down everyone's throats; a simple set of principles that every day developers can use to connect applications in a style native to the Web... Every developer working with the Web needs to read this book"&lt;br /&gt;&lt;br /&gt;As I learn more about RESTful principles, I start to appreciate it more and more and favor it over the "Big web services".&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-2118092440151584579?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/2118092440151584579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=2118092440151584579' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/2118092440151584579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/2118092440151584579'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/05/restful-web-services-book.html' title='RESTful web services - the book'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-8091879267240339828</id><published>2007-05-20T09:37:00.000-04:00</published><updated>2007-05-28T14:53:57.698-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Could it be any easier?</title><content type='html'>Well here I am again, on the second week of development of my Grails based 'addictive time waster' web2.0 site (I'm not rushing and spend may be an hour a day on it). As I described in the previous post, I was having a blast with Grails custom codecs feature which enables adding various 'encoding/transformation' features to any arbitrary Java types with ease! Well, I'm continuing "abusing" custom codecs with a great level of success and most importantly with a lot of fun.&lt;br /&gt;&lt;br /&gt;As I noticed on almost all of those user generated content web2.0 style sites, there are some kind of a '&lt;span style="font-style: italic;"&gt;Submitted by: user234 x days ago&lt;/span&gt; type of a piece of info. So, I've decided to add 'time ago' type of a stat to my web app. I'll continue to show the 'Submission' class for the examples, representing user's submission of any kind. So in order to track when Submissions are created, I've added a 'createdOn' property:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;class Submission {&lt;br /&gt;&lt;br /&gt; ...&lt;br /&gt; Date createdOn = new Date()&lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That will take care of recording the date of submission. Now, when retrieving and showing the the submissions, there would need to be some kind of a calculation to show the 'x minutes/hours/days/weeks/months/years ago' info. So, I've decided to "abuse" the codecs feature and "attach" the "encoding" of the date type into the 'time ago' string to the java.util.Date type. Thanks to the "richness" of the Joda time library, I was able to do that easily and put the code into the custom codec:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;import org.joda.time.*&lt;br /&gt;&lt;br /&gt;class TimeAgoStringCodec { &lt;br /&gt;&lt;br /&gt; static encode = { date -&gt;&lt;br /&gt;  def start = new DateTime(date)&lt;br /&gt;  def end = new DateTime(new Date())&lt;br /&gt;  def ago = Minutes.minutesBetween(start, end).getMinutes()&lt;br /&gt;  if(ago == 0) {&lt;br /&gt;      return 'less then 1 minute ago'&lt;br /&gt;  }&lt;br /&gt;  else if(ago &lt; 60) {&lt;br /&gt;       return "$ago minute" + (ago &gt; 1 ? "s ago" : " ago")&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  ago = Hours.hoursBetween(start, end).getHours()&lt;br /&gt;  if(ago &lt; 24) {&lt;br /&gt;      return "$ago hour" + (ago &gt; 1 ? "s ago" : " ago")&lt;br /&gt;  }&lt;br /&gt;  ago = Days.daysBetween(start, end).getDays()&lt;br /&gt;  if(ago &lt; 7) {&lt;br /&gt;      return "$ago day" + (ago &gt; 1 ? "s ago" : " ago")&lt;br /&gt;  }&lt;br /&gt;  ago = Weeks.weeksBetween(start, end).getWeeks()&lt;br /&gt;  if(ago &lt; 4) {&lt;br /&gt;      return "$ago week" + (ago &gt; 1 ? "s ago" : " ago")&lt;br /&gt;  }&lt;br /&gt;  ago = Months.monthsBetween(start, end).getMonths()&lt;br /&gt;  if(ago &lt; 12) {&lt;br /&gt;      return "$ago month" + (ago &gt; 1 ? "s ago" : " ago")&lt;br /&gt;  }&lt;br /&gt;  ago = Years.yearsBetween(start, end).getYears()&lt;br /&gt;  return "$ago year" + (ago &gt; 1 ? "s ago" : " ago")&lt;br /&gt; }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And equipped with this codec, I am then able to call: submission.createdOn.encodeAsTimeAgoString() and viola, I have the proper 'time ago' for any Date type application-wide!&lt;br /&gt;&lt;br /&gt;Here I could conclude that adding 'codecs' to any arbitrary Java type application-wide is piece of cake in Grails, and also here is a great example of the advantage of Groovy's seamless integration with "raw Java" where I was able to make use of an existing Java library (Joda time) with zero integration overhead.&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-8091879267240339828?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/8091879267240339828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=8091879267240339828' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/8091879267240339828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/8091879267240339828'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/05/could-it-be-any-easier.html' title='Could it be any easier?'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-6591785530344327372</id><published>2007-05-13T09:59:00.000-04:00</published><updated>2007-05-28T14:41:49.170-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Permalink codec</title><content type='html'>So, for about a week I've been working on my fun little "social" Grails web application and I've been having a lot of fun.&lt;br /&gt;&lt;br /&gt;Yesterday, while &lt;a href="http://jyte.com/"&gt;jyting&lt;/a&gt; I've been taking a note of its URL structure. Let's say you have a claim, and then in order to see it, the URL to it is not something like http://jyte.com/claim/show/12345 , but rather more readable, like &lt;a href="http://jyte.com/cl/dima767.myopenid.com-is-the-only-grails-hacker-on-jyte"&gt;http://jyte.com/cl/dima767.myopenid.com-is-the-only-grails-hacker-on-jyte&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;That's called "permalink" (for permanent link) and is done by converting the text of the claim (or any user submition for that matter) into permalink string (removing all the special characters e.g. \W, and replacing them with '-'). Then permalink essentially becomes a searchable attribute of the submission, so instead of doing something like Claim.get(1234) you do Claim.findByPermalink(params.permalink). It's just a way of creating "user friendlier" interfaces.&lt;br /&gt;&lt;br /&gt;Thanks to Grails and its nice custom URL mapping, and custom codecs facility, I was able to implement "permalink" functionality very easily!&lt;br /&gt;&lt;br /&gt;Lets' say I have a domain class "Submission":&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;class Submission {&lt;br /&gt;  String title&lt;br /&gt;&lt;br /&gt;  //permalink property here is for nicer URLs&lt;br /&gt;  String permalink&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So then I simply create "PermalinkCodec" utility class and place it in grails-app/utils so the Grails "ExpandoMetaClass" machinery could "weave" this functionality into all Strings!&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;class PermalinkCodec {&lt;br /&gt;&lt;br /&gt;   static encode = { str -&gt;&lt;br /&gt;       str.toLowerCase().replaceAll(/\W/,'-')&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then in my "SubmissionController's" "save" action I do something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;...&lt;br /&gt;def save = {&lt;br /&gt;   def s = new Submission()&lt;br /&gt;   s.properties = params&lt;br /&gt;   s.permalink = params.title.encodeAsPermalink()&lt;br /&gt;   s.save()&lt;br /&gt;   ...&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And finally, i define the custom mapping:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;&lt;br /&gt;class MyAppUrlMappings {&lt;br /&gt;   static mappings = {&lt;br /&gt;      ...&lt;br /&gt;      "/s/$permalink" {&lt;br /&gt;         controller = 'submission'&lt;br /&gt;         action = 'show'&lt;br /&gt;      }&lt;br /&gt;      ...&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So this will give users nice URLs like http://myapp/s/my-shiny-and-the-best-in-the-world-submission instead of http://myapp/submission/show/1234&lt;br /&gt;&lt;br /&gt;I think it's a little thing, but nice, nevertheless.&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-6591785530344327372?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/6591785530344327372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=6591785530344327372' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/6591785530344327372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/6591785530344327372'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/05/permalink-code.html' title='Permalink codec'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-1155874587686887973</id><published>2007-05-07T09:11:00.000-04:00</published><updated>2007-05-07T09:24:38.431-04:00</updated><title type='text'>Groovy actors</title><content type='html'>I've been reading up yesterday about an interesting concept called &lt;a href="http://groovyactors.com/"&gt;groovy actors:&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;IMO, this is a very interesting and powerful programming model. Now, my brain is working hard, trying to figure out some interesting ideas that could be implemented with 'actors'.&lt;br /&gt;&lt;br /&gt;How about a "loosely-coupled demand/supply engine"  where  some people submit their "needs" and others submit their "offers" and the system does the matching and bring the parties together. Kinda like craigslist, but without people actually manually searching through the classifieds. Instead, they just express their needs and the system does the rest...&lt;br /&gt;&lt;br /&gt;Another one, could be the automated "matchmaking engine", etc.&lt;br /&gt;&lt;br /&gt;Does something like this exist already?&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-1155874587686887973?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/1155874587686887973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=1155874587686887973' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/1155874587686887973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/1155874587686887973'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/05/groovy-actors.html' title='Groovy actors'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-707372805877512563</id><published>2007-04-26T21:58:00.000-04:00</published><updated>2007-04-26T22:04:06.642-04:00</updated><title type='text'>Jyting</title><content type='html'>Ever since I've signed up for a &lt;a href="http://jyte.com/"&gt;Jyte&lt;/a&gt; account, I've been "jyting" more and more every day. It is actually quite addicting, so now I'm convinced that our upcoming "community" site should be Jyte-like. Please note, not a Jyte clone, but Jyte-like ;-)&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-707372805877512563?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/707372805877512563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=707372805877512563' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/707372805877512563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/707372805877512563'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/04/jyting.html' title='Jyting'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-7440070712746398713</id><published>2007-04-23T10:07:00.001-04:00</published><updated>2007-04-23T10:07:42.233-04:00</updated><title type='text'>Twitterfeed</title><content type='html'>Testing twitterfeed.com ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-7440070712746398713?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/7440070712746398713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=7440070712746398713' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/7440070712746398713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/7440070712746398713'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/04/twitterfeed.html' title='Twitterfeed'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-5521572199649869124</id><published>2007-04-22T19:27:00.000-04:00</published><updated>2007-04-22T19:40:42.114-04:00</updated><title type='text'>OpenID enabled...</title><content type='html'>I've been reading some blogs and watching some introductory videos about OpenID today and I kinda like what I heard/saw. I think that by OpenID-enabling a "social" web site will help its adoption as there are many web 2.0 startups embracing OpenID and many more are coming aboard including giants like AOL and Microsoft.For the users of those sites, OpenID makes it easier to manage their identity and enables to participate in many, many, many "social networks" (OpenID-enabled) without a hassle. Plus a sea of endless possibilities to inter operate between OpenID networks, etc.&lt;br /&gt;&lt;br /&gt;I'm seriously thinking of building support for OpenID into our upcoming site. I will be reading the OpenID spec in the upcoming weeks to get myself familiar with the technology. What would be cool is Grails support (plugin) for OpenID!&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://jyte.com/widget/claim/openid-will-help-new-web-2.0-startups-to-succeed" style="border: 1px solid rgb(119, 119, 119); width: 400px; height: 60px;" scrolling="no"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-5521572199649869124?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/5521572199649869124/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=5521572199649869124' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/5521572199649869124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/5521572199649869124'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/04/openid-enabled.html' title='OpenID enabled...'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-14819733478068512</id><published>2007-04-20T16:48:00.000-04:00</published><updated>2007-04-20T17:07:21.323-04:00</updated><title type='text'>New adventure</title><content type='html'>After thinking about doing something exciting e.g. building a web 2.0 style site that one day could become "the next best thing" :-) for a while with my colleagues, we've finally decided to go ahead with one idea. We would go ahead and build it, test if it will work or not, etc. No VC, no big expenses, no day job quitting, etc. The only thing we've decided to do is to register an LLC., get a cheap web hosting (for now), then "hack" the application and put it out there. The only investment would be our spare time and some money for expenses like registering a company and web hosting.&lt;br /&gt;&lt;br /&gt;I'm excited about it for several reasons, because:&lt;br /&gt;    a) it's something different from doing my day to day job (working for "uncle Sam")&lt;br /&gt;    b) we will be building it with Grails!&lt;br /&gt;    c) Grails community is great!&lt;br /&gt;    d) and if we're lucky, we could "make some money" somehow ;-)&lt;br /&gt;&lt;br /&gt;If anyone reading this could give a word of advice about decent/modern Java web hosting solution, that would be appreciated.&lt;br /&gt;&lt;br /&gt;We will be registering a domain name for our LLC., putting "the new project" blog there, and will be doing updates about our "new adventure" in that blog.&lt;br /&gt;&lt;br /&gt;Stay tuned...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-14819733478068512?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/14819733478068512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=14819733478068512' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/14819733478068512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/14819733478068512'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/04/new-adventure.html' title='New adventure'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-1926713907575446460</id><published>2007-04-02T19:40:00.000-04:00</published><updated>2007-04-02T20:10:30.634-04:00</updated><title type='text'>Trip to Indiana</title><content type='html'>Here I am, in my room of a nice Marriott hotel, located in a beautiful small town called Bloomington. That's in Indiana, about 50 miles from Indianapolis. We (me and my colleague) are here on the business trip to IU (Indiana University) to meet the technical team behind &lt;a href="http://rice.kuali.org/"&gt;Kuali Rice&lt;/a&gt; project. Our organization is at the phase of evaluating different enterprise workflow and rules engines, and since Rice effort is built by higher education institution(s), it kind of makes sense for us to get involved with, I guess.&lt;br /&gt;&lt;br /&gt;Anyway, Kuali is built on Spring, CAS, Acegi (in the future). Our management has "donated" both me and my colleague to join the architecture team for the purpose of helping out with the architecture of Rice, since I am an expert in Spring and my pal is a CAS (http://www.ja-sig.org/products/cas/) project lead.&lt;br /&gt;&lt;br /&gt;So we met the team this afternoon (nice bunch of guys) and they showed us around Kuali and the Kuali Rice. I can't say that I'm impressed so far (heavy, heavy use of XML, XSLT, which I'm not a big fan of; use of Apache OJB for the persistence layer, etc.), but I could say that only time will tell as we dig deeper into it. May be we will be able to convince them to re-evaluate some of the technology choices i.e. use of JPA for the persistence  and  Mule for the KSB (Kuali Service Bus), and may be I'd be able to sneak in some Groovy in there to define a nice DSL for the Workflow and Business Rules definitions ;-) But until I could fully understand the architecture, I'm not going to speculate anymore.&lt;br /&gt;&lt;br /&gt;Hopefully everything goes fine this week, so on Friday I could safely return to my beautiful, young wife and my adorable daughter, whom I already miss!&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-1926713907575446460?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/1926713907575446460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=1926713907575446460' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/1926713907575446460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/1926713907575446460'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/04/trip-to-indiana.html' title='Trip to Indiana'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-1184919282470782844</id><published>2007-03-26T14:38:00.000-04:00</published><updated>2007-03-26T14:44:52.216-04:00</updated><title type='text'>Time to look back</title><content type='html'>It's that time of the year again. No, I'm not talking about the Tax submission time. I'm talking about the "annual performance review" period at my organization. So, I'm going to be busy at work trying to craft a fancy "self appraizal" with a list of great accomplishments that helped my organization be the best of the best and stay in business. &lt;br /&gt;&lt;br /&gt;[Update: I just received a word from my boss that he needs it ASAP]&lt;br /&gt;&lt;br /&gt;Now I just need to remember, what the hell did I accomplish...?&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-1184919282470782844?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/1184919282470782844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=1184919282470782844' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/1184919282470782844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/1184919282470782844'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/03/time-to-look-back.html' title='Time to look back'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-3621986849788850081</id><published>2007-02-25T14:16:00.001-05:00</published><updated>2007-02-28T16:30:19.185-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Groovy adoption continues</title><content type='html'>There are a lot of heated debates lately about Java vs dynamic languages such as  Ruby and Groovy,  the  Ruby vs Groovy, RoR vs Grails, etc. Some folks say that Groovy is a failure, that it's a hacker's toy language and that it's much slower (cause it's doing all the wonderful meta object magic at runtime) than "raw" Java. Of course it's slower, but come on, we live in the 21st century and with the computing power available and type of work we do (for typical web applications, anyway) does it really matter? And of course, as we all might know, that the most time is spent in the database and passing data over the wire. After all, if one needs pure real time performance or builds aircraft management system, than yes, choose the right tool for the job i.e. real time C, Ada or even Assembly.&lt;br /&gt;&lt;br /&gt;Anyway, I've got this new project assignment - it's a small and simple CRUD application with several screens backed by Oracle. I didn't choose Grails yet, as the DB schema is so twisted that it wouldn't map naturally to the domain. Instead I've decided to introduce some Groovy via Spring 2.0 dynamic language integration. I've written controllers, validators and repository in Groovy. Here's the code snippet from simple Spring controller implemented in Groovy:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;class AvailableCourseSearchController extends AvailableCourseBaseController implements InitializingBean {&lt;br /&gt;  &lt;br /&gt;   AvailableCourseRepository availableCourseRepository&lt;br /&gt;  &lt;br /&gt;   public ModelAndView processFormSubmission(HttpServletRequest request, HttpServletResponse response,&lt;br /&gt; Object command, BindException errors) throws Exception {&lt;br /&gt;       def availableCourses =&lt;br /&gt;           this.availableCourseRepository.findAllByCourse(&lt;br /&gt;               new Course(unitOfRegCode:request.getParameter('unitOfRegCode'),&lt;br /&gt;                       offeringUnitCode:request.getParameter('offeringUnitCode'),&lt;br /&gt;                       subjectCode:request.getParameter('subjectCode'),&lt;br /&gt;                       courseId:request.getParameter('courseId')))&lt;br /&gt;      &lt;br /&gt;       if (availableCourses.isEmpty()) {&lt;br /&gt;           errors.reject("courses.not.found")&lt;br /&gt;           return showForm(request, errors, getFormView())&lt;br /&gt;       }&lt;br /&gt;       def courseHolder = new CourseHolder('courses':availableCourses)&lt;br /&gt;       request.getSession().setAttribute(getCommandName(), courseHolder)&lt;br /&gt;       new ModelAndView(getSuccessView(), ['courseHolder':courseHolder,'suffixAList':suffixAList,'athleteCodeList':athleteCodeList])&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And then the implementation of the course repository uses groovy.Sql to query and construct Course object. It's no JPA of course, but for simple case like this it works like a charm:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-weight: bold; color: green; background-color: rgb(0, 0, 0); font-size: 13px; line-height: 14px; width: 98%;"&gt;&lt;code&gt;class AvailableCourseRepositoryImpl implements AvailableCourseRepository {&lt;br /&gt;&lt;br /&gt;    Sql db&lt;br /&gt;&lt;br /&gt;    void setDataSource(DataSource dataSource) {&lt;br /&gt;        this.db = new Sql(dataSource)&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;   &lt;br /&gt;    List findAllByCourse(Course criteria) {&lt;br /&gt;        def query = buildDynamicQueryString(criteria)&lt;br /&gt;        def courses = []&lt;br /&gt;        this.db.eachRow(query) { courseRow -&gt;&lt;br /&gt;            courses &lt;&lt; new Course('unitOfRegCode':courseRow.unit_of_reg_cd,&lt;br /&gt;                     'offeringUnitCode':courseRow.offering_unit_cd,&lt;br /&gt;                     'subjectCode':courseRow.subj_cd,&lt;br /&gt;                     'courseId':courseRow.course_no,&lt;br /&gt;                     'courseTitle':courseRow.course_title,&lt;br /&gt;                     'suffixA':courseRow.suffix_a,&lt;br /&gt;                     'unavailable':courseRow.course_deleted_ind == 'N'?false:true,&lt;br /&gt;                     'required':courseRow.required_ind == 'N'?false:true,&lt;br /&gt;                     'athleteCode':courseRow.athlete_cd,&lt;br /&gt;                    'id':courseRow.id) }&lt;br /&gt;        return courses&lt;br /&gt;    }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This usage of Groovy in these simple scenarios proved to be simple and expressive. The next step is a full-blown Grails application!&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-3621986849788850081?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/3621986849788850081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=3621986849788850081' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/3621986849788850081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/3621986849788850081'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/02/groovy-adoption-continues_1902.html' title='Groovy adoption continues'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-5693851961194414147</id><published>2007-02-22T11:40:00.000-05:00</published><updated>2007-02-25T14:20:27.520-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Grails will survive</title><content type='html'>Some people have an &lt;a href="http://www.xeniumhk.com/blog/?postid=57"&gt;opinion&lt;/a&gt; that Grails will fail. I have an opposite opinion that Grails will "survive".&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-5693851961194414147?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/5693851961194414147/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=5693851961194414147' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/5693851961194414147'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/5693851961194414147'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/02/grails-will-survive.html' title='Grails will survive'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-4950137530136541367</id><published>2007-02-14T10:14:00.000-05:00</published><updated>2007-02-25T14:21:02.950-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='books'/><title type='text'>Founders at work - the book</title><content type='html'>Today is the first significant snow storm of the season in the North East. Finally I arrived at work (after around a 3 hours of fun commute). Of course the train had to break down somewhere between Newark Penn and EWR station, so we (unfortunate passengers) were sitting there for about 40 minutes.&lt;br /&gt;&lt;br /&gt;Nevertheless, I wasn't bored at all because I had something interesting to read. The new &lt;a href="http://www.amazon.com/Founders-Work-Stories-Startups-Early/dp/1590597141/sr=8-1/qid=1171466416/ref=pd_bbs_sr_1/103-9351588-9299060?ie=UTF8&amp;s=books"&gt;book&lt;/a&gt; called "Founders at work" has arrived last night. The book is unique (IMO) in that it's a collection of interviews of the "fathers" of successful "startups" who are now millionaires. Founders of such companies as PayPal, Adobe, Apple, Yahoo, Hotmail, del.icio.us, 37signals, Tivo, Firefox, to name a few, are talking about all the things that they had to do inside and out to make their companies where they are today - from initial idea, implementation, initial funding, and ups and downs of the early days.  The stories are incredible and they show that those folks are not "super humans", but just very smart and motivated people and in many ways they are just like "the rest of us".&lt;br /&gt;&lt;br /&gt;I have a feeling that this read will be very refreshing and motivational for me ;-)&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-4950137530136541367?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/4950137530136541367/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=4950137530136541367' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4950137530136541367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4950137530136541367'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/02/founders-at-work-book.html' title='Founders at work - the book'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-67967055253654639</id><published>2007-02-11T08:39:00.000-05:00</published><updated>2007-02-25T14:21:21.392-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Groovy adoption begins</title><content type='html'>&lt;blockquote&gt;&lt;/blockquote&gt;After virtually being in the Groovy and Grails world for a couple of months - that is reading GINA and Definitive guide to Grails books and just playing around with Grails, I finally decided to start slowly introducing this wonderful language and framework at work.&lt;br /&gt;&lt;br /&gt;So I decided to "just do it". The first opportunity came as there is a need to rewrite a simple CRUD type of an application written in Oracle forms (BTW, this app is used by one person only one time a year) That would be the typical Spring stack app. At first one might think that it would be a perfect candidate for Grails, but then several factors decided against it: the db schema is so messed up that even "raw" Hibernate mapping would not be able to help (it doesn't have any PK for instance; tables are terribly denormalized... agrrr); and also I decided to wait until Grails matures a little, so I would have easier times of pushing it through our "red tape".&lt;br /&gt;&lt;br /&gt;So I've just introduced a simple helper written in Groovy, using groovy.Sql to do a simple DB update. Then injected that Groovy implementation into a "raw" java DAO using Spring 2.0 dynamic language support. I'll tell you one thing - the clarity of the code is even better than using JdbcTemplate (Oops.. did I actually say it) :-)&lt;br /&gt;&lt;br /&gt;Next step is to rewrite the SimpleFormControllers in Groovy to reduce the amount of code in half.&lt;br /&gt;&lt;br /&gt;And then fully rewrite one of our simpler Spring apps (namely netid query) in Grails (shhh... don't tell anyone...I've already done it... When the time is right I'll introduce it to our crowd at work)&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-67967055253654639?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/67967055253654639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=67967055253654639' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/67967055253654639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/67967055253654639'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/02/groovy-adoption-begins.html' title='Groovy adoption begins'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-6188354847477761700</id><published>2007-01-24T15:59:00.000-05:00</published><updated>2007-02-14T10:45:37.883-05:00</updated><title type='text'>Operation "freedom from DBA's"</title><content type='html'>The never ending saga continues... I mean as long as I've worked at this organization (4+ years now), one of the frustrating things remains is the relationship with our old-school Oracle DBAs. Even though we've been able to revolutionize our development process, enterprise architecture, etc. from a big "waterfall mess" to "agile", "iterative" (or name it whatever you like), one aspect remains ancient - the database administration and "gate keeping" waterfall frame of mind, which in practice totally slows the iterative development cycle and adds frustration.&lt;br /&gt;&lt;br /&gt;The current frame of mind of our DBAs is the "total control". No development schemas with full DDL privileges exist (forget about the individual development DB snadboxes). The development teams have to develop against central "application" schemas with any slight DDL action having to have to go through the "DBA authority". Also they require that all the database design is done upfront and approved by them before doing any development: classical waterfall if you ask me.&lt;br /&gt;&lt;br /&gt;Nevertheless, the first signs of the new direction that they're (DBAs) willing to try to take showed today (thanks to my boss who's trying hard) This means that for each individual project DBAs are willing to create a "development" schema with all the necessary DDL privileges granted to developers (that's something!). But with that they still require the up-front design, strict approval, and early "synchronization" with the "application schema" Agrrrr.&lt;br /&gt;&lt;br /&gt;Well, may be some day, the DBAs will finally &lt;span style="font-style: italic;"&gt;get&lt;/span&gt; the "iterative" development process and perhaps embrace it. But I have a strange feeling it will not be in my life time :-(&lt;br /&gt;&lt;br /&gt;It's time to catch a bus. Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-6188354847477761700?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/6188354847477761700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=6188354847477761700' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/6188354847477761700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/6188354847477761700'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/01/operation-freedom-from-dbas.html' title='Operation &quot;freedom from DBA&apos;s&quot;'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-4951402077504091749</id><published>2007-01-24T09:12:00.000-05:00</published><updated>2007-01-24T13:06:43.341-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Philadelphia SPUG</title><content type='html'>Yesterday I went to the Philadelphia's Spring user group meeting with two of my colleagues, where Thomas Risberg presented "using Groovy with Spring" (using Spring 2 dynamic language support) and Jason Rudolph of Grails fame presented "An introduction to Grails"&lt;br /&gt;&lt;br /&gt;Thomas showed the arbitrary Spring web app with Controller implemented in Groovy and seamlessly integrated with the rest of the app e.g. dependency injected, etc. This is really cool integration and I'm definitely going to explore it by slowly introducing some Groovy bits and pieces into our existing Spring apps by perhaps implementing some Services in Groovy (where it makes sense of course) to do things much more expressively and naturally :-) One such example would be the XML parsing (agrrrrr) with Groovy's excellent XML support i.e. XmlSlurper, GPath, etc.&lt;br /&gt;&lt;br /&gt;Then Jason did an excellent job of introducing Grails to the audience. I felt that the presentation was very fresh, dynamic and not boring. Jason used a "live coding" demo, where he coded from scratch the basic "Racetrack" application (from his "Getting started with Grails book") before our eyes. Nice job Jason! I might even steal his presentation to do it at our internal "Design and Development" meeting to introduce it to our development crowd.&lt;br /&gt;&lt;br /&gt;And also I've won a copy of an excellent and much anticipated "Groovy in Action" book! The only caveat is that I've ordered that book from Amazon a couple of weeks ago and it actually arrived last night :-( So this one will go to our "Development library" at work to educate other developers about this excellent language.&lt;br /&gt;&lt;br /&gt;I am very excited about Groovy and Grails development and the growing momentum it has. And I sure hope to see Grails applications being developed and deployed at our enterprise some time in 2007!&lt;br /&gt;&lt;br /&gt;Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-4951402077504091749?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/4951402077504091749/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=4951402077504091749' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4951402077504091749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/4951402077504091749'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/01/philadelphia-spug.html' title='Philadelphia SPUG'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6974641895376633181.post-8280743446581962453</id><published>2007-01-20T13:12:00.000-05:00</published><updated>2007-01-20T13:23:11.093-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='family'/><title type='text'>My first</title><content type='html'>Today's Saturday. This is my first post. Just for fun. Just for me, not for the world to judge me. I'll try to keep this blog work-oriented as much as possible.&lt;br /&gt;&lt;br /&gt;Anyway... Myself and Zina have just finished a "fun" activity of bathing our precious 30 days old daughter Oksana. Now she's asleep and hopefully I would have a chance to watch today's Devils vs Flyers game... Oh, the game is on...&lt;br /&gt;&lt;br /&gt;Later on, my "mama law" is coming to babysit Oksana so we could go with Zina to my folks and finally have a good night sleep. I'll be taking my mac book with me with the latest Grails src tree where I'll be studying in details the persistence layer.&lt;br /&gt;&lt;br /&gt;Monday I'm off. That's about it for the first post. Later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6974641895376633181-8280743446581962453?l=dima767.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dima767.blogspot.com/feeds/8280743446581962453/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6974641895376633181&amp;postID=8280743446581962453' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/8280743446581962453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6974641895376633181/posts/default/8280743446581962453'/><link rel='alternate' type='text/html' href='http://dima767.blogspot.com/2007/01/my-first.html' title='My first'/><author><name>Dmitriy Kopylenko</name><uri>http://www.blogger.com/profile/09103763160500756208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_9vYs3LeSMWw/R_3sIatqDeI/AAAAAAAAB7k/ZjIcvMfyYPc/S220/dima.jpg'/></author><thr:total>0</thr:total></entry></feed>
