<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>Grails - Blogs at Near Infinity</title>


        <link>http://www.nearinfinity.com/blogs/</link>
        <description>Employee Blogs</description>
        <language>en</language>
        <copyright>Copyright 2010</copyright>
        <lastBuildDate>Wed, 27 Feb 2008 23:36:01 -0500</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <item>
            <title>A Grails plugin for fuzzy string matching</title>
            <description><![CDATA[Long ago at a company which <i>shall not be named</i>, I made the mistake of shunning contemporary technology. Never again! Since Near Infinity honors its training commitment I was able to attend and enjoy the Groovy / Grails NFJS <a href="http://www.groovygrails.com/gg/2gexperience">conference</a>.
<p>
Apache Commons <a href="http://commons.apache.org/codec/">Codec</a> implemented soundex, double metaphone, base64, and more. in the spirit of Grails why not stitch them into java.lang.String?
</p><p>

</p><pre class="prettyprint">import org.apache.commons.codec.language.*
import org.apache.commons.codec.net.*

class FuzzstrGrailsPlugin {
    def version = 0.1
    def dependsOn = [core:grails.util.GrailsUtil.getGrailsVersion()]
	
    def doWithDynamicMethods = {
        def encodingClosure = { it.encode(delegate) }
        def decodingClosure = { it.decode(delegate) }

        String.metaClass.toSoundex = encodingClosure.curry(new Soundex())
        String.metaClass.toRefinedSoundex = encodingClosure.curry(new RefinedSoundex())
        String.metaClass.toMetaphone = encodingClosure.curry(new Metaphone())
        String.metaClass.toDoubleMetaphone = encodingClosure.curry(new DoubleMetaphone())

        String.metaClass.toBase64 = encodingClosure.curry(new BCodec())
        String.metaClass.fromBase64 = decodingClosure.curry(new BCodec())

        String.metaClass.toQPrintable = encodingClosure.curry(new QCodec())
        String.metaClass.fromQPrintable = decodingClosure.curry(new QCodec())

        String.metaClass.toQuotedPrintable = encodingClosure.curry(new QuotedPrintableCodec())
        String.metaClass.fromQuotedPrintable = decodingClosure.curry(new QuotedPrintableCodec())

        String.metaClass.toUrlEncoded = encodingClosure.curry(new URLCodec())
        String.metaClass.fromUrlEncoded = decodingClosure.curry(new URLCodec())

        String.metaClass.similarTo = { Cosine.stringSimilarity(delegate, it) }
        String.metaClass.mostSimilarTo = { Cosine.mostSimilar(delegate, it) }
        String.metaClass.rankedSimilarity = { Cosine.horseShoes(delegate, it) }
    }
}
</pre>
<p>
</p><p>So what? Well, see for yourself:
</p><p>
</p><pre class="prettyprint">Loading with installed plug-ins: ["fuzzstr"] ...
Groovy Shell (1.5.4, JVM: 1.5.0_13-119)
Type 'help' or '\h' for help.
-------------------------------------------------------------------------------
groovy:000> "literal".toSoundex()
===> L364
groovy:000> "literal".toDoubleMetaphone()
===> LTRL
groovy:000> "literal".toBase64().fromBase64()
===> literal
groovy:000> "literal".similarTo("litteral")
===> 93
groovy:000> "litteral".mostSimilarTo(['literature', 'litter', 'literal']) 
===> literal
</pre>
<p>
The plugin's not ready to be released yet but hopefully within a few weeks; localization and caching need some love. Pondering whether GORM might benefit from some of these methods.
</p><p>
seth _dot_ schroeder _at_ nearinfinity _dot_ com</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/seth_schroeder/a_grails_plugin_for_fuzzy.html</link>
            <guid>http://www.nearinfinity.com/blogs/seth_schroeder/a_grails_plugin_for_fuzzy.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Grails</category>
            
            
            <pubDate>Wed, 27 Feb 2008 23:36:01 -0500</pubDate>
        </item>
        
        <item>
            <title>Groovy cosine similarity in Grails</title>
            <description><![CDATA[<p>I really appreciate <a href="http://www.nearinfinity.com/blogs/page/mwizeman">Matt</a> and <a href="http://www.nearinfinity.com/blogs/page/rdonaway">Bob</a> <a href="http://www.nearinfinity.com/blogs/page/seths?entry=finding_similar_strings_using_character">showing</a> me <b>significantly</b> better ways to compare strings. Yet another perk of working for this company :)

</p><p>I've been spending time with <a href="http://grails.codehaus.org/">grails</a> lately. One of my biggest beefs is 100% accuracy required 100% of the time when typing parameters to the "grails" application. Not a big deal (esp. with emacs M-/)... but what an opportunity to do something useful with cosine similarity!

</p><p>All code on this page is licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2</a> license.

</p><p>The heart of the code. Please ignore the lack of error handling and optimization.

</p><pre class="prettyprint">    static def similarity(l_seq, r_seq, degree=2) {
        def l_histo = countNgramFrequency(l_seq, degree)
        def r_histo = countNgramFrequency(r_seq, degree)
        
        dotProduct(l_histo, r_histo) /
            Math.sqrt(dotProduct(l_histo, l_histo) *
                      dotProduct(r_histo, r_histo))
    }
</pre>

<p> This probably isn't ideal Groovy, but I sure appreciated the syntax improvements to arrays and maps.
</p><pre class="prettyprint">    static def countNgramFrequency(sequence, degree) {
        def histo = [:]
        def items = sequence.size()

        for (int i = 0; i + degree &lt;= items; i++)
        {
            def gram = sequence[i..&lt;(i + degree)]
            histo[gram] = 1 + histo.get(gram, 0)
        }
        histo
    }
</pre>

<p>Still nothing specific to strings here...
</p><pre class="prettyprint">    static def dotProduct(l_histo, r_histo) {
        def sum = 0
        l_histo.each { key, value ->
            sum = sum + l_histo[key] * r_histo.get(key, 0)
        }
        sum
    }
</pre>

<p>Finally, here's something useful:

</p><pre class="prettyprint">    static def stringSimilarity (l_str, r_str, degree=2) {
        similarity(l_str.toLowerCase().toCharArray(),
                   r_str.toLowerCase().toCharArray(),
                   degree)
    }
</pre>

<p>... okay, how to apply this to grails? Just one more bit of code:

</p><pre>    static def mostSimilar(pattern, candidates, threshold=0) {
        def topScore = 0
        def bestFit = null

        candidates.each { candidate ->
            def score = stringSimilarity(pattern, candidate)
            if (score > topScore) {
                topScore = score
                bestFit = candidate
            }
        }

        if (topScore &lt; threshold)
            bestFit = null

        bestFit
    }
</pre>

<p>Drop this into GrailsScriptRunner.groovy and now this:
</p><ul><li>grails create-domain-class</li></ul>
<p>... is equivalent to <b>all</b> of these:
</p><ul>
<li>grails craete-domain-class
</li><li>grails domain
</li><li>grails dom
</li></ul>
<p>To everyone who read this far, thank you :) And... one other observation. Strings are ordered sequences (of chars). What about file contents (lines) and directory contents (file names)?

</p><pre class="prettyprint">    static def fileSimilarity (l_file, r_file, degree=3) {
        similarity(new File(l_file).readLines(),
                   new File(r_file).readLines(),
                   degree)
    }

    static def dirSimilarity(l_dir, r_dir, degree=3) {
        def l_files = []
        def r_files = []

        new File(l_dir).eachFileRecurse { l_files &lt;&lt; it.name }
        new File(r_dir).eachFileRecurse { r_files &lt;&lt; it.name }

        similarity(l_files, r_files, degree)
    }
</pre>
<p><i>edit 2007-12-05 --  size() method works for arrays and lists; easier than length and size properties. Contribution much appreciated!
</i></p><i><p>-- seth.schroeder _at_ nearinfinity.com</p></i>]]></description>
            <link>http://www.nearinfinity.com/blogs/seth_schroeder/groovy_cosine_similarity_in_grails.html</link>
            <guid>http://www.nearinfinity.com/blogs/seth_schroeder/groovy_cosine_similarity_in_grails.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Grails</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Groovy</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">cosine similarity</category>
            
            <pubDate>Sat, 01 Dec 2007 19:41:28 -0500</pubDate>
        </item>
        
        <item>
            <title>Review of The Definitive Guide to Grails</title>
            <description><![CDATA[<div style="float:left; margin:5px"><a href="http://www.amazon.com/gp/product/1590597583?ie=UTF8&amp;tag=jefkun-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1590597583"><img border="0" src="/blogs/assets/definitive_guide_to_grails_cover.jpg" /></a><img src="http://www.assoc-amazon.com/e/ir?t=jefkun-20&amp;l=as2&amp;o=1&amp;a=1590597583" width="1" height=";1&quot;" border="0" alt="" style="border:none !important; margin:0px !important;" /></div>

<p>I've found myself a bit bored with web application development lately. I've been itching to do something significant with <a href="http://www.rubyonrails.org">Ruby on Rails</a> for quite some time but always find myself working on Java projects for various clients. At the recommendation of some colleagues I've decided to take a peak at Grails and I have to say that I've shed my boredom and am once again excited about web development.</p>

<p>The following is my review of <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.com%2FDefinitive-Guide-Grails%2Fdp%2F1590597583%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1187180584%26sr%3D8-1&amp;tag=jefkun-20&amp;linkCode=ur2&amp;camp=1789&amp;creative=9325">The Definitive Guide to Grails</a>, written by Graeme Keith Rocher. Prior to reading this book I considered myself to know a lot about Java, a little about Ruby and Ruby on Rails, very little about <a href="http://groovy.codehaus.org/">Groovy</a>, and nothing about <a href="http://grails.codehaus.org/">Grails</a>. After one speed reading of The Definitive Guide to Grails I have to admit that I'm quite excited at the prospect of starting a new project with Grails.</p>

<h1 id="conclusion">Conclusion</h1>

<p>Yes, that's right, I'm placing the conclusion at the front of the review. Why? Because the reviews of each chapter ended up being much longer than I'd anticipated and I fear few readers will hang on until the end. If you're interested in some of the finer grained details of each chapter please read the following sections that I spent way too much time writing.</p>

<p>I found The Definitive Guide to Grails to be one of the best technical books I've read recently. The book appears to be targeted at the Grails newbie, which would suit just about everyone at this point in time. I never felt the content was over my head nor was I bored with long-winded explanations. I was looking for a book that would introduce me to as many core Grails concepts as possible within a short page count, and Graeme's book certainly delivered.</p>

<p>If you learn best by following along with examples, you're likely to enjoy this book. All eleven chapters are filled with plenty of code examples that not only bolstered my understanding of Grails, but also helped me comprehend some of the finer points of the Groovy language. I found the examples to be straightforward, numerous, and relatively short. I'm not a big fan of the long multi-page examples you sometimes find in technical books. I want enough just enough code to understand the topic and then move on. In my opinion, this is where The Definitive Guide to Grails excels. If you're coming from a Java background, you should be able to pick up on the examples with minimal effort.</p>

<p>Also being new to Groovy, I appreciated the fact that Graeme sprinkled the use of some advanced Groovy features into the code examples. In wasn't a windfall of features mind you, but it was enough to convince me of the power of Groovy and get me excited about learning more.</p>

<p>Overall, The Definitive Guide to Grails was a well-written, informative treatment of an exciting new web development framework. The code examples were woven in very well and really helped to understand the topics. If you're looking to get up to speed on Grails in short order, I think you'll be pleased with <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.com%2FDefinitive-Guide-Grails%2Fdp%2F1590597583%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1187180584%26sr%3D8-1&amp;tag=jefkun-20&amp;linkCode=ur2&amp;camp=1789;amp;creative=9325">The Definitive Guide to Grails</a>.</p>

<p>The following paragraphs provide a quick summary of each chapter.</p>

<h1 id="chapter_1_the_search_for_the_holy_grails">Chapter 1 - The Search for the Holy Grail(s)</h1>

<p>The first chapter provides some insight into the how and why of Grails. Graeme hits on the relative difficulty of developing applications on the JEE platform. He goes on to discuss how the prominence of Ajax and Web 2.0 have focused a lot of attention on web application development, and more specifically efficient web app development.</p>

<p>He then moves onto an introduction of Grails, paying homage to its Ruby on Rails inspiration. There's a short discussion of how Grails leverages the power of the Java platform and specifically the <a href="http://www.springframework.org">Spring Framework</a>, <a href="http://www.hibernate.org">Hibernate</a>, and <a href="http://www.opensymphony.com/sitemesh/">Sitemesh</a>. </p>

<p>The remainder of the chapter gets you up and running with Groovy and Grails. Graeme guides you though creating the first pieces of the sample application used throughout the book. Very few concepts are explained at this point, but it does whet the pallet.</p>

<h1 id="chapter_2_the_groovy_language">Chapter 2 - The Groovy Language</h1>

<p>Here's your introduction to the Groovy language from the perspective of a Java developer. The basic topics introduced include classes, assertions, Groovy Strings (GStrings), closures, lists, maps, and Expando objects. Graeme follows up with some "power" features such as Groovy's object-oriented design, Groovy's notion of equals, metaprogramming, and builders.</p>

<p>You shouldn't expect to become an expert on Groovy from this one chapter. For that, consider reading <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.com%2FGroovy-Action-Dierk-Koenig%2Fdp%2F1932394842%3Fie%3DUTF8%26s%3Dbooks%26s9r%3D8afd079f0eefbbe9010f873c3e10073b%26itemPosition%3D1%26qid%3D1187180781%26sr%3D1-1&amp;tag=jefkun-20&amp;linkCode=ur2&amp;camp=1789&amp;creative=9325">Groovy in Action</a> or <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.com%2FGroovy-Programming-Introduction-Java-Developers%2Fdp%2F0123725070%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1187180781%26sr%3D1-3&amp;tag=jefkun-20&amp;linkCode=ur2&amp;camp=1789&amp;creative=9325">Groovy Programming: An Introduction for Java Developers</a>. Luckily, I found most of the topics to be explained in enough detail for me to follow along. A Java or Ruby background is a big help here. Without it, I think you may have a difficult time understanding some of the code samples.</p>

<h1 id="chapter_3_the_grails_project_infrastructure">Chapter 3 - The Grails Project Infrastructure</h1>

<p>This chapter dives into how a Grails project is organized and configured. If you've ever used Ruby on Rails, you'll notice the project directory structure is similar. Either way, the big benefit here is that there's a common structure for all Grails projects.</p>

<p>Graeme follows up the directory structure discussion with a brief description of Grails and the MVC architecture. At first I groaned about having to read yet another description of MVC, but it turns out that I didn't have to. The whole discussion is only two pages covering where the different Grails components like controllers, views, and the domain model fit into the MVC picture.</p>

<p>The next few pages focus on configuring your data source and logging configuration for different environments. While I welcome the configuration simplicity Grails provides for these resources, I found myself wondering how I would specify other things on an environment by environment level.</p>

<p>The Grails command line utilities, console, and shell are also introduced in chapter three. The command line utilities are very Rails-like, providing you with quick scripts to create things such as applications, controllers, domain objects, tests and tag libraries. The command line can also be used to launch the Grails shell and console. Graeme doesn't spend much time explaining these commands, nor do I think he needs to. Just being aware of them is probably good enough since they're mostly self-explanatory.</p>

<p>The chapter finishes up with a discussion on Eclipse IDE integration. Graeme spends a good six pages describing the integration with plenty of screen shots to guide the reader along. I can't comment on how good the instructions actually are since I didn't try them.</p>

<h1 id="chapter_4_the_application_domain">Chapter 4 - The Application Domain</h1>

<p>This is the chapter where you really see Grails shine. It's a long chapter mainly covering Grails ORM (GORM) and domain model validation. I felt that Graeme spent a lot of time explaining these two concepts and it really paid off for me. </p>

<h2 id="grails_orm_gorm">Grails ORM (GORM)</h2>

<p>On the GORM side, he covers the basics of creating Grails domain objects and setting up relationships between them. He then goes on to talk about the various ways to query the database, including dynamic finders and a lengthy discussion on how to leverage the Hibernate Criteria API. The text on using the Hibernate Criteria made it seem relatively trivial to take advantage of the powerful library.</p>

<p>One thing I found strangely missing was a description of how to create the database schema. There were plenty of examples describing how to create the domain model, establish associations, and perform queries, but no description of how to create the necessary tables in the first place. I assume Grails is relying on Hibernate to automatically create the schema, but this is purely a guess since it's not touched upon.</p>

<h2 id="data_validation">Data Validation</h2>

<p>The discussion on domain model validation focuses on how to add simple constraints to individual fields of your domain model. Graeme also describes how to create custom constraints through the use of closures.</p>

<h1 id="chapter_5_scaffolding">Chapter 5 - Scaffolding</h1>

<p>Chapter five included a discussion of both dynamic and static scaffolding. Unfortunately (in my opinion), Graeme devotes three-quarters of the chapter to dynamic scaffolding, which I've found to be of little benefit in my brief time playing with the Ruby on Rails equivalent. </p>

<h2 id="dynamic_scaffolding">Dynamic Scaffolding</h2>

<p>He uses dynamic scaffolding to create the first few pages of the sample application, showing the reader screen shots of the UI along the way. There are descriptions of how to modify some of the scaffolding by overriding default CRUD operations and customizing fields with constraints.</p>

<h2 id="static_scaffolding">Static Scaffolding</h2>

<p>I found the text on static scaffolding to be more beneficial. The discussion mainly focuses on using the command line tools to generate default implementations of controllers, views, tests, etc. There's also some brief but clear discussion on the location of generated artifacts and the code that is created behind the scenes.</p>

<h1 id="chapter_6_testing_testing_testing">Chapter 6 - Testing, Testing, Testing</h1>

<p>The chapter on testing was split up into two sections, unit testing and functional testing. </p>

<h2 id="unit_testing">Unit Testing</h2>

<p>The unit testing part of the chapter covered Groovy's assert methods beyond those provided by <a href="http://www.junit.org">JUnit</a> and its mocking capabilities through the use of closures. The generous code examples really helped me understand how powerful Groovy's mocking capabilities are. My collegue Scott Leberknight has a <a href="http://www.nearinfinity.com/blogs/page/sleberkn?entry=dirt_simple_mocks_in_groovy">nice post</a> that explains some of the finer points of mocking with Groovy if you're interested in some more detail.</p>

<h2 id="functional_testing">Functional Testing</h2>

<p>In my opinion, you can probably skip the second half of the chapter devoted to functional testing with <a href="http://webtest.canoo.com/webtest/manual/WebTestHome.html">Canoo WebTest</a>. Although Graeme does a nice job explaining how to use WebTest and its integration with Grails is commendable, I think it will largely be an exercise in frustration for any modern web application using Ajax. As far as I know, WebTest is not able to exercise any Ajax functionality.</p>

<h1 id="chapter_7_grails_controllers">Chapter 7 - Grails Controllers</h1>

<p>The chapter on Grails controllers covers a lot of ground in a short thirty-one pages, so make sure you're paying close attention when you read it. There's a lot of great information that you won't want to miss. Below are some of the highlights.</p>

<h2 id="actions">Actions</h2>

<p>Graeme starts off by describing actions, the workhorses of controllers. He does a nice job of describing how Grails use of closures for action definitions is so beneficial. He quickly follows this up by describing how the developer can access various request attributes with little effort. For those of you who've written a lot of Java web applications in the past, you'll be pleased to find that things like
    request.getSession().getAttribute("attrName")
are reduced to
    session.attrName</p>

<h2 id="flash">Flash</h2>

<p>The explanation of flash scope will be particularly helpful to anyone who hasn't used Ruby on Rails before. Graeme does a nice job of illustrating how this scope differs from the familiar page, request, session, and servlet context scopes we're all used to and why it's so helpful to have it in your bag of tricks.  </p>

<h2 id="data_binding">Data Binding</h2>

<p>Three full pages are devoted to Grails data binding, which builds upon Spring's binding code. Binding is one of the more tedious aspects of web development, but Graeme does a nice job at putting your worries at ease. He also takes the time to describe how binding can be used outside of the context of Grails domain objects.</p>

<h2 id="control_flow">Control Flow</h2>

<p>Graeme follows up data binding with some text on controlling flow with redirects. There's nothing exciting here, although the tactics are well explained.</p>

<h2 id="response_rendering">Response Rendering</h2>

<p>Grails has a very flexible response rendering framework wrapped up in a simple API. The text covers a wide range of rendering options with short code samples. The discussion of rendering HTML or XML using builders is especially cool.</p>

<h2 id="action_interception">Action Interception</h2>

<p>Think of action interception as AOP for your controller methods, which is exactly how it's described by the author. He gives a quick example of before and after advice followed by a discussion of how action interceptors can be used to implement authentication and authorization. The apparent simplicity of this approach makes me wonder if using Acegi (as briefly described in chapter eleven) is worth the effort.</p>

<h2 id="file_uploads">File Uploads</h2>

<p>The last topic in this busy chapter deals with file uploads, which again builds upon Spring's binding technology. Graeme provides two examples of handling file uploads. The first involves pulling the file directly from the request from within a controller. The second example demonstrates binding a file directly to a domain model object.</p>

<h1 id="chapter_8_groovy_server_pages">Chapter 8 - Groovy Server Pages</h1>

<p>The chapter on Groovy Server Pages (GSP) is quite long and covers a lot of material. The chapter starts off by talking about some of the more mundane basics; page directives, scriptlets, and GStrings but quickly moves on to more interesting topics.</p>

<h2 id="tags">Tags</h2>

<p>Graeme starts off the tag discussion by describing the built-in Grails tags. There's at least one usage example for setting variables with tags, logic tags, and iterative tags. These tags probably don't sound all that different than the JSTL ones you may have used, and they aren't. What is different are the filtering and iteration tags, including collect, findAll, and grep. For these more unfamiliar tags, Graeme provides several examples each that demonstrate their usage. He finishes off by talking about Grails dynamic tags, explaining both how to use the built-in Grails ones and also how to create your own.</p>

<h2 id="validation_and_error_handling">Validation and Error Handling</h2>

<p>Validation and error handling are next on tap. The discussion here is short and to the point. If you've had any experience with Spring MVC before, this text will be quite familiar.</p>

<h2 id="internationalization_support">Internationalization Support</h2>

<p>The discussion of internationalization support is very brief, but I didn't find it lacking. You're mileage may vary. It basically boils down to describing where different language bundles are placed in the Grails directory structure and how those messages can be displayed using Grails tags.</p>

<h2 id="layouts_and_templates">Layouts and Templates</h2>

<p>Graeme spends a full ten pages describing layouts and templates, more than I would have expected. He provides sample layouts and describes how layouts are selected by convention or through the use of meta tags. This is all the same stuff you'd expect if you've used SiteMesh before.</p>

<p>A discussion of templates follows the text on layouts. Templates are simply reusable snippets of markup. Graeme provides a few examples demonstrating how the g:render tag makes working with templates dead simple. If it weren't for the g:render tag integration, templates would be little more than JSP includes.</p>

<h2 id="pagination">Pagination</h2>

<p>Pagination is one of those things that has to be dealt with in every web application, and it's never fun. Here, Graeme explains how the g:paginate tag in Grails  makes rendering paging links and managing the display of multiple pages a bit easier. As usual, there are plenty of code examples to help you understand how to use the tag.</p>

<h2 id="custom_tags">Custom Tags</h2>

<p>Graeme finishes up the chapter with a discussion on how to create your own custom tags and yes, this is different than creating your own dynamic tags. Graeme describes the process through an example of in-place editing that's folded into the example played out throughout the book. I found the example easy enough to understand but the resulting code ugly. It reminded me of the long forgotten days of outputting HTML from servlets.</p>

<h1 id="chapter_9_ajax">Chapter 9 - Ajax</h1>

<p>The chapter on Ajax is focused on describing the tight integration of Grails custom tags with your favorite JavaScript library, as long as it's Prototype/Scriptaculous, Yahoo UI, or the Dojo Toolkit. Most of the explanation is described by refactoring the book example to add in some Ajax goodness. Included are descriptions of the g:remoteField, g:remoteLink, and g:formRemote tag, the process of specify JavaScript to run before or after a remote call, and custom event handling. Lastly, there's a quick example of adding some JavaScript UI effects using Scriptaculous.</p>

<h1 id="chapter_10_services_and_jobs">Chapter 10 - Services and Jobs</h1>

<p>Chapter ten starts with a discussion of the traditional service tier of a Java application. This chapter is also home to the first mention of transactional support from Grails, and it is certainly brief. I have to think there's a lot more to Grails transaction support than Graeme is divulging.</p>

<p>The discussion of services finishes up with a demonstration on the use of the service layer by creating one that calls a del.icio.us web service. The example covers everything from writing the Jakarta <a href="http://commons.apache.org/httpclient/">Commons HTTP Client</a> to calling the service from a controller.</p>

<p>From services we move to jobs, which Graeme has spent a whopping twenty-six pages describing. Jobs are built on top of the <a href="http://www.opensymphony.com/quartz/">Quartz</a> scheduling engine, and a good portion of the twenty-six pages is devoted to explaining it. He covers all angles associated with jobs, including creating, scheduling, testing, pausing, resuming, and removing jobs. All of this is done through a non-trivial example of a daily scheduled job that queries the database and then formats the results as an email delivered via JavaMail.</p>

<h1 id="chapter_11_java_integration">Chapter 11 - Java Integration</h1>

<p>The last chapter covers Grails integration with Java. The discussion is most heavily weighted towards integration options with Hibernate and Spring. However, Graeme also covers using <a href="http://www.acegisecurity.org/">Acegi</a> for Grails security and exposing a SOAP service using the <a href="http://xfire.codehaus.org/">XFire</a> library. The following paragraphs describe each topic.</p>

<h2 id="orm_integration_with_hibernate">ORM Integration with Hibernate</h2>

<p>Anyone using Hibernate on an existing project will likely be quite happy after reading this part of chapter eleven. Graeme describes how you can use Grails with an existing domain model and either Hibernate XML mapping files or EJB3 annotations. I have to admit that I had a bit of a smile on my face after reading this section and realizing that I didn't have to wait for an entirely new project to try out Grails.</p>

<p>I was equally surprised to find that I can use Grails constraints on my non-Grails domain objects. Graeme provides an example of how to do this in short order.</p>

<h2 id="dependency_injection_with_spring">Dependency Injection with Spring</h2>

<p>The section on dependency injection with Spring shows you how to leverage the Spring Framework underlying Grails. A basic understanding of the Spring Framework will certainly help understand the text, although I don't think it's absolutely necessary.</p>

<p>In the chapter, Graeme talks about how to override Grails beans and how to use Spring controllers with Grails. The explanation of using Spring controllers is much more thorough than I would have expected, with plenty of sample code to help guide the reader.</p>

<h2 id="acegi">Acegi</h2>

<p>The section on using Acegi is jam packed with the XML code snippets you need for a basic configuration of the security framework. If you seriously plan to use Acegi, you'll need to look elsewhere for more information. The eight pages of XML is hardly enough to understand what's going on. </p>

<h2 id="exposing_a_soap_service_with_xfire">Exposing a SOAP Service with XFire</h2>

<p>I have a feeling that Apress pressured Graeme into including the chapter on web services with XFire. After all, any respectable book on web development needs to talk about web services. Right? The content was nothing more than a brush pass and had nothing to do with Grails. The text, although well-explained, would have fit just as nicely in any book on JEE web development.</p>

<style type="text/css">h1, h2 {text-align:left}</style>]]></description>
            <link>http://www.nearinfinity.com/blogs/jeff_kunkle/review_of_the_definitive_guide.html</link>
            <guid>http://www.nearinfinity.com/blogs/jeff_kunkle/review_of_the_definitive_guide.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Grails</category>
            
            
            <pubDate>Wed, 15 Aug 2007 09:11:01 -0500</pubDate>
        </item>
        
        <item>
            <title>Grails adds layers -- cake or onion?</title>
            <description><![CDATA[<a href="http://grails.codehaus.org/">Grails</a> has big hopes. It hopes to find a place for <a href="http://groovy.codehaus.org">Groovy</a> in every tier of a Java-based webapp. It hopes to vanquish configuration files by enforcing implicit requirements / conventions. It hopes to simplify starting a respectable Java webapp by providing and configuring Hibernate, Spring, and multi-environment build files.

<p>I hope the Grails dev team succeeds. JRuby is a well-intentioned, <a href="http://developers.slashdot.org/article.pl?sid=06/09/12/068253">well-heeled</a>, but misbegotten creation (q.v. <a href="http://en.wikipedia.org/wiki/Victor_Frankenstein">V. Frankenstein</a>). Should Groovy succeed, it should be the ultimate Java webapp framework. Ultimate in <a href="http://www.google.com/search?&amp;q=define:ultimate">this</a> sense: "being the last or concluding element of a series." Consider this diagram of a minimal Grails application -- can you find room for more layers?</p>

<img src="http://www.nearinfinity.com/blogs/resources/seths/Grails.png" alt="structure of Grails webapp framework" border="0" />

<p><b>All</b> of those jar files are in the classpath and configured for immediate coding. Did I mention the grails commandline app? It's fantastic. It creates classes &amp; test classes, runs tests, runs apps, and is a good engine for the development workflow.

So what's the catch? Adding Grails into an existing project doesn't make much sense. The Grails skeleton would duplicate much of the existing infrastructure. Migrating existing code into a Grails skeleton can be done, but some refactoring will be needed. Here's my quick take based on some tinkering.

<h3>Controllers</h3>Rewrite controllers. A controller in Grails lives for one request, unlike a long-lived Spring MVC controller. Grails has done a good job of improving the process of implementing a controller: autobinding the query string key:value pairs to instance fields, simple url mapping conventions, and more.

<h3>Services</h3>Consider migrating .java business logic to Grails .groovy services. A Grails service class instance is long lived as in Spring MVC; it can also be injected into a Grails controller very easily. Java service classes with complicated transaction requirements should not be migrated. Transaction / rollback is applied to all Grails service methods by default. Disabling rollback affects all methods in a service class.

<h3>Views and layouts</h3>Grails supports Groovy Server Pages (.gsp) and Java Server Pages (.jsp); Sitemesh can be used with both. Unfortunately support for custom JSP tag libraries will wait until version 0.6. GSP isn't bad. The conditional control flow tags are nice, but I really see no strong reason to prefer a .gsp to a .jsp. One notable item on the roadmap is support for Spring Web Flow.

<h3>Model / DAO / domain classes</h3>Hibernate mapping files and annotations are well understood ways to control ORM. GORM configuration uses static class variables. Here is a partial list: <code class="prettyprint">optionals, transients, belongsTo, hasMany, mappedBy, embedded, constraints</code>. Grails supports Groovy SQL but has plans to fork it eventually. GORM also injects id and version properties to domain objects at runtime. 

<h3>Conclusion</h3>Grails adds layers, but more cake-like than onion-like. Programmers can look forward to writing Groovy code for a multi-tier webapp with the dependencies already in place. Much existing code can be migrated in by adapting it to the Grails conventions; other parts may be included as .java files. The largest learning curve will probably be GORM. Finally, it's probably a good idea to let Grails mature for 3-6 months before deploying it into production.]]></description>
            <link>http://www.nearinfinity.com/blogs/seth_schroeder/grails_adds_layers_cake_or.html</link>
            <guid>http://www.nearinfinity.com/blogs/seth_schroeder/grails_adds_layers_cake_or.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Grails</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Java</category>
            
            
            <pubDate>Tue, 12 Jun 2007 21:43:01 -0500</pubDate>
        </item>
        
    </channel>
</rss>
