<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Kaptain on ... stuff &#187; Programming</title>
	<atom:link href="http://www.kellyrob99.com/blog/tag/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kellyrob99.com/blog</link>
	<description>Tales of development, life and the folly that goes along with both</description>
	<lastBuildDate>Sun, 04 Dec 2011 21:51:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Five Cool Things You Can Do With Groovy Scripts</title>
		<link>http://www.kellyrob99.com/blog/2011/12/04/five-cool-things-you-can-do-with-groovy-scripts/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=five-cool-things-you-can-do-with-groovy-scripts</link>
		<comments>http://www.kellyrob99.com/blog/2011/12/04/five-cool-things-you-can-do-with-groovy-scripts/#comments</comments>
		<pubDate>Sun, 04 Dec 2011 21:51:34 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[gist]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Gradle]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Hudson]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[jenkins]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[JsonSlurper]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1761</guid>
		<description><![CDATA[1. Ensure all of your Jenkins builds are building the correct branch from source control I manage a large number of builds at work, spread across several build servers. When we release a new version all of the builds need to be updated to point to new working branches. This script takes advantage of the [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2011/09/18/using-gradle-to-bootstrap-your-legacy-ant-builds/' rel='bookmark' title='Using Gradle to Bootstrap your Legacy Ant Builds'>Using Gradle to Bootstrap your Legacy Ant Builds</a></li>
<li><a href='http://www.kellyrob99.com/blog/2011/03/27/hooking-into-the-jenkinshudson-api/' rel='bookmark' title='Hooking into the Jenkins(Hudson) API'>Hooking into the Jenkins(Hudson) API</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/09/26/groovy-inspecteval-for-externalizing-data/' rel='bookmark' title='Groovy inspect()/Eval for Externalizing Data'>Groovy inspect()/Eval for Externalizing Data</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<h2>1. Ensure all of your Jenkins builds are building the correct branch from source control</h2>
<p>I manage a large number of builds at work, spread across several build servers. When we release a new version all of the builds need to be updated to point to new working branches. This script takes advantage of the fact that our branches all end in the version number to quickly check that all of the last builds were on the expected version.<br />
Using the <a href="https://wiki.jenkins-ci.org/display/JENKINS/Remote+access+API">Jenkins API</a> is very easy and the new capabilities of Groovy introduced by <a href="http://groovy.codehaus.org/gapi/groovy/json/JsonSlurper.html">JSONSlurper</a> make it easier than ever to consume.<br />
<script src="http://gist.github.com/1430845.js?file=jenkinsSVNVersionChecker.groovy"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-1430845" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">import</span> <span class="nn">groovy.json.JsonSlurper</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="k">assert</span> <span class="n">args</span> <span class="o">&amp;&amp;</span> <span class="n">args</span><span class="o">.</span><span class="na">size</span><span class="o">()</span> <span class="o">==</span> <span class="mi">2</span></div><div class='line' id='LC4'><span class="n">def</span> <span class="n">urls</span> <span class="o">=</span> <span class="n">args</span><span class="o">[</span><span class="mi">0</span><span class="o">].</span><span class="na">split</span><span class="o">(</span><span class="sc">&#39;,&#39;</span><span class="o">)</span></div><div class='line' id='LC5'><span class="n">def</span> <span class="n">expectedVersion</span> <span class="o">=</span> <span class="n">args</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span></div><div class='line' id='LC6'><span class="n">urls</span><span class="o">.</span><span class="na">each</span> <span class="o">{</span> <span class="n">url</span> <span class="o">-&gt;</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">println</span> <span class="s">&quot;examining url $url&quot;</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">def</span> <span class="n">json</span> <span class="o">=</span> <span class="k">new</span> <span class="n">JsonSlurper</span><span class="o">().</span><span class="na">parseText</span><span class="o">(</span><span class="n">url</span><span class="o">.</span><span class="na">toURL</span><span class="o">().</span><span class="na">text</span><span class="o">)</span></div><div class='line' id='LC9'><br/></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">json</span><span class="o">.</span><span class="na">jobs</span><span class="o">.</span><span class="na">each</span> <span class="o">{</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">try</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">{</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">def</span> <span class="n">job</span> <span class="o">=</span> <span class="k">new</span> <span class="n">JsonSlurper</span><span class="o">().</span><span class="na">parseText</span><span class="o">(</span><span class="s">&quot;${it.url}/api/json?depth=1&quot;</span><span class="o">.</span><span class="na">toURL</span><span class="o">().</span><span class="na">text</span><span class="o">)</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="o">(!</span><span class="n">job</span><span class="o">.</span><span class="na">builds</span><span class="o">[</span><span class="mi">0</span><span class="o">].</span><span class="na">changeSet</span><span class="o">.</span><span class="na">revisions</span><span class="o">[</span><span class="mi">0</span><span class="o">].</span><span class="na">module</span><span class="o">.</span><span class="na">endsWith</span><span class="o">(</span><span class="n">expectedVersion</span><span class="o">))</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">{</span></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">println</span> <span class="s">&quot;$it.url fails!&quot;</span></div><div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">else</span></div><div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">{</span></div><div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">println</span> <span class="s">&quot;$it.url passes!&quot;</span></div><div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">catch</span> <span class="o">(</span><span class="n">e</span><span class="o">)</span></div><div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">{</span></div><div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">println</span> <span class="s">&quot;Exception thrown processing $it.url : $e&quot;</span></div><div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC28'><span class="o">}</span></div><div class='line' id='LC29'><br/></div><div class='line' id='LC30'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1430845/bbc1beba1dfd59a6fe9925af14d301460202f0d3/jenkinsSVNVersionChecker.groovy" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1430845#file_jenkins_svn_version_checker.groovy" style="float:right;margin-right:10px;color:#666">jenkinsSVNVersionChecker.groovy</a>
            <a href="https://gist.github.com/1430845">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript></p>
<h2>2. Look up the artifacts from the last successful Jenkins build</h2>
<p>This is very handy if you want to automate deployment of software from your build system and can replace a lot of error prone manual updating of scripts. In this particular example you can link up quickly with the latest, greatest build of JRuby from <a href="http://ci.jruby.org/">their public CI server</a>.<br />
<script src="http://gist.github.com/1430856.js?file=jenkinsBuildArtifacts.groovy"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-1430856" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">import</span> <span class="nn">groovy.json.*</span></div><div class='line' id='LC2'><span class="n">def</span> <span class="n">HOSTNAME</span> <span class="o">=</span> <span class="err">&#39;</span><span class="nl">http:</span><span class="c1">//ci.jruby.org&#39;</span></div><div class='line' id='LC3'><span class="n">def</span> <span class="n">JOBNAME</span> <span class="o">=</span> <span class="err">&#39;</span><span class="n">jruby</span><span class="o">-</span><span class="n">dist</span><span class="err">&#39;</span></div><div class='line' id='LC4'><span class="n">def</span> <span class="n">JOB_URL</span> <span class="o">=</span> <span class="s">&quot;$HOSTNAME/job/$JOBNAME/lastSuccessfulBuild&quot;</span></div><div class='line' id='LC5'><span class="n">def</span> <span class="n">text</span> <span class="o">=</span> <span class="s">&quot;$JOB_URL/api/json&quot;</span><span class="o">.</span><span class="na">toURL</span><span class="o">().</span><span class="na">text</span></div><div class='line' id='LC6'><span class="n">println</span> <span class="n">JsonOutput</span><span class="o">.</span><span class="na">prettyPrint</span><span class="o">(</span><span class="n">text</span><span class="o">)</span></div><div class='line' id='LC7'><span class="n">def</span> <span class="n">json</span> <span class="o">=</span> <span class="k">new</span> <span class="n">JsonSlurper</span><span class="o">().</span><span class="na">parseText</span><span class="o">(</span><span class="n">text</span><span class="o">)</span></div><div class='line' id='LC8'><span class="n">json</span><span class="o">.</span><span class="na">artifacts</span><span class="o">.</span><span class="na">each</span><span class="o">{</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">println</span> <span class="n">it</span></div><div class='line' id='LC10'><span class="o">}</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1430856/cea0186a862217015fb4fc2b63eb0ad3575c06fc/jenkinsBuildArtifacts.groovy" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1430856#file_jenkins_build_artifacts.groovy" style="float:right;margin-right:10px;color:#666">jenkinsBuildArtifacts.groovy</a>
            <a href="https://gist.github.com/1430856">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript><br />
Here&#8217;s the sample output at time of writing:</p>
<blockquote><p>[relativePath:dist/jruby-bin-1.7.0.dev.tar.gz, fileName:jruby-bin-1.7.0.dev.tar.gz, displayPath:null]<br />
[relativePath:dist/jruby-bin-1.7.0.dev.tar.gz.md5, fileName:jruby-bin-1.7.0.dev.tar.gz.md5, displayPath:null]<br />
[relativePath:dist/jruby-bin-1.7.0.dev.tar.gz.sha1, fileName:jruby-bin-1.7.0.dev.tar.gz.sha1, displayPath:null]<br />
[relativePath:dist/jruby-bin-1.7.0.dev.zip, fileName:jruby-bin-1.7.0.dev.zip, displayPath:null]<br />
[relativePath:dist/jruby-bin-1.7.0.dev.zip.md5, fileName:jruby-bin-1.7.0.dev.zip.md5, displayPath:null]<br />
[relativePath:dist/jruby-bin-1.7.0.dev.zip.sha1, fileName:jruby-bin-1.7.0.dev.zip.sha1, displayPath:null]<br />
[relativePath:dist/jruby-complete-1.7.0.dev.jar, fileName:jruby-complete-1.7.0.dev.jar, displayPath:null]<br />
[relativePath:dist/jruby-complete-1.7.0.dev.jar.md5, fileName:jruby-complete-1.7.0.dev.jar.md5, displayPath:null]<br />
[relativePath:dist/jruby-complete-1.7.0.dev.jar.sha1, fileName:jruby-complete-1.7.0.dev.jar.sha1, displayPath:null]<br />
[relativePath:dist/jruby-jars-1.7.0.dev.gem, fileName:jruby-jars-1.7.0.dev.gem, displayPath:null]<br />
[relativePath:dist/jruby-jars-1.7.0.dev.gem.md5, fileName:jruby-jars-1.7.0.dev.gem.md5, displayPath:null]<br />
[relativePath:dist/jruby-jars-1.7.0.dev.gem.sha1, fileName:jruby-jars-1.7.0.dev.gem.sha1, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.tar.gz, fileName:jruby-src-1.7.0.dev.tar.gz, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.tar.gz.md5, fileName:jruby-src-1.7.0.dev.tar.gz.md5, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.tar.gz.sha1, fileName:jruby-src-1.7.0.dev.tar.gz.sha1, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.zip, fileName:jruby-src-1.7.0.dev.zip, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.zip.md5, fileName:jruby-src-1.7.0.dev.zip.md5, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.zip.sha1, fileName:jruby-src-1.7.0.dev.zip.sha1, displayPath:null]</p></blockquote>
<h2>3. Read in a CSV file, filter it, and write out the result</h2>
<p>Groovy Grapes and one of my favorite libraries, <a href="http://opencsv.sourceforge.net/">OpenCSV</a>, make it trivial to script &#8216;one off&#8217; solutions for removing work that would normally take place manually in Excel. For me it comes up most often with data import/export from systems I&#8217;m working on and the need to create particular test environments using those import/export mechanisms. For example, using a scripted solution like this you can quickly:</p>
<ul>
<li>Export users from one test system into a CSV file, along with local phone number contact data</li>
<li>Replace the existing phone numbers with a mix of local and international numbers</li>
<li>Import the new data into a different test system</li>
<li>Verify that the system properly deals with international calling concerns</li>
</ul>
<p>This example simply trims out all of the rows where the second column of input contains values less than 100. It&#8217;s also nice to note that OpenCSV is smart enough to let you ignore one or more &#8216;header rows&#8217;, a common attribute of CSV files.<br />
<script src="http://gist.github.com/1430935.js?file=openCsv.groovy"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-1430935" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nd">@Grab</span><span class="o">(</span><span class="n">group</span> <span class="o">=</span> <span class="err">&#39;</span><span class="n">net</span><span class="o">.</span><span class="na">sf</span><span class="o">.</span><span class="na">opencsv</span><span class="err">&#39;</span><span class="o">,</span> <span class="n">module</span> <span class="o">=</span> <span class="err">&#39;</span><span class="n">opencsv</span><span class="err">&#39;</span><span class="o">,</span> <span class="n">version</span> <span class="o">=</span> <span class="err">&#39;</span><span class="mf">2.3</span><span class="err">&#39;</span><span class="o">)</span></div><div class='line' id='LC2'><span class="kn">import</span> <span class="nn">au.com.bytecode.opencsv.CSVReader</span></div><div class='line' id='LC3'><span class="kn">import</span> <span class="nn">au.com.bytecode.opencsv.CSVParser</span></div><div class='line' id='LC4'><span class="kn">import</span> <span class="nn">au.com.bytecode.opencsv.CSVWriter</span></div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'><span class="n">def</span> <span class="n">TEST_FILE_NAME</span> <span class="o">=</span> <span class="err">&#39;</span><span class="n">test</span><span class="o">.</span><span class="na">csv</span><span class="err">&#39;</span></div><div class='line' id='LC7'><span class="n">def</span> <span class="n">TEST_OUTPUT_FILE_NAME</span> <span class="o">=</span> <span class="err">&#39;</span><span class="n">testOut</span><span class="o">.</span><span class="na">csv</span><span class="err">&#39;</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'><span class="n">List</span><span class="o">&lt;</span><span class="n">String</span><span class="o">[]&gt;</span> <span class="n">rows</span> <span class="o">=</span> <span class="k">new</span> <span class="n">CSVReader</span><span class="o">(</span><span class="k">new</span> <span class="n">FileReader</span><span class="o">(</span><span class="k">new</span> <span class="n">File</span><span class="o">(</span><span class="n">TEST_FILE_NAME</span><span class="o">)),</span> <span class="n">CSVParser</span><span class="o">.</span><span class="na">DEFAULT_SEPARATOR</span><span class="o">,</span> <span class="n">CSVParser</span><span class="o">.</span><span class="na">DEFAULT_ESCAPE_CHARACTER</span><span class="o">,</span> <span class="n">CSVParser</span><span class="o">.</span><span class="na">DEFAULT_QUOTE_CHARACTER</span><span class="o">,</span> <span class="mi">1</span><span class="o">).</span><span class="na">readAll</span><span class="o">()</span></div><div class='line' id='LC10'><span class="n">def</span> <span class="n">rowsOver100</span> <span class="o">=</span> <span class="n">rows</span><span class="o">.</span><span class="na">findAll</span> <span class="o">{</span><span class="n">it</span><span class="o">[</span><span class="mi">1</span><span class="o">].</span><span class="na">toInteger</span><span class="o">()</span> <span class="o">&gt;</span> <span class="mi">100</span><span class="o">}</span></div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'><span class="n">File</span> <span class="n">output</span> <span class="o">=</span> <span class="k">new</span> <span class="n">File</span><span class="o">(</span><span class="n">TEST_OUTPUT_FILE_NAME</span><span class="o">)</span></div><div class='line' id='LC13'><span class="k">if</span> <span class="o">(</span><span class="n">output</span><span class="o">.</span><span class="na">exists</span><span class="o">())</span></div><div class='line' id='LC14'><span class="o">{</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">output</span><span class="o">.</span><span class="na">delete</span><span class="o">()</span></div><div class='line' id='LC16'><span class="o">}</span></div><div class='line' id='LC17'><span class="n">output</span><span class="o">.</span><span class="na">createNewFile</span><span class="o">()</span></div><div class='line' id='LC18'><span class="n">output</span><span class="o">.</span><span class="na">withWriter</span> <span class="o">{</span> <span class="n">writer</span> <span class="o">-&gt;</span></div><div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">new</span> <span class="nf">CSVWriter</span><span class="o">(</span><span class="n">writer</span><span class="o">).</span><span class="na">writeAll</span><span class="o">(</span><span class="n">rowsOver100</span><span class="o">)</span></div><div class='line' id='LC20'><br/></div><div class='line' id='LC21'><span class="o">}</span></div><div class='line' id='LC22'><br/></div><div class='line' id='LC23'><span class="c1">//println rows</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1430935/0c21cfe5a273ed552193c3b94e379d3bb941a5e6/openCsv.groovy" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1430935#file_open_csv.groovy" style="float:right;margin-right:10px;color:#666">openCsv.groovy</a>
            <a href="https://gist.github.com/1430935">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript></p>
<h2>4. Download, install and run a stand-alone webserver</h2>
<p>This example comes courtesy of a <a href="http://www.ibm.com/developerworks/java/library/j-javadev2-20/index.html">recent article by Andrew Glover</a> about <a href="https://github.com/groovypp/gretty/wiki">Gretty</a>, a lightweight http server. I don&#8217;t have a concrete use-case for this right now, but it&#8217;s easy to note that in this case you can code a large part of the server behaviour directly in the script, unlike, for instance, if you were to use a script to stand up a Jetty server. This should let you publish a script once in a central location and stand up as many Gretty servers providing the declared services as you like. This particular example simply echos back &#8216;Hello&#8217; plus whatever path you append to localhost:8080.<br />
<script src="http://gist.github.com/1431012.js?file=grettyExample.groovy"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-1431012" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">import</span> <span class="nn">org.mbte.gretty.httpserver.*</span> </div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="nd">@GrabResolver</span><span class="o">(</span><span class="n">name</span><span class="o">=</span><span class="err">&#39;</span><span class="n">gretty</span><span class="err">&#39;</span><span class="o">,</span> </div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="n">root</span><span class="o">=</span><span class="err">&#39;</span><span class="nl">http:</span><span class="c1">//groovypp.artifactoryonline.com/groovypp/libs-releases-local&#39;)</span></div><div class='line' id='LC5'><span class="nd">@Grab</span><span class="o">(</span><span class="err">&#39;</span><span class="n">org</span><span class="o">.</span><span class="na">mbte</span><span class="o">.</span><span class="na">groovypp</span><span class="o">:</span><span class="nl">gretty:</span><span class="mf">0.4</span><span class="o">.</span><span class="mi">279</span><span class="err">&#39;</span><span class="o">)</span> </div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'><span class="n">GrettyServer</span> <span class="n">server</span> <span class="o">=</span> <span class="o">[]</span> </div><div class='line' id='LC8'><span class="n">server</span><span class="o">.</span><span class="na">groovy</span> <span class="o">=</span> <span class="o">[</span> </div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nl">localAddress:</span> <span class="k">new</span> <span class="n">InetSocketAddress</span><span class="o">(</span><span class="s">&quot;localhost&quot;</span><span class="o">,</span> <span class="mi">8080</span><span class="o">),</span> </div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nl">defaultHandler:</span> <span class="o">{</span> </div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">response</span><span class="o">.</span><span class="na">redirect</span> <span class="s">&quot;/&quot;</span> </div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">},</span> </div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="s">&quot;/:name&quot;</span><span class="o">:</span> <span class="o">{</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">get</span> <span class="o">{</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">response</span><span class="o">.</span><span class="na">text</span> <span class="o">=</span> <span class="s">&quot;Hello ${request.parameters[&#39;name&#39;]}&quot;</span></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span> </div><div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span> </div><div class='line' id='LC18'><span class="o">]</span> </div><div class='line' id='LC19'><span class="n">server</span><span class="o">.</span><span class="na">start</span><span class="o">()</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1431012/e0bcf55e0b19d2cf070dab3d3797d2ee0b231655/grettyExample.groovy" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1431012#file_gretty_example.groovy" style="float:right;margin-right:10px;color:#666">grettyExample.groovy</a>
            <a href="https://gist.github.com/1431012">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript></p>
<h2>5. Remotely execute any of these scripts by url</h2>
<p>As of <a title="Groovy 1.8.3/1.9-beta-4" href="http://glaforge.appspot.com/article/groovy-1-8-3-and-1-9-beta-4-released" target="_blank">Groovy 1.8.3/1.9-beta-4</a> you can refer to a Groovy script hosted at a remote url and execute it locally. If you work on different machines a lot(as I do) this can really help keep your toolbox of scripts handy, regardless of where you are. Since these scripts are publicly hosted on GitHub(thanks guys!), you can simply copy the url from the &#8216;view raw&#8217; link at the bottom and go to your console to execute them like this:</p>
<pre class="brush: groovy; title: ; notranslate">
$ groovy https://gist.github.com/raw/1430856/cea0186a862217015fb4fc2b63eb0ad3575c06fc/jenkinsBuildArtifacts.groovy
{
    &quot;actions&quot;: [
        {
            &quot;causes&quot;: [
                {
                    &quot;shortDescription&quot;: &quot;Started by timer&quot;
                }
            ]
        },
        {
            &quot;buildsByBranchName&quot;: {
                &quot;origin/master&quot;: {
                    &quot;buildNumber&quot;: 684,
                    &quot;buildResult&quot;: null,
                    &quot;revision&quot;: {
                        &quot;SHA1&quot;: &quot;3419fee4bb9436d3222ff3df8dd7fcf2308a6919&quot;,
                        &quot;branch&quot;: [
                            {
                                &quot;SHA1&quot;: &quot;3419fee4bb9436d3222ff3df8dd7fcf2308a6919&quot;,
                                &quot;name&quot;: &quot;origin/master&quot;
                            }
                        ]
                    }
                }
            },
... and so on
</pre>
<h2>Final note</h2>
<p>Being able to share scripts across a variety of machines has definitely made my professional life a lot easier and I&#8217;m very glad to see the ability to execute code from a URL in Groovy. But what really turned me onto the idea was its usage in Gradle, which supports loading remote Groovy/Gradle scripts using the &#8220;apply from: {url or file}&#8221; syntax. I find that more and more I reference particular tasks remotely in a build, especially for static analysis tools that don&#8217;t necessarily need to be run on a regular basis.<br />
A great example of this is the recently released <a href="http://tellurianring.com/wiki/gradle/templates">Gradle Templates Plugin</a>, which is basically the Gradle answer to the <a href="http://maven.apache.org/archetype/maven-archetype-plugin/">Maven Archetype plugin</a>. Create a build.gradle with the following content:</p>
<pre class="brush: groovy; title: ; notranslate">
apply from: 'http://launchpad.net/gradle-templates/trunk/1.2/+download/apply.groovy'
</pre>
<p>And we have the following tasks available to create new Gradle projects and objects with conventional structure:</p>
<pre class="brush: groovy; title: ; notranslate">
Template tasks
--------------
createGradlePlugin - Creates a new Gradle Plugin project in a new directory named after your project.
createGroovyClass - Creates a new Groovy class in the current project.
createGroovyProject - Creates a new Gradle Groovy project in a new directory named after your project.
createJavaClass - Creates a new Java class in the current project.
createJavaProject - Creates a new Gradle Java project in a new directory named after your project.
createScalaClass - Creates a new Scala class in the current project.
createScalaObject - Creates a new Scala object in the current project.
createScalaProject - Creates a new Gradle Scala project in a new directory named after your project.
createWebappProject - Creates a new Gradle Webapp project in a new directory named after your project.
exportAllTemplates - Exports all the default template files into the current directory.
exportGroovyTemplates - Exports the default groovy template files into the current directory.
exportJavaTemplates - Exports the default java template files into the current directory.
exportPluginTemplates - Exports the default plugin template files into the current directory.
exportScalaTemplates - Exports the default scala template files into the current directory.
exportWebappTemplates - Exports the default webapp template files into the current directory.
initGradlePlugin - Initializes a new Gradle Plugin project in the current directory.
initGroovyProject - Initializes a new Gradle Groovy project in the current directory.
initJavaProject - Initializes a new Gradle Java project in the current directory.
initScalaProject - Initializes a new Gradle Scala project in the current directory.
initWebappProject - Initializes a new Gradle Webapp project in the current directory.
</pre>
<!-- AdSense Now! V1.95 -->
<!-- Post[count: 2] -->
<div class="adsense adsense-leadout" style="float:right;margin: 12px;"><script type="text/javascript"><!--
google_ad_client = "pub-6955914197200080";
/* 728x90, created 8/3/09 */
google_ad_slot = "4051815125";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2011/09/18/using-gradle-to-bootstrap-your-legacy-ant-builds/' rel='bookmark' title='Using Gradle to Bootstrap your Legacy Ant Builds'>Using Gradle to Bootstrap your Legacy Ant Builds</a></li>
<li><a href='http://www.kellyrob99.com/blog/2011/03/27/hooking-into-the-jenkinshudson-api/' rel='bookmark' title='Hooking into the Jenkins(Hudson) API'>Hooking into the Jenkins(Hudson) API</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/09/26/groovy-inspecteval-for-externalizing-data/' rel='bookmark' title='Groovy inspect()/Eval for Externalizing Data'>Groovy inspect()/Eval for Externalizing Data</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2011/12/04/five-cool-things-you-can-do-with-groovy-scripts/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Groovy and CSV: How to Get Your Data Out?</title>
		<link>http://www.kellyrob99.com/blog/2010/07/01/groovy-and-csv-how-to-get-your-data-out/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy-and-csv-how-to-get-your-data-out</link>
		<comments>http://www.kellyrob99.com/blog/2010/07/01/groovy-and-csv-how-to-get-your-data-out/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 21:07:35 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Comma-separated values]]></category>
		<category><![CDATA[csv]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[hsqldb]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[OpenCSV]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Spreadsheet]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1420</guid>
		<description><![CDATA[I don&#8217;t know exactly how many CSV files I&#8217;ve read/written to date, but I&#8217;m willing to bet it&#8217;s a lot. These kind of files are a simple and common way to exchange data and are interoperable with spreadsheet programs as well, making them more easily accessible to non-programmer types. There is some excellent support out [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/09/26/groovy-inspecteval-for-externalizing-data/' rel='bookmark' title='Groovy inspect()/Eval for Externalizing Data'>Groovy inspect()/Eval for Externalizing Data</a></li>
<li><a href='http://www.kellyrob99.com/blog/2011/12/04/five-cool-things-you-can-do-with-groovy-scripts/' rel='bookmark' title='Five Cool Things You Can Do With Groovy Scripts'>Five Cool Things You Can Do With Groovy Scripts</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t know exactly how many <a class="zem_slink" title="Comma-separated values" rel="wikipedia" href="http://en.wikipedia.org/wiki/Comma-separated_values">CSV</a> files I&#8217;ve read/written to date, but I&#8217;m willing to bet it&#8217;s a lot. These kind of files are a simple and common way to exchange data and are interoperable with spreadsheet programs as well, making them more easily accessible to non-programmer types.  There is some excellent support out there for reading and writing CSV files and so here, from simplest to most complex, are a few different ways to load and query the data trapped inside your CSV files. But first off&#8230;</p>
<p></p>
<h2>CSV is Not XML</h2>
<p>Or any other suitably constrained data format for that matter.  There are some pretty clear &#8216;rules&#8217; out there for transporting data in this format, but of course hardly anybody listens to them. I found <a href="http://creativyst.com/Doc/Articles/CSV/CSV01.htm#FileFormat">this</a> and <a href="http://en.wikipedia.org/wiki/Comma-separated_values#Basic_rules">this</a> in the first page of a quick Google search.<br />
However, while looking for available sample material on the web to demonstrate with, I found many great examples of how to screw it up: not quoting empty strings, not escaping embedded line breaks, commas embedded in unquoted text, etc.  All of these are things that prevent automation from properly interacting with the data.  There are also, of course, the CSV &#8216;formats&#8217; that insist on embedding comments and descriptions, trying to present more than one matrix of information or any of the other crazy things you can do when writing to a format with no real metadata layer.</p>
<p>&lt; \rant&gt;</p>
<p>Unfortunately, there&#8217;s nothing as convenient as an xml schema available for describing what information is encoded in the document and, in general, the only potentially useful metadata in an individual file is the header line. The good news is that all of these deficiencies can be overcome if you know they exist. And there&#8217;s some pretty nifty tools you can use to take out much of the guesswork. I&#8217;ll suggest a couple of ideas for how to deal with files that don&#8217;t adhere to the &#8216;rules&#8217;, but the main example I&#8217;ve decided on is a straightforward  and well formed set representing the periodic table of elements, provided generously by <a href="http://akiscode.com/pt/">Akiscode</a>. This file is directly machine readable(has no headers or embedded data), quotes all values and just follows all the &#8216;rules&#8217;. Here&#8217;s the first five lines as an example.<br />

<table id="wp-table-reloaded-id-4-no-1" class="wp-table-reloaded wp-table-reloaded-id-4">
<tbody>
	<tr class="row-1 odd">
		<td class="column-1">Atomic Number</td><td class="column-2">Atomic Mass</td><td class="column-3">Name</td><td class="column-4">Symbol</td>
	</tr>
	<tr class="row-2 even">
		<td class="column-1">1</td><td class="column-2">1.00794</td><td class="column-3">Hydrogen</td><td class="column-4">H</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">2</td><td class="column-2">4.002602</td><td class="column-3">Helium</td><td class="column-4">He</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">3</td><td class="column-2">6.941</td><td class="column-3">Lithium</td><td class="column-4">Li</td>
	</tr>
	<tr class="row-5 odd">
		<td class="column-1">4</td><td class="column-2">9.012182</td><td class="column-3">Beryllium</td><td class="column-4">Be</td>
	</tr>
	<tr class="row-6 even">
		<td class="column-1">5</td><td class="column-2">10.811</td><td class="column-3">Boron</td><td class="column-4">B</td>
	</tr>
</tbody>
</table>
<span class="wp-table-reloaded-table-description-id-4 wp-table-reloaded-table-description">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The simple format of the example CSV file.</span>
</p>
<p></p>
<h2>Groovy All by Itself</h2>
<p><a href="http://groovy.codehaus.org/">Groovy</a> makes dealing with String objects pretty painless.  By adding facilities like easy casting and find()/findAll() for quickly turning raw Strings into real data, you can program some fairly complex questions. In this simple example I&#8217;m depending on all values being quoted and I am not protecting against casting problems. I&#8217;m running this through Maven which really helps to keep test data organized; all you have to do is drop your test file in /src/test/resources and it&#8217;s automagically available on the test classpath.<br />
No specific handling is done for different types here; everything is read in as a String and cast to a more specific type as needed. In a &#8216;real&#8217; application you&#8217;re very likely going to encounter mixed alphanumeric data in any given column of data &#8211; &#8216;UNKNOWN&#8217; instead of a number in a column labeled &#8216;Quantity&#8217; for instance &#8211; and be more careful about casting.</p>
<pre class="brush: groovy; title: ; notranslate">
//load and split the file
InputStream inputFile = getClass().classLoader.getResourceAsStream(TEST_FILE_NAME)
String[] lines = inputFile.text.split('\n')
List&lt;String[]&gt; rows = lines.collect {it.split(',')}

/**
 * A little helper method to get rid of the quotes in the input
 * and cast values so they can be compared properly.
 */
private double castToDouble(string)
{
    return string.replaceAll('&quot;', '').toDouble()
}

//OK, it's parsed - let's ask some questions
private static final int ATOMIC_MASS = 1;

def elementsOver200Mass = rows.findAll {castToDouble(it[ATOMIC_MASS]) &gt; 200}
def elementsBetween10And20 = rows.findAll { row -&gt;
            double mass = castToDouble(row[ATOMIC_MASS])
            mass &lt;= 20 &amp;&amp; mass &gt;= 10
}
</pre>
<p>So this approach works fine for well formed input, but falls apart quickly in other cases. For instance, if any columns in the file are missing values the split() function treats them as nulls, leading to different size arrays being stored in the list. Similarly you need to deal with quoted VS non-quoted content, embedded line breaks and other issues individually. Fortunately, some nice guys have done that for us.</p>
<p></p>
<h2>OpenCSV</h2>
<p><a href="http://blogs.bytecode.com.au/glen/">Glen Smith&#8217;s</a> <a href="http://opencsv.sourceforge.net/">OpenCSV</a> library nicely abstracts away a lot of the minutiae of dealing with CSV. It properly deals with escaped characters, multiline input and a host of other issues for you. Give it pretty much anything that satisfies the Reader interface as an input and it&#8217;s good to go. The return type of the CSVReader.readAll() method also satisfies the same contract as the plain Groovy version shown above, so we can interact with the parsed results in exactly the same way as in the previous example.<br />
All values are still typed as Strings, so we need to cast in order to compare numeric values.</p>
<pre class="brush: groovy; title: ; notranslate">
import au.com.bytecode.opencsv.CSVReader

List&lt;String[]&gt; rows = new CSVReader(
        new InputStreamReader(getClass().classLoader.getResourceAsStream(TEST_FILE_NAME)))
            .readAll()

//same finders as in the Groovy version
def elementsOver200Mass = rows.findAll {it[ATOMIC_MASS].toDouble() &gt; 200}
def elementsBetween10And20 = rows.findAll { row -&gt;
    double mass = castToDouble(row[ATOMIC_MASS])
    mass &lt;= 20 &amp;&amp; mass &gt;= 10
}
</pre>
<p></p>
<h2>HsqlDB</h2>
<p>HsqlDB allows for using flat files as <a href="http://hsqldb.org/doc/2.0/guide/texttables-chapt.html">Text Tables</a>, effectively turning a CSV file into a database table. Data values are cast to the types specified in your table definition, so any potential type cast failures happen right up front when loading the data. The benefit is that once the data is read in no further manual processing is necessary. Note: by default the csv file and the database file must be located in the same directory, as a security precaution (can be overridden through configuration).</p>
<p>In addition, leveraging sql makes querying the data extremely easy. Groovy brings in the <a href="http://groovy.codehaus.org/api/groovy/sql/Sql.html">Sql class</a> to abstract away a lot of the normal <a class="zem_slink" title="Java (programming language)" rel="homepage" href="http://java.sun.com">Java</a> boilerplate you encounter when working with a <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/sql/ResultSet.html">ResultSet</a>. I didn&#8217;t do any in-depth testing to prove it out, but this is also the only one of the strategies described here that doesn&#8217;t require holding the entire data in memory in order to do arbitrary queries. That can be mitigated in the previously shown methods by processing files line by line rather than in bulk if memory usage is a concern.</p>
<pre class="brush: groovy; title: ; notranslate">
//create the table definition to insert
String tableName = 'elements'
String tableDefinition = &quot;&quot;&quot;CREATE TEXT TABLE $tableName (
    atomic_number INTEGER PRIMARY KEY,
    atomic_mass NUMERIC,
    name VARCHAR(255),
    symbol VARCHAR(3)
);&quot;&quot;&quot;

//create a new file database and a table corresponding to the csv file
Sql sql = Sql.newInstance(&quot;jdbc:hsqldb:file:${testdbDir.absolutePath}/testdb&quot;, 'sa', ''
    ,'org.hsqldb.jdbcDriver')
sql.execute(tableDefinition)

//set the source to the csv file
sql.execute(&quot;SET TABLE elements SOURCE '${TEST_FILE_NAME};all_quoted=true'&quot;.toString())

//querying the database that's wrapping our CSV file
def elementsOver200Mass = sql.rows(&quot;SELECT * FROM $tableName WHERE atomic_mass &gt; ?&quot;, [200])
def elementsBetween10And20 = sql.rows(
    &quot;SELECT * FROM $tableName WHERE atomic_mass &lt;= ? AND atomic_mass &gt;= ?&quot;, [20, 10])

//simple db aggregates
def count = 0
sql.eachRow(&quot;SELECT count(1) FROM $tableName WHERE atomic_mass &lt;= ?&quot;, [20]){row-&gt;
    count = row[0]
}
def avg = 0
sql.eachRow(&quot;SELECT avg(atomic_mass) FROM $tableName&quot;.toString()){row-&gt;
    avg = row[0]
}
</pre>
<p></p>
<h2>Which One do I Use???</h2>
<p>Pick the one that fits best for your use case is the real answer. I didn&#8217;t know about the HsqlDB option until recently, but OpenCSV has been a personal standby for years. Then again, if you&#8217;re writing something quick and dirty at the script level, the simplicity of just applying a couple of split() operations is pretty appealing. Here&#8217;s how I generally decide.</p>

<table id="wp-table-reloaded-id-5-no-1" class="wp-table-reloaded wp-table-reloaded-id-5">
<thead>
	<tr class="row-1">
		<th class="column-1"></th><th class="column-2">Plain Groovy</th><th class="column-3">OpenCSV</th><th class="column-4">HsqlDB</th>
	</tr>
</thead>
<tbody>
	<tr class="row-2">
		<td class="column-1">Use it</td><td class="column-2">File contains well-formed input and questions to be asked involve a small subset of columns.</td><td class="column-3">File contains well or badly formed input and questions to be asked involve a small subset of columns.</td><td class="column-4">File contains well or badly formed input, questions to be asked involve many columns or span multiple files.</td>
	</tr>
	<tr class="row-3">
		<td class="column-1">Don't use it</td><td class="column-2">File contains badly formed input or questions being asked are complex.</td><td class="column-3">Not able to easily leverage the OpenCSV library.</td><td class="column-4">Not able to easily leverage the HsqlDB database.</td>
	</tr>
	<tr class="row-4">
		<td class="column-1">Where it works</td><td class="column-2">Groovy only</td><td class="column-3">Groovy or Java</td><td class="column-4">Groovy or Java</td>
	</tr>
</tbody>
</table>
<span class="wp-table-reloaded-table-description-id-5 wp-table-reloaded-table-description">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Some common sense guidelines for which method to apply given a problem to solve.</span>

<div class="zemanta-pixie"><a class="zemanta-pixie-a" title="Enhanced by Zemanta" href="http://www.zemanta.com/"><img class="zemanta-pixie-img" src="http://img.zemanta.com/zemified_a.png?x-id=104c23a4-eae4-4092-87ab-7680f9df82e2" alt="Enhanced by Zemanta" /></a><span class="zem-script more-related pretty-attribution"><script src="http://static.zemanta.com/readside/loader.js" type="text/javascript"></script></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/09/26/groovy-inspecteval-for-externalizing-data/' rel='bookmark' title='Groovy inspect()/Eval for Externalizing Data'>Groovy inspect()/Eval for Externalizing Data</a></li>
<li><a href='http://www.kellyrob99.com/blog/2011/12/04/five-cool-things-you-can-do-with-groovy-scripts/' rel='bookmark' title='Five Cool Things You Can Do With Groovy Scripts'>Five Cool Things You Can Do With Groovy Scripts</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/07/01/groovy-and-csv-how-to-get-your-data-out/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Achieving Groovy-like Fluency in Java with Google Collections</title>
		<link>http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=achieving-groovy-like-fluency-in-java-with-google-collections</link>
		<comments>http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/#comments</comments>
		<pubDate>Sun, 16 May 2010 05:33:19 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Collections]]></category>
		<category><![CDATA[DataProvider]]></category>
		<category><![CDATA[fluent syntax]]></category>
		<category><![CDATA[GMaven]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[google-collections]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[guava]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[MultiMap]]></category>
		<category><![CDATA[mvn]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[TestNG]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1261</guid>
		<description><![CDATA[One of the most compelling things about using Groovy is the fluent and concise syntax, as well as the productivity and readability gains that come out of it. But there&#8217;s no reason not to take advantage of some of the same techniques and some library support, in this case google-collections, to make Java code easy [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/04/19/groovy-and-glazed-lists-with-grape/' rel='bookmark' title='Groovy and Glazed Lists with Grape'>Groovy and Glazed Lists with Grape</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/' rel='bookmark' title='Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;'>Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/02/08/my-favorite-new-groovy-trick/' rel='bookmark' title='My favorite new Groovy trick'>My favorite new Groovy trick</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>One of the most compelling things about using Groovy is the fluent and concise syntax, as well as the productivity and readability gains that come out of it. But there&#8217;s no reason not to take advantage of some of the same techniques and some library support, in this case <a href="http://code.google.com/p/google-collections/">google-collections</a>, to make Java code easy to write AND to read.</p>
<h2>Creating Collections</h2>
<p>Groovy really shines for this one, making the creation of Lists and Maps, empty or populated, an absolute breeze. Java has some help for creating basic Lists but begins to struggle when creating maps. This is an area that google-collections can help in, especially in regards to creating immutable Maps.</p>
<pre class="brush: groovy; title: ; notranslate">
//Empty Lists
        List&lt;String&gt; groovyList = []
        List&lt;String&gt; javaList = new ArrayList&lt;String&gt;()
        List&lt;String&gt; googleList = Lists.newArrayList()  //can omit generics

//Populated Lists
        List&lt;String&gt; groovyList = [&quot;1&quot;, &quot;2&quot;]
        List&lt;String&gt; javaList = Arrays.asList(&quot;1&quot;, &quot;2&quot;)
        List&lt;String&gt; googleList = Lists.newArrayList(&quot;1&quot;, &quot;2&quot;)

//Immutable Lists
        List&lt;String&gt; groovyList = [&quot;1&quot;, &quot;2&quot;].asImmutable()
        List&lt;String&gt; javaList = Collections.unmodifiableList(Arrays.asList(&quot;1&quot;, &quot;2&quot;))
        List&lt;String&gt; googleList = ImmutableList.of(&quot;1&quot;, &quot;2&quot;)

//Empty Maps
        Map&lt;String, String&gt; groovyMap = [:]
        Map&lt;String, String&gt; javaMap = new LinkedHashMap&lt;String,String&gt;()
        Map&lt;String, String&gt; googleMap = Maps.newLinkedHashMap()

//Immutable Maps
        Map&lt;String, String&gt; groovyMap = [&quot;a&quot;:&quot;1&quot;, &quot;b&quot;:&quot;2&quot;].asImmutable()

        Map&lt;String, String&gt; javaMap = new LinkedHashMap&lt;String,String&gt;()
        javaMap.put(&quot;a&quot;, &quot;1&quot;)
        javaMap.put(&quot;b&quot;, &quot;2&quot;)
        javaMap = Collections.unmodifiableMap(javaMap)

        //OR(works only in Java, will not compile in Groovy)
        Map&lt;String, String&gt; javaMap = new LinkedHashMap&lt;String, String&gt;()
        {
            {
                put(&quot;a&quot;, &quot;1&quot;);
                put(&quot;b&quot;, &quot;2&quot;);
            }
        };

        Map&lt;String, String&gt; googleMap = ImmutableMap.of(&quot;a&quot;, &quot;1&quot;, &quot;b&quot;, &quot;2&quot;)  //clunky syntax but it works
</pre>
<h2>Filtering Collections</h2>
<p>Groovy provides the very handy &#8216;findAll&#8217; method that allows you to filter a Collection by applying a Closure. Google-collections provides similar facilities using the Predicate interface and two filter methods available statically on Collections2 and Iterables. This would also be a lot more readable if the Predicate definition were extracted but I wanted to show that it&#8217;s still possible to create them in-line quickly.</p>
<pre class="brush: groovy; title: ; notranslate">
import static com.google.common.collect.Collections2.*

List&lt;Integer&gt; toFilter = [1, 2, 3, 4, 5]
List&lt;Integer&gt; groovyVersion = toFilter.findAll{ it &lt; 3}
List&lt;Integer&gt; googleVersion = filter(toFilter, new Predicate&lt;Integer&gt;()
    {
        public boolean apply(Integer input)
        {
            return input &lt; 3;
        }
    };)
</pre>
<h2>Joining Collections into a String Representation</h2>
<p>This one has come up pretty often over the years, and it&#8217;s not surprising that where the JDK hasn&#8217;t provided, enterprising developers have added support through libraries. The problem is: given a Collection of objects, create a String representation of that Collection suitable for view from a consumer of the system. And admit it &#8211; the first time you hand-coded the algorithm you left a trailing comma, didn&#8217;t you? I know I did.<br />
Groovy has fantastic support for this use-case by simply including the &#8216;join&#8217; method on Lists. Google-collections utilizes static calls on the Joiner class along with a simple DSL-like syntax to achieve the same effect. Throw in a static import to make it even more concise and it does a fine job. These two examples yield the same result.</p>
<pre class="brush: groovy; title: ; notranslate">
import static com.google.common.base.Joiner.*
def toJoin = ['a', 'b', 'c']
def separator = ', '

//groovy version
def groovyJoin = toJoin.join(separator)

//google-collections version
def googleJoin = on(separator).join(toJoin)
</pre>
<p>And google-collections also supports join for Maps, something missing from Groovy(although not very hard to implement).</p>
<pre class="brush: groovy; title: ; notranslate">
import static com.google.common.base.Joiner.*
def toJoin = [1: 'a', 2: 'b', 3: 'c']
def separator = ', '
def keyValueSeparator = ':'

//results in '1:a, 2:b, 3:c' which is essentially what is returned from Groovy map.toMapString()
def googleVersion = on(separator).withKeyValueSeparator(keyValueSeparator).join(map)

//results in '1 is a and 2 is b and 3 is c'
googleVersion = on(&quot; and &quot;).withKeyValueSeparator(&quot; is &quot;).join(map)

//doing the same in Groovy is slightly more involved, but really not that bad
def groovyVersion = toJoin.inject([]) {builder, entry -&gt;
            builder &lt;&lt; &quot;${entry.key} is ${entry.value}&quot;
            builder
        }.join(' and ')
</pre>
<h2>Multimaps</h2>
<p>Multimaps are one of the more interesting parts of google-collections, at least to me. Have you ever found yourself writing code to create a Map of keys to Lists? Well the various <a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Multimap.html">Multimap</a> implementations in google-collections mean you never have to write that boilerplate kind of code again. Here&#8217;s a &#8220;first-stab&#8221; effort to simulate a fairly generic Multimap with pure Java code.</p>
<pre class="brush: groovy; title: ; notranslate">
public class JavaMultimap
{
    private Map&lt;Object, List&lt;Object&gt;&gt; multimap = new LinkedHashMap&lt;Object, List&lt;Object&gt;&gt;();

    public boolean put(Object key, Object value)
    {
        List&lt;object&gt; objects = multimap.get(key);
        objects = objects != null ? objects : new ArrayList&lt;object&gt;();
        objects.add(value);
        multimap.put(key, objects);
        return true;
    }
}
</pre>
<p>
And the same thing in Groovy, achieving a slightly smaller version.</p>
<pre class="brush: groovy; title: ; notranslate">
class GroovyMultimap
{
    Map map = [:]

    public boolean put(Object key, Object value)
    {
        List list = map.get(key, [])
        list.add(value)
        map.&quot;$key&quot; = list
    }
}
</pre>
<p>I did some primitive timings comparing Java, Groovy and google-collections Multimaps implementations and, as you&#8217;d pretty much expect, google clearly takes the lead.  Where things really start to get interesting though is when you start using the Multimap in Groovy code. Imagine if you will that you want to iterate over a collection of Objects and map some of the properties to a List. Here&#8217;s a contrived example of what I&#8217;m talking about, but applying this same pattern to domain objects in your application or even a directory full of xml files is pretty much the same. If you look closely you&#8217;ll notice that Groovy actually makes this a one liner to extract all values for a property across a List of Objects(used in the assertion), but I imagine that Multimap is probably a better alternative for large data sets.</p>
<pre class="brush: groovy; title: ; notranslate">
class GoogleCollectionsMultiMapTest
{
    private Random random = new Random()

    @Test
    public void testMultimap()
    {
        def list = []
        10.times {
            list &lt;&lt; createObject()
        }
        List properties = ['value1', 'value2', 'value3']
        Multimap multimap = list.inject(LinkedListMultimap.create()) {Multimap map, object -&gt;
            properties.each {
                map.put(it, object.&quot;$it&quot;)
            }
            map
        }
        properties.each {
            assertEquals (multimap.get(it), list.&quot;$it&quot;)
        }
    }

    Object createObject()
    {
        Expando expando = new Expando()
        expando.value1 =  random.nextInt(10) + 1
        expando.value2 =  random.nextInt(100) + 100
        expando.value3 =  random.nextInt(50) + 50
        return expando
    }
}
</pre>
<h2>So Where Does This Get Us?</h2>
<p>Between google-collections and <a href="http://code.google.com/p/guava-libraries/">the newer guava-libraries</a> that contain it, there&#8217;s lots of help available for simplifying programming problems and making your code more readable. I haven&#8217;t even touched on the newly available support for primitives, Files, Streams and more, but if you&#8217;re interested in reducing the amount of code you write AND simultaneously making it more readable you should probably take a look. There&#8217;s a very nice overview available in <a href="http://codemunchies.com/2009/10/beautiful-code-with-google-collections-guava-and-static-imports-part-1/">part one</a> and <a href="http://codemunchies.com/2009/10/diving-into-the-google-guava-library-part-2/">part two</a> by <a href="http://twitter.com/astensby">Aleksander Stensby</a>.  And here&#8217;s a <a href="http://bwinterberg.blogspot.com/2009/09/introduction-to-google-collections.html">closer look at what google-collections can do for you</a>.</p>
<h2>Source Code</h2>
<p>As per usual, source code is <a href="http://github.com/kellyrob99/groovy-google-collections">available at github as a maven project</a>. Big thanks to the Spock team for sharing <a href="http://old.nabble.com/GMaven-and-Groovy-1.7-td27378212.html">how they configure GMaven to properly utilize Groovy 1.7</a>.  Please feel free to take a look and comment here. Thanks!</p>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/04/19/groovy-and-glazed-lists-with-grape/' rel='bookmark' title='Groovy and Glazed Lists with Grape'>Groovy and Glazed Lists with Grape</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/' rel='bookmark' title='Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;'>Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/02/08/my-favorite-new-groovy-trick/' rel='bookmark' title='My favorite new Groovy trick'>My favorite new Groovy trick</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Groovy and Hibernate Validator for Dynamic Constraints</title>
		<link>http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy-and-hibernate-validator-for-dynamic-constraints</link>
		<comments>http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/#comments</comments>
		<pubDate>Sun, 18 Apr 2010 06:17:50 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JBoss Seam]]></category>
		<category><![CDATA[kellyrob99.com]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[theKaptain]]></category>
		<category><![CDATA[User interface]]></category>
		<category><![CDATA[validator]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1263</guid>
		<description><![CDATA[I was reading this article about hibernate validator today and it inspired me to apply a little Groovy to the problem of validating a bean. More specifically, finding out how hard it would be to apply different validation rules to the same classes at runtime. Turns out it&#8217;s really pretty simple. Hibernate validator, if you [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/07/01/groovy-and-csv-how-to-get-your-data-out/' rel='bookmark' title='Groovy and CSV: How to Get Your Data Out?'>Groovy and CSV: How to Get Your Data Out?</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/12/16/jira-grails-plugin/' rel='bookmark' title='Jira Grails Plugin'>Jira Grails Plugin</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/' rel='bookmark' title='Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code'>Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I was reading <a href="http://java.dzone.com/articles/using-hibernate-validator">this article about hibernate validator</a> today and it inspired me to apply a little <a class="zem_slink" href="http://groovy.codehaus.org" title="Groovy (programming language)" rel="homepage">Groovy</a> to the problem of validating a bean.  More specifically, finding out how hard it would be to apply different validation rules to the same classes at runtime. Turns out it&#8217;s really pretty simple.<br />
<a href="http://www.hibernate.org/subprojects/validator/download.html">Hibernate validator</a>, if you didn&#8217;t already know, is the reference implementation of <a href="http://jcp.org/en/jsr/detail?id=303">JSR-303</a> and it provides the ability to specify by xml or annotation configuration validation rules for pojos.</p>
<p></p>
<h2>Where Hibernate Validator Shines</h2>
<p>Annotations on domain classes allow for easily validating object state at the time of persistence. Excellent integration with frameworks like <a class="zem_slink" href="http://www.seamframework.org" title="JBoss Seam" rel="homepage">JBoss Seam</a> allow this same ability to be utilized for validating web forms on the client-side with little more than an <a href="http://docs.jboss.org/seam/1.2.1.GA/reference/en/html/validation.html">&lt;s:validateAll/&gt; tag</a>. Seam practically hides the entire interaction with validation components from the developer. Since validation rules are defined directly in the domain class, you can (almost) guarantee that no objects with inconsistent state will ever end up being saved in your database.  There are certain validations that aren&#8217;t possible to verify without actually looking in the database, unique constraints for example, but generally in my experience hibernate validator is extremely easy to configure and work with. Implementing <a class="zem_slink" href="http://en.wikipedia.org/wiki/Create%2C_read%2C_update_and_delete" title="Create, read, update and delete" rel="wikipedia">CRUD</a> functionality is pretty trivial, and UIs can achieve consistency since all validations are applied equally.<br />
Alternatively, if you can&#8217;t or don&#8217;t want to use annotations for some reason, you can specify your validation rules in an xml file. Usually a singleton validation.xml file is made available on the classpath and picked up automagically when a ValidationFactory is created. A simple xml configuration looks like this:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;constraint-mappings xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemalocation=&quot;http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd&quot; xmlns=&quot;http://jboss.org/xml/ns/javax/validation/mapping&quot;&gt;
    &lt;default-package&gt;org.kar.test&lt;/default-package&gt;
    &lt;bean class=&quot;ValidateTestableClass&quot;&gt;
        &lt;field name=&quot;name&quot;&gt;
            &lt;constraint annotation=&quot;javax.validation.constraints.NotNull&quot;&gt;
        &lt;/constraint&gt;
    &lt;/field&gt;
&lt;/bean&gt;
</pre>
<p>and is meant to be applied to this simple class:</p>
<pre class="brush: groovy; title: ; notranslate">
class ValidateTestableClass
{
    int id
    String name
    String description
    boolean enabled
}
</pre>
<p></p>
<h2>Comparing with <a class="zem_slink" href="http://grails.org" title="Grails (framework)" rel="homepage">Grails</a> Validation</h2>
<p>Grails automatically provides <a href="http://www.grails.org/doc/latest/guide/7.%20Validation.html">validation capabilities</a> for domain classes and command objects, and enables adding the same behavior to any pogo through a combination of the @Validateable annotation and a static constraints closure. Adding validation support to arbitrary classes also requires specifying which packages to scan for the annotation.<br />
Plugin support from projects like <a href="http://www.grails.org/plugin/bean-fields">bean-fields</a> simplifies the handling of client-side validation and rendering error markers in the UI, an ability which the Grails framework provides natively by adding an &#8216;errors&#8217; field directly onto the domain or command object class instances bound to a web form.</p>
<p></p>
<h2>Dynamic Constraints</h2>
<p>Both the hibernate validator and the Grails strategies for applying validation described here have the same limitation: both are universally applied to all instances of a class. There&#8217;s no easy apparent way to override those constraints at runtime, although I suspect that some fancy MOP&#8217;ing or configuration could probably be used to accomplish overrides at runtime.<br />
Hibernate validator also supports creation of ad hoc validators by seeding with one or more xml documents. Or if you&#8217;re like me and hate hand editing xml, you can leverage Groovy to take a bit of the pain away. Here&#8217;s the same xml snippet from above in a Groovy Closure, generated simply by turning the DomToGroovy class loose on the raw xml:</p>
<pre class="brush: groovy; title: ; notranslate">
looseConstraint = {
        mkp.declareNamespace(xsi: 'http://www.w3.org/2001/XMLSchema-instance')
        'constraint-mappings'(xmlns: 'http://jboss.org/xml/ns/javax/validation/mapping',
                'xsi:schemaLocation': 'http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd') {
            'default-package'('org.kar.test.objects')
            bean('class': 'ValidateTestableClass') {
                field(name: 'name') {
                    constraint(annotation: 'javax.validation.constraints.NotNull')
                }
            }
        }
    }
</pre>
<p>Losing all the angle brackets is a good start, but we really haven&#8217;t saved a lot of typing. Until you start taking advantage of the ability to define more complicated structures. Note the use of a list structure here to apply NotNull constraints to multiple fields.</p>
<pre class="brush: groovy; title: ; notranslate">
strictConstraint = {
        mkp.declareNamespace(xsi: 'http://www.w3.org/2001/XMLSchema-instance')
        'constraint-mappings'(xmlns: 'http://jboss.org/xml/ns/javax/validation/mapping',
                'xsi:schemaLocation': 'http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd') {
            'default-package'('org.kar.test.objects')
            bean('class': 'ValidateTestableClass') {
                ['name', 'description'].each {
                    field(name: it) {
                        constraint(annotation: 'javax.validation.constraints.NotNull')
                    }
                }
                field(name: 'id') {
                    constraint(annotation: 'javax.validation.constraints.DecimalMin') {
                        element(name: 'value', '2')
                    }
                }
                field(name: 'enabled') {
                    constraint(annotation: 'javax.validation.constraints.AssertTrue')
                }
            }
        }
    }
</pre>
<p></p>
<h2>Applying Dynamic Constraints</h2>
<p>Applying constraints is as simple as converting Closures to xml and mapping them to a Configuration object, which then supplies a Validator to use. StreamingMarkupBuilder is utilized to create the xml behind the scenes.</p>
<pre class="brush: groovy; title: ; notranslate">
    /**
     * Create a configuration object passing closures as validation mapping documents.
     * @param closures closures to render into validation mapping documents
     * @return config
     */
    public Configuration createConfig(Closure... closures)
    {
        Configuration config = Validation.byDefaultProvider().configure()
        closures.each {
            config.addMapping(new ByteArrayInputStream(GroovyXmlConversionUtil.convertToXml(it).bytes))
        }
        config
    }
</pre>
<p>I haven&#8217;t tested the use of multiple mappings extensively, but minimally each class you&#8217;re configuring must be confined to a single mapping &#8211; you can&#8217;t extend the validations by layering configurations on top of one another. You should however be able to map constraints for different classes in separate Closures.</p>
<p></p>
<h2>Crying out for a Builder!</h2>
<p>Going from Closures to xml is a quick and dirty way to test out this functionality, but what would really be nice is a Builder that could create an appropriate validation environment more directly. At the least it would allow for removing the namespace declarations and explicit package naming that make up the bulk of the content.</p>
<h2>So what do you get?</h2>
<ol>
<li>1. Ability to declare validations against any existing <a class="zem_slink" href="http://java.sun.com" title="Java (programming language)" rel="homepage">Java</a> or Groovy class without changing the source code</li>
<li>2. Programmatic ability to create the configuration of validations</li>
<li>3. A choice of which validations to apply at runtime</li>
<li>4. Consistency with the behavior of domain class validation</li>
</ol>
<p>And what&#8217;d I get? A fun bit of quick coding on a Saturday afternoon. Nice! Source code is <a href="http://github.com/kellyrob99/groovy-hibernate-validator">available on git-hub</a> if you want to check it out.</p>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" title="Reblog this post [with Zemanta]" href="http://reblog.zemanta.com/zemified/c83e9a1b-1079-49a8-80cb-95c76b967f69/"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=c83e9a1b-1079-49a8-80cb-95c76b967f69" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script src="http://static.zemanta.com/readside/loader.js" type="text/javascript"></script></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/07/01/groovy-and-csv-how-to-get-your-data-out/' rel='bookmark' title='Groovy and CSV: How to Get Your Data Out?'>Groovy and CSV: How to Get Your Data Out?</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/12/16/jira-grails-plugin/' rel='bookmark' title='Jira Grails Plugin'>Jira Grails Plugin</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/' rel='bookmark' title='Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code'>Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code</title>
		<link>http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code</link>
		<comments>http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/#comments</comments>
		<pubDate>Sun, 14 Mar 2010 23:44:59 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Application programming interface]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Java2D]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[Open source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[tesseract-ocr]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1158</guid>
		<description><![CDATA[I read an interesting article recently about using python and open source software to defeat a particular captcha implementation and I set out to see how hard it would be to do the same in Groovy. In particular, coming from the Java side of the fence, I was impressed by how the available libraries in [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/' rel='bookmark' title='Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;'>Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/' rel='bookmark' title='Groovy and Hibernate Validator for Dynamic Constraints'>Groovy and Hibernate Validator for Dynamic Constraints</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I read <a href="http://www.bonsai-sec.com/blog/index.php/breaking-weak-captcha-in-26-lines-of-code/">an interesting article</a> recently about using python and <a class="zem_slink" href="http://www.wikinvest.com/concept/Open_Source" title="Open Source" rel="wikinvest">open source</a> software to defeat a particular captcha implementation and I set out to see how hard it would be to do the same in Groovy. In particular, coming from the <a class="zem_slink" href="http://java.sun.com" title="Java (programming language)" rel="homepage">Java</a> side of the fence, I was impressed by how the available libraries in python made loading, mutating and saving images so easy. Admittedly I have limited experience working with image data, but when I have it has always seemed like a complex(and easy to get wrong) process. Maybe there&#8217;s a Java library out there that provides a simple &#8216;image_resize&#8217; method, but it&#8217;s certainly not in the BufferedImage <a class="zem_slink" href="http://en.wikipedia.org/wiki/Application_programming_interface" title="Application programming interface" rel="wikipedia">API</a>. Still, when porting the 26 lines of code over to Groovy, I was able to get it considerably less verbose than the Java equivalent.</p>
<p></p>
<h2>The Pretty Pictures</h2>
<p>Here are the three images to test against. In order to put them in a suitable format for <a href="http://code.google.com/p/tesseract-ocr">the open source tesseract-ocr program</a> to process we need to make them bigger, remove the background noise and transform them into a &#8216;tif&#8217; format. The python program we&#8217;re porting utilizes the PIL library for image handling and the pytesseract library for wrapping tesseract; I didn&#8217;t look very hard for java equivalents and just coded the required functions directly.</p>
<table>
<tbody>
<tr>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/9koo.gif" title="Original image for 9koO" class="shutterset_singlepic58" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/58__x_9koo.gif" alt="9koo" title="9koo" />
</a>
</td>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/jxt9.gif" title="Original image for jxt9" class="shutterset_singlepic60" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/60__x_jxt9.gif" alt="jxt9" title="jxt9" />
</a>
</td>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/e4ya.gif" title="Original image for e4ya" class="shutterset_singlepic59" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/59__x_e4ya.gif" alt="e4ya" title="e4ya" />
</a>
</td>
</tr>
</tbody>
</table>
<p></p>
<h2>Reading in the Image</h2>
<p>The python code for this is three lines, one to load the image and a couple more to convert it into a format suitable for directly manipulating pixel color through <a class="zem_slink" href="http://en.wikipedia.org/wiki/RGB_color_model" title="RGB color model" rel="wikipedia">RGB</a> values. Groovy takes a bit more to do the same, but being able to use a &#8216;with&#8217; block makes interacting with the Graphics object a lot cleaner than the same Java code</p>
<pre class="brush: groovy; title: ; notranslate">
//python
from PIL import Image
img = Image.open('input.gif')
img = img.convert(&quot;RGBA&quot;)
pixdata = img.load()

//Groovy
BufferedImage image = ImageIO.read(new File(fileName))
BufferedImage dimg = new BufferedImage(image.width, image.height, BufferedImage.TYPE_INT_ARGB)
dimg.createGraphics().with {
    setComposite(AlphaComposite.Src)
    drawImage(image, null, 0, 0)
    dispose()
}
</pre>
<p></p>
<h2>Removing the Background Noise</h2>
<p>In both cases we&#8217;re doing essentially the same thing: finding all non-black pixels and setting them to white. This leaves only the actual embedded text to stand out. Being able to utilize the Java Color constants makes the Groovy version a little more readable, IMO, but otherwise the two pieces of code are generally equivalent.</p>
<pre class="brush: groovy; title: ; notranslate">
//python
for y in xrange(img.size[1]):
    for x in xrange(img.size[0]):
        if pixdata[x, y] != (0, 0, 0, 255):
            pixdata[x, y] = (255, 255, 255, 255)

//Groovy
(0..&lt;dimg.height).each {i=&quot;&quot; -=&quot;&quot;&gt;
    (0..&lt;dimg.width).each {j=&quot;&quot; -=&quot;&quot;&gt;
        if (dimg.getRGB(j, i) != Color.BLACK.RGB)
        {
            dimg.setRGB(j, i, Color.WHITE.RGB)
        }
    }
}
</pre>
<p></p>
<h2>Resizing the Image</h2>
<p><a class="zem_slink" href="http://www.python.org/" title="Python (programming language)" rel="homepage">Python</a>&#8216;s library usage really shines here, making this a one line call. Not quite the same in Java-land, although again there&#8217;s probably a better way to do this(I just don&#8217;t know it offhand).</p>
<pre class="brush: groovy; title: ; notranslate">
//python
big = im_orig.resize((116, 56), Image.NEAREST)

//Groovy
dimg = resizeImage(dimg, 116, 56)
...
def resizeImage = {BufferedImage image, int w, int h -&amp;gt;
    BufferedImage dimg = new BufferedImage(w, h, image.type)
    dimg.createGraphics().with {
        setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR)
        drawImage(image, 0, 0, w, h, 0, 0, image.width, image.height, null)
        dispose()
    }
    return dimg
}
</pre>
<p>By this point the original images now look like this, and are <i>almost</i> ready for OCR.</p>
<table>
<tbody>
<tr>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/tmp0.gif" title="Resized and cleaned for OCR" class="shutterset_singlepic61" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/61__x_tmp0.gif" alt="9koO-readyForOCR" title="9koO-readyForOCR" />
</a>
</td>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/tmp1.gif" title="Resized and cleaned for OCR" class="shutterset_singlepic62" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/62__x_tmp1.gif" alt="jxt9-readyForOCR" title="jxt9-readyForOCR" />
</a>
</td>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/tmp2.gif" title="Resized and cleaned for OCR" class="shutterset_singlepic63" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/63__x_tmp2.gif" alt="e4ya-readyForOCR" title="e4ya-readyForOCR" />
</a>
</td>
</tr>
</tbody>
</table>
<p></p>
<h2>Converting to a tif File</h2>
<p>This one turns out to be a bit of a PITA in Java and particularly on a Mac, and represents the bulk of the Groovy code. Unfortunately it is also the only format that tesseract appears to accept &#8216;out of the box&#8217;.  After googling the fun that is JAI and working with the <a class="zem_slink" href="http://en.wikipedia.org/wiki/Tagged_Image_File_Format" title="Tagged Image File Format" rel="wikipedia">.tif</a>(f) format with it on a Mac,   I ended up taking the code kindly provided in <a href="http://www.ideyatech.com/2009/05/converting-to-tiff-on-mac-using-java-advanced-imaging/">this blog post</a> and Groovified it a bit to make a working transformation. Thanks very much to Allan Tan for that. One more time, there&#8217;s likely a better/easier way to do this, but honestly it&#8217;s more effort than I&#8217;m willing to put in on a weekend afternoon just to satisfy my curiosity.<br />
 <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<pre class="brush: groovy; title: ; notranslate">
//python
ext = &quot;.tif&quot;
big.save(&quot;input-NEAREST&quot; + ext)

//Groovy
void convertToTiff(String inputFile, String outputFile)
{
    OutputStream ios
    try
    {
        ios = new BufferedOutputStream(new FileOutputStream(new File(outputFile)))
        ImageEncoder enc = ImageCodec.createImageEncoder(&quot;tiff&quot;, ios, new TIFFEncodeParam(compression: TIFFEncodeParam.COMPRESSION_NONE, littleEndian: false))
        RenderedOp src = JAI.create(&quot;fileload&quot;, inputFile)

        //Apply the color filter and return the result.
        ColorConvertOp filterObj = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB), null)
        BufferedImage dst = new BufferedImage(src.width, src.height, BufferedImage.TYPE_3BYTE_BGR)
        filterObj.filter(src.getAsBufferedImage(), dst)

        // save the output file
        enc.encode(dst)
    }
    catch (Exception e)
    {
        println e
    }
    finally
    {
        ios.close()
    }
}
</pre>
<p></p>
<h2>OCR with Tesseract-OCR</h2>
<p>Finally we need to pass the processed image to tesseract so it can &#8216;read&#8217; it for us. Again, the python library makes this a breeze, but calling out to a command line program with Groovy is so simple that it ends up being about the same. Tesseract itself is available as a macport, as well in downloadable unix binaries and a windows executable so installing the software is a breeze.</p>
<pre class="brush: groovy; title: ; notranslate">
//python
from pytesser import *
image = Image.open('input-NEAREST.tif')
print image_to_string(image)

//Groovy
def tesseract = ['/opt/local/bin/tesseract', tmpTif, tmpTesseract].execute()
tesseract.waitFor()
return new File(&quot;${tmpTesseract}.txt&quot;).readLines()[0]
</pre>
<p></p>
<h2>Testing it out</h2>
<p>To test it out I implemented the code in a maven project, iterate over the images and write out intermediate results to a temp directory. And it only works on two out of three of the cases. For some reason tesseract insists on consistently seeing &#8216;e4ya&#8217; as &#8216;e4ga&#8217;.  I tried to see if I could get it working by tweaking the image manipulation parameters and the order of operations(resizing before removing the background noise for instance) but that just caused the other cases to fail as well. Since in the final image the &#8216;y&#8217; seems pretty clear, it&#8217;s more likely that tweaking tesseract configuration might yield better results.</p>
<pre class="brush: groovy; title: ; notranslate">
public void testPrintImage()
{
    def breaker = new CaptchaBreaker()
    /* tesseract interprets &quot;e4ya&quot; as &quot;e4ga&quot; unfortunately */
    ['9koO', 'jxt9'/*,'e4ya'*/].each {String imageName -&amp;gt;
        def fileName = &quot;src/test/resources/${imageName}.gif&quot;
        assertEquals(&quot;Testing $imageName&quot;,imageName, breaker.imageToString(fileName))
    }
}
</pre>
<p></p>
<h2>C&#8217;est Finis</h2>
<p>I had some fun playing with areas of Java that I don&#8217;t usually interact with, and gained some appreciation for the diversity and ease-of-use exposed by just a couple of python libraries. It&#8217;s comforting to note that I was able to implement all of the required functionality from those libraries in &lt; 90 lines of Groovy. With a little more effort I think the final product could be tweaked to avoid the intermediate file system reads/writes as well, but that&#8217;s for another day.<br />
Source code is <a href="http://github.com/kellyrob99/catcha-breaker">available on github</a> if you&#8217;d care to take a look, and thanks for stopping by!</p>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/7a2ae51d-774b-47b5-894b-592c38ebf542/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=7a2ae51d-774b-47b5-894b-592c38ebf542" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/' rel='bookmark' title='Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;'>Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/' rel='bookmark' title='Groovy and Hibernate Validator for Dynamic Constraints'>Groovy and Hibernate Validator for Dynamic Constraints</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>A One Day Griffon Application/Presentation</title>
		<link>http://www.kellyrob99.com/blog/2010/02/11/a-one-day-griffon-applicationpresentation/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-one-day-griffon-applicationpresentation</link>
		<comments>http://www.kellyrob99.com/blog/2010/02/11/a-one-day-griffon-applicationpresentation/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 05:15:57 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[beta]]></category>
		<category><![CDATA[Collections]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Griffon]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[plugin architecture]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[slideware]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[Swing]]></category>
		<category><![CDATA[TestNG]]></category>
		<category><![CDATA[theKaptain]]></category>
		<category><![CDATA[Transitions2D]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1072</guid>
		<description><![CDATA[I took the opportunity this past weekend to test drive the latest beta version of Griffon and along with it the as-of-yet unreleased slideware plugin. If you&#8217;re not already aware, Griffon is a Grails inspired framework for creating Java Swing applications. The project lead, Andres Almiray, has given several presentations using this plugin and it [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/08/27/vijug-griffongroovy-presentation/' rel='bookmark' title='VIJUG Griffon/Groovy Presentation'>VIJUG Griffon/Groovy Presentation</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/03/15/fun-day-playing-with-new-stuff/' rel='bookmark' title='Fun day playing with new Stuff'>Fun day playing with new Stuff</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I took the opportunity this past weekend to test drive the latest beta version of <a href="http://griffon.codehaus.org/">Griffon</a> and along with it the as-of-yet unreleased slideware plugin. If you&#8217;re not already aware, Griffon is a Grails inspired framework for creating <a class="zem_slink" href="http://en.wikipedia.org/wiki/Swing_%28Java%29" title="Swing (Java)" rel="wikipedia">Java Swing</a> applications. The project lead, Andres Almiray, has given several presentations using this plugin and it provides an excellent platform for showcasing both the power of Swing and the capabilities of Griffon to make it all look so easy.</p>
<p>The slideware plugin provides a framework for creating presentations with a little twist &#8211; you can execute code live from the presentation software.  If you&#8217;ve ever given a presentation about programming you probably are fully aware of the transition from presentation software to your preferred environment for demonstrating code samples. Well, now you can stay entirely within the same application, editing and running code live.</p>
<p>The plugin itself isn&#8217;t available from the Griffon repository but source code and a built 0.2 version can be <a href="http://github.com/aalmiray/Presentations">found on github</a>.  Considering both the youth of the plugin and the beta status of the framework, it worked impressively well AND had a rich feature set.  All of the expected &#8220;powerpoint&#8221; features are there: themes, layout control, styling, slide transitions and export are all pretty easy to incorporate and configure. The code editor view also works very well. A great variety of additional plugins are harnessed to put all the pieces together and as a result building one of these applications is a great way to tour the platform.</p>
<p></p>
<h2>Theming</h2>
<p>Applying a theme to the presentation is simply selecting a Java Look and Feel to apply in Initialize.groovy. The Substance jar is included with the plugin so I test drove a few of the nice setups in there and finally settled on the SubstanceMagmaLookAndFeel. There is definitely a wide variety of L&amp;F&#8217;s to choose from in that bundle alone and, although I haven&#8217;t done it myself, they seem pretty tweakable as well. Plus any old L&amp;F should plug in nicely, I would imagine. </p>
<pre class="brush: groovy; title: ; notranslate">
//Initialize.groovy
SwingBuilder.lookAndFeel('org.jvnet.substance.skin.SubstanceMagmaLookAndFeel',
       'mac', 'nimbus', 'gtk', ['metal', [boldFonts: false]])
</pre>
<p></p>
<h2>Layout</h2>
<p>Controlling the page composition is a standard Swing Layout or, in the case of the default slide you get with the included &#8220;create-slide&#8221; script, a MigLayout. Framing the standard variety of slides is very simple. Bulleted pages, title slides, code slides and custom layouts are very easy to accomplish. I don&#8217;t have a lot of experience using this particular layout but the presentations Andres has made available on github have a good diversity of examples of how they look in practice.</p>
<pre class="brush: groovy; title: ; notranslate">
//the default create-slide generated template
import net.miginfocom.swing.MigLayout

slide(id: &quot;slide0&quot;, layout: new MigLayout(&quot;fill&quot;,&quot;[center]&quot;,&quot;[center]&quot;)) {
    label(&quot;Insert your text here&quot;)
}
</pre>
<p></p>
<h2>Styling</h2>
<p>Styling is supplied by the css plugin, on which slideware has a dependency. The default style.css file sets out just some reasonable defaults for the fonts used in different parts of the app, and I didn&#8217;t see any real need to fiddle with it. Especially happy to see the nice monospace code font. On a totally related note I recently installed the <a href="http://www.levien.com/type/myfonts/inconsolata.html">Inconsolata</a> monospace font to try for development and I&#8217;ve been very happy seeing it in my editor, but it&#8217;s still nice to see this kind of polish applied to the presentation. The code editor view even includes syntax highlighting! More on that coming right up&#8230;</p>
<p></p>
<h2>Slide Transitions</h2>
<p>Moving between slides with style is the responsibility of the <a href="http://griffon.codehaus.org/Transitions+Plugin">transitions plugin</a>. You can see see all of the animations this plugin enables over here at <a href="http://javagraphics.blogspot.com/2007/04/slideshows-transitions-swf.html">this page describing Transitions and Transition2Ds</a>. Pretty slick stuff and defined as simply as a parameter to each &#8220;slide&#8221; node in a script.</p>
<pre class="brush: groovy; title: ; notranslate">
slide(id: &quot;slide3&quot;, layout: new MigLayout(&quot;fill&quot;,&quot;3%[center]3%&quot;,&quot;3%[center]3%&quot;),
        title: &quot;Junit3&quot;,
        transition: new FlurryTransition2D(Transition2D.OUT)) {
    scrollPane(constraints: &quot;grow&quot;) {
        widget(createEditor(text: script))
    }
}
</pre>
<p></p>
<h2>Code Editor</h2>
<p>Code slides embed an editable widget and allow for composing and executing Groovy scripts or classes of arbitrary complexity. You can execute the code with a keyboard shortcut and a window will open displaying the console output. The code itself is executed through a GroovyShell, enabling pretty much anything you might want to do. If you have an internet connection and the required repositories configured, Grapes simplifies packaging the dependencies for the application as your code samples can directly Grab the jars they need. Basically, the first time you execute a code slide you&#8217;ll have to put up with a small pause while Ivy downloads to your local repository, unless of course the required dependencies are already there.  In my case I changed strategies from including jars in the application lib directory to a Grapes approach and I think it&#8217;s a better way to go.</p>
<p>I was surprised to find that the editor even included undo functionality. It&#8217;s definitely not close to a full blown IDE, and there&#8217;s absolutely no reason that it should be. For the task of demoing simple code examples it&#8217;s more than up to the task, even to the point of maintaining your edits between slide transitions, allowing you to move back and forth through the slide deck without any state problems.<br />

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-11-at-7-47-04-pm.png" title="Code slide with JUnit4 and Hamcrest matcher example" class="shutterset_singlepic38" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/38__x_screen-shot-2010-02-11-at-7-47-04-pm.png" alt="Code slide with JUnit4 and Hamcrest matcher example" title="Code slide with JUnit4 and Hamcrest matcher example" />
</a>
</p>
<p></p>
<h2>Export</h2>
<p>The application includes a &#8220;Print&#8221; feature which iterates through the entire slide deck and renders it to a pdf. Distribution of one of these presentations is really very easy, including the ability to create installers for all major platforms simply by adding the packaging plugin.</p>
<p></p>
<h2>Test Application</h2>
<p>The test app I built while looking into this is pretty simple. It&#8217;s got a title slide, a bullet slide and 4 code slides. The code simply demonstrates how you can create test classes and make assertions for Junit 3(with GroovyTestCase), Junit 4 and TestNG. GroovyShell recognizes all 3 of these test files by interface or annotation and executes them appropriately. In each case the console output of the test framework is the result, including the new Spock inspired ascii art assert failure renderings. The Test result files are also written to disk, and that TestNG html output is what I&#8217;m used to looking at anyhow. Show me the Green!</p>
<p>The last code slide is just a slightly updated version of an example script on the Grapes page, using the current version of Google Collections and intentionally introducing a failure- mostly just to show off that new assert rendering I mentioned a moment ago. VERY helpful at highlighting the exact nature of a failure. It also encourages me to pay more attention to how I name variables, something I&#8217;m sure every developer that has ever worked with me will cheer at. Man, I suck at naming things.</p>
<p>I also developed a brute force test that loads each slide and executes scripts if finds embedded there. Failures are hard to detect since the direct output is simply a text block, but some fairly simple regex&#8217;s applied to the output make me at least moderately confident that the code won&#8217;t fail at show time.</p>
<p></p>
<h2>Overall Impression</h2>
<p>It took a couple of afternoons(six hours or so total) to download the source code from github, explore it, create a simple presentation and document the experience. I won&#8217;t begin to suggest that I&#8217;m fully aware of all the details happening behind the scenes, but the end user experience is pretty fluid: create a slide, tailor the layout, add content and then repeat. The included examples were more than enough documentation on how to hit the ground running. The plugin code itself is a great example of the MVC nature of Griffon, not a whole lot of code, but a great deal of power and expressability. There were a couple of glitches happening in the background, mostly just logging to the console with no visible effect to the application, but overall it functioned as well as (not) advertised. For publicly unreleased software it was an absolute pleasure to work with and I plan on continuing with the development of this particular presentation.</p>
<p>Everything you need to build and run this stuff yourself is publicly available. In my case, Griffon generally has a recent Macport available for both the released(griffon @0.2.1) and development versions(griffon-devel @0.3-BETA-2). Switching versions is relatively painless and, for applications this simple, testing out upgrades is basically just going through the presentation once in a functional test. Versions for other platforms can be downloaded from the <a href="http://griffon.codehaus.org/Download">Griffon download page</a>.</p>
<p></p>
<h2>Deliverables</h2>
<p>Source code for the sample application is <a href="http://github.com/kellyrob99/Groovy-Testing-Presentation">available on github here</a>. Please just leave a comment on this page if you have any problems running it.</p>
<p>Here&#8217;s the pdf produced by the application &#8216;Print&#8217; feature: <a class="downloadlink" href="http://www.kellyrob99.com/blog/wp-content/plugins/download-monitor/download.php?id=2" title="Version0.1 downloaded 252 times" >Groovy Testing Presentation (252)</a></p>
<p>And if you don&#8217;t feel like downloading anything, here&#8217;s how it all looks in pretty pictures.<br />

<div class="ngg-galleryoverview" id="ngg-gallery-9-1072">

	<!-- Slideshow link -->
	<div class="slideshowlink">
		<a class="slideshowlink" href="http://www.kellyrob99.com/blog/2010/02/11/a-one-day-griffon-applicationpresentation/?show=slide">
			[Show as slideshow]		</a>
	</div>

	<!-- Piclense link -->
	<div class="piclenselink">
		<a class="piclenselink" href="javascript:PicLensLite.start({feedUrl:'http://www.kellyrob99.com/blog/wp-content/plugins/nextgen-gallery/xml/media-rss.php?gid=9&amp;mode=gallery'});">
			[View with PicLens]		</a>
	</div>
	
	<!-- Thumbnails -->
		
	<div id="ngg-image-35" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-11-at-7-46-46-pm.png" title="Title slide" class="shutterset_set_9" >
								<img title="Title slide" alt="Title slide" src="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/thumbs/thumbs_screen-shot-2010-02-11-at-7-46-46-pm.png" width="99" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-36" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-11-at-7-46-50-pm.png" title="Bullet slide" class="shutterset_set_9" >
								<img title="Bullet slide" alt="Bullet slide" src="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/thumbs/thumbs_screen-shot-2010-02-11-at-7-46-50-pm.png" width="99" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-37" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-11-at-7-47-00-pm.png" title="Code slide with JUnit 3 example" class="shutterset_set_9" >
								<img title="Code slide with JUnit 3 example" alt="Code slide with JUnit 3 example" src="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/thumbs/thumbs_screen-shot-2010-02-11-at-7-47-00-pm.png" width="99" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-38" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-11-at-7-47-04-pm.png" title="Code slide with JUnit4 and Hamcrest matcher example" class="shutterset_set_9" >
								<img title="Code slide with JUnit4 and Hamcrest matcher example" alt="Code slide with JUnit4 and Hamcrest matcher example" src="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/thumbs/thumbs_screen-shot-2010-02-11-at-7-47-04-pm.png" width="99" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-39" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-11-at-7-47-08-pm.png" title="Code slide with TestNG example" class="shutterset_set_9" >
								<img title="Code slide with TestNG example" alt="Code slide with TestNG example" src="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/thumbs/thumbs_screen-shot-2010-02-11-at-7-47-08-pm.png" width="99" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-40" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-11-at-7-47-13-pm.png" title="Code slide with Google Collections example" class="shutterset_set_9" >
								<img title="Code slide with Google Collections example" alt="Code slide with Google Collections example" src="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/thumbs/thumbs_screen-shot-2010-02-11-at-7-47-13-pm.png" width="99" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-41" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-08-at-8-53-43-pm.png" title="Help screen showing keyboard shortcuts" class="shutterset_set_9" >
								<img title="Help screen showing keyboard shortcuts" alt="Help screen showing keyboard shortcuts" src="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/thumbs/thumbs_screen-shot-2010-02-08-at-8-53-43-pm.png" width="99" height="75" />
							</a>
		</div>
	</div>
	
		
 	 	
	<!-- Pagination -->
 	<div class='ngg-clear'></div>
 	
</div>

</p>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/a9a507d7-67b9-4178-bf0f-e90f2cc1d0a6/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=a9a507d7-67b9-4178-bf0f-e90f2cc1d0a6" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/08/27/vijug-griffongroovy-presentation/' rel='bookmark' title='VIJUG Griffon/Groovy Presentation'>VIJUG Griffon/Groovy Presentation</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/03/15/fun-day-playing-with-new-stuff/' rel='bookmark' title='Fun day playing with new Stuff'>Fun day playing with new Stuff</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/02/11/a-one-day-griffon-applicationpresentation/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Jira Grails Plugin</title>
		<link>http://www.kellyrob99.com/blog/2009/12/16/jira-grails-plugin/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=jira-grails-plugin</link>
		<comments>http://www.kellyrob99.com/blog/2009/12/16/jira-grails-plugin/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 08:31:16 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Atlassian]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Jira]]></category>
		<category><![CDATA[MOP]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[theKaptain]]></category>
		<category><![CDATA[XML-RPC]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=958</guid>
		<description><![CDATA[I set out to explore some of the Atlassian API&#8217;s this week, along with a test drive of Jira 4, and ended up developing a simple XML-RPC plugin for Grails. Utilizing little more than the Groovy XMLRPC library I was able to implement a client service for the Jira XmlRpcService in minutes. Nothing terribly complicated [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/01/07/bamboo-grails-and-git-for-continuous-integration/' rel='bookmark' title='Bamboo, Grails and Git for Continuous Integration'>Bamboo, Grails and Git for Continuous Integration</a></li>
<li><a href='http://www.kellyrob99.com/blog/2011/04/03/a-groovygradle-jslint-plugin/' rel='bookmark' title='A Groovy/Gradle JSLint Plugin'>A Groovy/Gradle JSLint Plugin</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/10/25/grails-ui-datatable-using-xml-for-a-model/' rel='bookmark' title='Grails-UI DataTable using XML for a model'>Grails-UI DataTable using XML for a model</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I set out to explore some of the Atlassian API&#8217;s this week, along with a test drive of <a href="http://www.atlassian.com/software/jira/">Jira 4</a>, and ended up developing a simple XML-RPC plugin for <a href="http://grails.org/">Grails</a>. Utilizing little more than the <a href="http://groovy.codehaus.org/XMLRPC">Groovy XMLRPC library</a> I was able to implement a client service for the Jira XmlRpcService in minutes.</p>
<p>Nothing terribly complicated going on for this plugin. Aside from the XMLRPC library and one more jar it depends upon there&#8217;s a service which implements calls for all of the methods on the XmlRpcService interface and a &#8216;helper&#8217; class that makes using it a little easier(removes the need to pass the host name into each method).  And any controller injected with the service gets a withJira(hostname, Closure) method which wraps the &#8216;helper&#8217; class. This might not be the optimal way to do things, but I was looking for some better experience with MOP&#8217;ing in Groovy along with this little project so it worked out perfectly for me.</p>
<p>The method added to Controller classes just creates a &#8216;helper&#8217; and sets it as the delegate for the closure.</p>
<pre class="brush: groovy; title: ; notranslate">
        cClass.metaClass.withJira = {String hostname, Closure closure -&gt;
            def helper = delegate.jiraXmlRpcService.createHelper(hostname)
            closure.setDelegate(helper)
            closure.setResolveStrategy(Closure.DELEGATE_FIRST)
            closure()
        }
</pre>
<p>Calling the withJira method looks like this, along with minimal exception handling:</p>
<pre class="brush: groovy; title: ; notranslate">
            try
            {
                def projects, priorities, serverInfo
                withJira(jiraInstance.baseUrl) {
                    def token = login(jiraInstance.userName, jiraInstance.password)
                    serverInfo = getServerInfo(token)
                    priorities = getPriorities(token)
                    projects = getProjectsNoSchemes(token)
                    logout(token)
                }
                [jiraInstance: jiraInstance, projects: projects, priorities: priorities, serverInfo: serverInfo]
            }
            catch (e)
            {
                flash.message = &quot;Failed to load data from ${jiraInstance.baseUrl}&quot;
                redirect(action: &quot;list&quot;)
            }
</pre>
<p>The &#8216;helper&#8217; class itself represents an experiment with the Groovy &#8216;methodMissing&#8217; behaviour. The idea is to store the &#8216;hostname&#8217; for a series of calls against the stateless service and add that as the first parameter for all wrapped methods. It was simple and quick, but right off the bat you lose the ability to use IDE syntax completion support on this object. I thought another possibility here would be to use the @Delegate annotation on the service and/or Closure currying to add the additional &#8216;hostname&#8217; parameter to methods.</p>
<pre class="brush: groovy; title: ; notranslate">
class JiraXmlRpcServiceHelper
{
    def hostname
    def JiraXmlRpcService service

    def methodMissing(String name, args)
    {
        assert hostname &amp;amp;&amp;amp; service
        def method = service.metaClass.methods.find {it.name == name}
        if(!method)
        {
            throw new NotImplementedException(&quot;The $name method is not implemented for ${this.getClass()}&quot;)
        }

        def newArgs = [hostname]
        args.each{newArgs &amp;lt;&amp;lt; it}
        return method.invoke(service, newArgs as Object[])
    }
}
</pre>
<p>This plugin works with Grails 1.2.0.RC1 and represents about 8 hours of work all told &#8211; and a lot of fun to make! Jira 4 is not too shappy either, especially with the GreenHopper plugin. But that&#8217;s a post for another day.</p>
<p>A special thank you to <a href="http://www.manning.com/gsmith/">Grails in Action</a> and <a href="http://naleid.com/blog/2009/06/25/groovy-closures-make-unit-testing-with-soft-asserts-simple/">this article by Ted Naleid</a> &#8211; both were extremely helpful putting this together. If you care to download it and take a spin here it is. Feedback is always welcome!</p>
<a class="downloadlink" href="http://www.kellyrob99.com/blog/wp-content/plugins/download-monitor/download.php?id=1" title="Version0.1 downloaded 261 times" >V0.1 of JiraGrailsPlugin (261)</a>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/3963a585-41c6-4cbb-a3b3-d2c006799a09/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_e.png?x-id=3963a585-41c6-4cbb-a3b3-d2c006799a09" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/01/07/bamboo-grails-and-git-for-continuous-integration/' rel='bookmark' title='Bamboo, Grails and Git for Continuous Integration'>Bamboo, Grails and Git for Continuous Integration</a></li>
<li><a href='http://www.kellyrob99.com/blog/2011/04/03/a-groovygradle-jslint-plugin/' rel='bookmark' title='A Groovy/Gradle JSLint Plugin'>A Groovy/Gradle JSLint Plugin</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/10/25/grails-ui-datatable-using-xml-for-a-model/' rel='bookmark' title='Grails-UI DataTable using XML for a model'>Grails-UI DataTable using XML for a model</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/12/16/jira-grails-plugin/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;</title>
		<link>http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier</link>
		<comments>http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 04:28:04 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Console]]></category>
		<category><![CDATA[dynamic execution]]></category>
		<category><![CDATA[embedded]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[groovyConsole]]></category>
		<category><![CDATA[GroovyScriptEngine]]></category>
		<category><![CDATA[GroovyShell]]></category>
		<category><![CDATA[Hello world program]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=858</guid>
		<description><![CDATA[Lately I&#8217;ve been thinking about all the different ways to bring Groovy into a pure Java or command line environment, and ended up diving into some code to explore the various options. Turns out there&#8217;s definitely a good variety of options for running Groovy dynamically inside and out of a Java application. I started out [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/10/04/groovy-clibuilder-with-multiple-arguments/' rel='bookmark' title='Groovy CliBuilder with multiple arguments'>Groovy CliBuilder with multiple arguments</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/' rel='bookmark' title='Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code'>Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Lately I&#8217;ve been thinking about all the different ways to bring Groovy into a pure Java or command line environment, and ended up diving into some code to explore the various options.  Turns out there&#8217;s definitely a good variety of options for running Groovy dynamically inside and out of a Java application. I started out on <a href="http://groovy.codehaus.org/Embedding+Groovy">this page from the Groovy site</a>.<br />
In particular for the environments I&#8217;ve been working in lately it&#8217;s been important to be able to run the same code both from within a Java application and from the command line. It&#8217;s also been a &#8216;nice to have&#8217; to be able to package a jar with a bunch of the same scripts compiled together. Using maven as a harness also has the benefit of allowing for testing compiled scripts directly through instantiation even though the intended usage is from within a Java app using one of these methods. Source code is <a href="http://github.com/kellyrob99/running-groovy">available here on github</a>.</p>
<p></p>
<h3>Groovy on the command line</h3>
<p>The quickest and simplest way to run a Groovy Script or Class, command line arguments are automatically marshalled into an &#8216;args&#8217; String array. Please note that due to a problem I&#8217;m having with my syntax highlighter plugin the process execution is shown here in single quotes; the actual code requires a GString(double quoted) in order to do the replacement for the inline variable. <code>&amp;quot;</code> THAT WordPress!</p>
<pre class="brush: groovy; title: ; notranslate">
//the script
myArgs = args
result = args.join(' ')
println result
println myArgs

//...and the test
    void testGroovyCall()
    {
        def proc = 'groovy $groovyScriptOne Hello World'.execute()
        proc.waitFor()
        def result = proc.text.split()
        assert result[0] == 'Hello'
        assert result[1] == 'World'
    }
</pre>
<p></p>
<h3>GroovyShell</h3>
<p>This is the basis of Groovy script execution. The <a href="http://groovy.codehaus.org/api/groovy/lang/GroovyShell.html">GroovyShell</a> allows for executing scripts, passing in a particular Binding context that allows for bi-directional communication between the script and the calling code. Parameters can be passed into the executing script in the Binding and results can be stored there to be returned to the calling context. GroovyShell also allows for running a class from the &#8216;main&#8217; method, passing in String arguments. It will also execute implementers of Runnable and test files for  JUnit or TestNG. Script text can also be declared inline and executed in the same way as files on disk. All in all, pretty bloody handy. Here&#8217;s a straightforward example of running a dirt simple Groovy script and inspecting the results. Note that this isn&#8217;t executable as shown, but I&#8217;ll provide the full source code on github for anyone who wants a closer look. Note that I&#8217;m also passing in an &#8216;out&#8217; variable in the Binding, which effectively redirect System.out to a specified Writer implementation &#8211; a nice touch for inspecting output.</p>
<pre class="brush: groovy; title: ; notranslate">
//the script
myArgs = args
result = args.join(' ')
println result
println myArgs

 //...and the test
    void testGroovyShell()
    {
        Binding binding = helper.createBinding()
        def shell = new GroovyShell(binding)
        shell.evaluate(new File(groovyScriptOne))
        helper.assertBinding(binding)
    }

//...and the Binding creation/assertion
     def static args = ['Hello', 'World'].asImmutable()
     /**
     * Create a Binding with a single parameter to be passed to scripts and an 'out' Writer to redirect console output.
     */
    private Binding createBinding()
    {
        Binding binding = new Binding()
        def sWriter = new StringWriter()
        def pWriter = new PrintWriter(sWriter)
        binding.setVariable ('args', new ArrayList(args))
        binding.setVariable ('out', pWriter)
        return binding
    }

    /**
     * Assert that the expected 'common' actions are done with the Binding by each of the use cases.
     * The original 'args' should be as expected.
     * A copy of 'args' should have been placed in the Binding during execution.
     * The 'result' should be the concatentation of 'args' separated by spaces.
     */
    private def assertBinding(Binding binding)
    {
        assert binding.variables.size() == 4
        assert binding.variables.args.value[0].toString() == args[0]
        assert binding.variables.args.value[1].toString() == args[1]
        assert binding.variables.result.value.toString() == args.join(' ')
        assert binding.variables.myArgs.value[0].toString() == args[0]
        assert binding.variables.myArgs.value[1].toString() == args[1]
    }
</pre>
<p></p>
<h3>GroovyScriptEngine</h3>
<p>The <a href="http://groovy.codehaus.org/api/groovy/util/GroovyScriptEngine.html">GroovyScriptEngine</a> enables dynamically running Groovy sources located in a fixed set of content roots,  complete with reloading modified scripts in between executions. Running a Groovy script this way is essentially the same as using GroovyShell.</p>
<pre class="brush: groovy; title: ; notranslate">
    void testGroovyScriptEngine()
    {
        Binding binding = helper.createBinding()
        def gse = new GroovyScriptEngine(new File('.').toURL())
        gse.run(groovyScriptOne, binding)
        helper.assertBinding(binding)
    }
</pre>
<p></p>
<h3>GroovyClassLoader</h3>
<p>An extension to URLClassLoader that enables parsing Groovy sources into Class representations. Once a Class object is created, instances of the class can be created easily and either cast to a known type or manipulated through convention by use of the standard Groovy &#8216;invokeMethod&#8217;.  This works equally well on Groovy and Java btw. Here&#8217;s an example of running a Java class using <a href="http://groovy.codehaus.org/api/groovy/lang/GroovyClassLoader.html">GroovyClassLoader</a>. In this case the Java file has a field called &#8216;binding&#8217; and implements a &#8216;run&#8217; method.</p>
<pre class="brush: groovy; title: ; notranslate">
    /**
     * Dynamically compile, instantiate, inspect and call methods on a POJO.
     */
    void testGroovyClassLoaderOnJava()
    {
        GroovyClassLoader loader = new GroovyClassLoader();
        Class javaClass = loader.parseClass(new File(javaFileOne));

        def groovyObject = javaClass.newInstance();
        def binding = helper.createBinding()
        groovyObject.binding = binding
        if(groovyObject.metaClass.respondsTo(groovyObject, 'run'))
        {
            groovyObject.invokeMethod('run', null);
            helper.assertBinding(binding)
        }
        if(groovyObject.metaClass.respondsTo(groovyObject, 'main'))
        {
            groovyObject.invokeMethod('main', new ArrayList(helper.args) as String[]);
        }
    }
</pre>
<p></p>
<h3>(Groovy)Console</h3>
<p>The <a href="http://groovy.codehaus.org/gapi/groovy/ui/Console.html">Console</a> can be embedded in Java or Groovy code to provide a dynamic interactive Swing environment. This is the same UI spawned from the command line invocation of &#8216;groovyConsole&#8217;. Internally it uses GroovyShell for actual execution, and so can do everything that GroovyShell can do &#8211; plus a couple of additions. For one, you can add jars and/or directories to the classpath used when executing your scripts.<br />
<a href="http://www.kellyrob99.com/blog/?attachment_id=885" rel="attachment wp-att-885"><img src="http://www.kellyrob99.com/blog/wp-content/uploads/2009/11/Picture-6.png" alt="Groovy Console" title="Groovy Console" class="size-full wp-image-885" width="651" height="457" /></a></p>
<p></p>
<h3>The Best of Both Worlds &#8211; at Least for my use case</h3>
<p>In actual practice these patterns can be used a lot more successfully by observing standard Java practices, like casting classes parsed using GroovyClassLoader to a known interface before interacting with them, or by using Classes to organize business logic inside of a Script that essentially functions as a &#8216;main&#8217; method.  This example defines two dependent internal classes, marshals parameters to them and then returns the results attached to the originally passed in Binding.</p>
<pre class="brush: groovy; title: ; notranslate">
/**
 * Classes inside of a Script.
 */
class TestableClass
{
    Binding binding

    def run()
    {
        binding.with
        {
            setVariable('myArgs', getVariable('args'))
            setVariable('result', getVariable('args')?.join(' '))
        }
        return binding
    }
}

class TestableClass2
{
    Binding binding

    public TestableClass2(Binding binding)
    {
        this.binding = binding;
    }

    def run()
    {
        return new TestableClass(binding: binding).run()
    }
}

if (args)
{
    def internalBinding = new Binding()
    internalBinding.setVariable('args', new ArrayList(args))
    internalBinding = new TestableClass2(internalBinding).run()
    args = internalBinding.args
    myArgs = internalBinding.myArgs
    result = internalBinding.result  //return value from script
}
else
{
    println 'no args!!'
}
</pre>
<h2 class="wp-table-reloaded-table-name-id-1 wp-table-reloaded-table-name">Summary of Groovy Execution Methods</h2>

<table id="wp-table-reloaded-id-1-no-1" class="wp-table-reloaded wp-table-reloaded-id-1">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Method</th><th class="column-2">Groovy Scripts</th><th class="column-3">Groovy Classes</th><th class="column-4">Java</th>
	</tr>
</thead>
<tbody>
	<tr class="row-2 even">
		<td class="column-1">groovy exec on the command line</td><td class="column-2">Yes, passes in String command line argments in a variable called 'args'</td><td class="column-3">Yes, calls the main method with String arguments</td><td class="column-4">No</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">GroovyShell</td><td class="column-2">Yes, parameters passed in a Binding object that the Script can mutate</td><td class="column-3">Yes, calls the main method with String arguments</td><td class="column-4">Yes, no apparent way to pass arguments</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">GroovyScriptEngine</td><td class="column-2">Yes, parameters passed in a Binding object that the Script can mutate</td><td class="column-3">Yes, no apparent way to pass arguments</td><td class="column-4">Yes, no apparent way to pass arguments</td>
	</tr>
	<tr class="row-5 odd">
		<td class="column-1">GroovyClassLoader</td><td class="column-2">Yes, instantiate a parsed Class and either cast to a known type or use Groovy reflection methods to call methods</td><td class="column-3">Yes, instantiate a parsed Class and either cast to a known type or use Groovy reflection methods to call methods</td><td class="column-4">Yes, instantiate a parsed Class and either cast to a known type or use Groovy reflection methods to call methods</td>
	</tr>
	<tr class="row-6 even">
		<td class="column-1">(Groovy)Console</td><td class="column-2">Same as GroovyShell</td><td class="column-3">Same as GroovyShell</td><td class="column-4">Same as GroovyShell</td>
	</tr>
</tbody>
</table>
<span class="wp-table-reloaded-table-description-id-1 wp-table-reloaded-table-description"></span>

<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/8cba1f46-7f81-473a-8fe0-ce5f0a45ec40/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=8cba1f46-7f81-473a-8fe0-ce5f0a45ec40" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/10/04/groovy-clibuilder-with-multiple-arguments/' rel='bookmark' title='Groovy CliBuilder with multiple arguments'>Groovy CliBuilder with multiple arguments</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/' rel='bookmark' title='Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code'>Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>VIJUG Griffon/Groovy Presentation</title>
		<link>http://www.kellyrob99.com/blog/2009/08/27/vijug-griffongroovy-presentation/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=vijug-griffongroovy-presentation</link>
		<comments>http://www.kellyrob99.com/blog/2009/08/27/vijug-griffongroovy-presentation/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 07:36:12 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Griffon]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Keynote]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Swing]]></category>
		<category><![CDATA[SwingWorker]]></category>
		<category><![CDATA[Vancouver Island]]></category>
		<category><![CDATA[VIJUG]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=658</guid>
		<description><![CDATA[I had a great time tonite geeking out with Griffon in front of an audience. My thanks to everyone that attended, and especially to Manfred Moser and VIJUG for the chance to show off some Groovy and Griffon Swing code! The venue was great &#8211; very nice that the Vancouver Island Tech Park is kind [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/02/11/a-one-day-griffon-applicationpresentation/' rel='bookmark' title='A One Day Griffon Application/Presentation'>A One Day Griffon Application/Presentation</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/08/griffon-swingx-fest-testing/' rel='bookmark' title='Griffon SwingX Fest testing'>Griffon SwingX Fest testing</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/07/16/presenting-a-groovygriffon-talk/' rel='bookmark' title='Presenting a Groovy/Griffon talk'>Presenting a Groovy/Griffon talk</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I had a great time tonite geeking out with <a class="zem_slink" title="Griffon (framework)" rel="homepage" href="http://griffon.codehaus.org">Griffon</a> in front of an audience. My thanks to everyone that attended, and especially to Manfred Moser and VIJUG for the chance to show off some Groovy and Griffon Swing code!</p>
<p>The venue was great &#8211; very nice that the <a href="http://www.vitp.ca/">Vancouver Island Tech Park</a> is kind enough to host meetings. Next time I&#8217;ll have to come early enough to figure out how to make the projector do better than 800X600 resolution, however. Hard to show much other than a slide deck presentation with that little space. Then again I may be a little spoiled when my usual is 1920X1200.</p>
<p>I love using <a class="zem_slink" title="Keynote (presentation software)" rel="homepage" href="http://www.apple.com/iwork/keynote/">Keynote</a> for presentations with the <a class="zem_slink" title="Apple" rel="homepage" href="http://www.apple.com">Apple</a> infrared remote. Between the presenter view with notes to guide what I wanted to say(and to remind me when to step out and demo some code) and the timer to keep me on track, it went really pretty smooth. That&#8217;s my story, and I&#8217;m sticking to it. The software, both Griffon and Keynote, worked flawlessly so if things weren&#8217;t perfect, there&#8217;s only me to blame.</p>
<p>SwingPad seemed to make quite an impression, which is not hard to understand considering how little effort it takes to start showing results on the screen. Put that together with the recent CSSBuilder integration and the rich samples for other builders and I think more than a couple of <a class="zem_slink" title="Java (software platform)" rel="homepage" href="http://java.sun.com">Java</a> developers will be installing it soon.</p>
<p>The question came up enough that I want to directly reference this blog post <a href="http://www.jroller.com/aalmiray/entry/griffon_gsql_mini_howto">from Andres Almiray regarding GSQL in Griffon</a>. Apparently people like to have databases handy at all times</p>
<p> <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>And a big thanks to Andres for sharing two free copies of the upcoming Griffon In Action that he is co-authoring for raffle prizes tonite. Through the magic of <a class="zem_slink" title="Twitter" rel="homepage" href="http://twitter.com">Twitter</a> he was very supportive about 20 seconds after the original announcement went out. Now if only they can kill all those nasty spam-bots, etc that are messing with my Twittiness!</p>
<p>I&#8217;ve uploaded the <a href="http://github.com/kellyrob99/GriffonDemo/tree/master">demonstration application at github</a>. It shows a simple Griffon app with three tabs. The first is a minor port of Andres&#8217; <a href="http://www.jroller.com/aalmiray/entry/griffon_making_animations_with_gfx">Trident/GfxBuilder example</a> to show animation. The second is a simple demo of the @Bindable <a class="zem_slink" title="Abstract syntax tree" rel="wikipedia" href="http://en.wikipedia.org/wiki/Abstract_syntax_tree">AST</a> transformation along with the SwingBuilder syntax for accesing SwingUtilities; it comes along with an accompanying <a href="http://code.google.com/p/fest/">Fest</a> test. The third requires an internet connection as it parses out the DZone rss feed and delivers it into a <a href="http://www.publicobject.com/glazedlists/">GlazedList</a>, demonstrating usage of <a class="zem_slink" title="SwingWorker" rel="wikipedia" href="http://en.wikipedia.org/wiki/SwingWorker">SwingWorker</a> courtesy of the <a href="http://groovy.codehaus.org/SwingXBuilder">SwingXBuilder</a>.  I showed those samples along with <a href="http://docs.codehaus.org/display/GRIFFON/Installer+Plugin">installer plugin</a> built versions of some of the included Griffon sample applications. WeatherWidget is a one fine looking translucent UI example!</p>
<p>Please ping me if you have any problems running this Griffon app, as I did trim out a bunch of the extraneous project files and test reports right before uploading. This was my first time &#8216;really&#8217; using <a class="zem_slink" title="Git (software)" rel="homepage" href="http://git-scm.com/">Git</a> for source control so it&#8217;s bound to be a bit messy &#8211; nevertheless the Git experience has been great so far. I also tried to get the slides up on SlideShare, but that appears to&#8230; not be happening(been uploading now for over 20 minutes this time- about to kill it, again). So <a href="http://www.kellyrob99.com/blog/wp-content/uploads/2009/08/GriffonPresentation.pdf">here&#8217;s the pdf</a>.<br />
<span style="font-size: large;"><a title="Source down for the demo hosted at github" href="http://github.com/kellyrob99/GriffonDemo/tree/master">Source code download here.</a></span></p>
<p><span style="font-size: large;"><a title="A pdf of the Keynote presentation." href="http://www.kellyrob99.com/blog/wp-content/uploads/2009/08/GriffonPresentation.pdf">Slidedeck download here.</a></span></p>
<div style="width:425px;text-align:left" id="__ss_1921982"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/buttita/griffon-presentation-1921982" title="Griffon Presentation">Griffon Presentation</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=griffonpresentation-090828194024-phpapp01&#038;stripped_title=griffon-presentation-1921982" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=griffonpresentation-090828194024-phpapp01&#038;stripped_title=griffon-presentation-1921982" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/buttita">The Kaptain</a>.</div>
</div>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" title="Reblog this post [with Zemanta]" href="http://reblog.zemanta.com/zemified/cc92f489-148d-4e3c-b156-a7dcf8688412/"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=cc92f489-148d-4e3c-b156-a7dcf8688412" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script src="http://static.zemanta.com/readside/loader.js" type="text/javascript"></script></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/02/11/a-one-day-griffon-applicationpresentation/' rel='bookmark' title='A One Day Griffon Application/Presentation'>A One Day Griffon Application/Presentation</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/08/griffon-swingx-fest-testing/' rel='bookmark' title='Griffon SwingX Fest testing'>Griffon SwingX Fest testing</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/07/16/presenting-a-groovygriffon-talk/' rel='bookmark' title='Presenting a Groovy/Griffon talk'>Presenting a Groovy/Griffon talk</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/08/27/vijug-griffongroovy-presentation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My Favorite IntelliJ Resources, Tips and Tricks</title>
		<link>http://www.kellyrob99.com/blog/2009/08/18/my-favorite-intellij-resources-tips-and-tricks/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=my-favorite-intellij-resources-tips-and-tricks</link>
		<comments>http://www.kellyrob99.com/blog/2009/08/18/my-favorite-intellij-resources-tips-and-tricks/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 06:17:33 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Debugger]]></category>
		<category><![CDATA[Development Tools]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Integrated development environment]]></category>
		<category><![CDATA[IntelliJ IDEA]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=620</guid>
		<description><![CDATA[Today at work I was reminded that I didn&#8217;t learn how to use my IDE overnight, and that I&#8217;ve been greedily hoarding where I found good resources for learning how to drive IntelliJ in the fast lane. So without further ado, here&#8217;s the top places I&#8217;ve found and things I know. Links on the IntelliJ [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/08/14/griffon-support-in-latest-intellij-eap/' rel='bookmark' title='Griffon support in latest Intellij EAP'>Griffon support in latest Intellij EAP</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/02/21/developing-faster-with-the-atlassian-intellij-connector/' rel='bookmark' title='Developing Faster with the Atlassian IntelliJ Connector'>Developing Faster with the Atlassian IntelliJ Connector</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/02/08/my-favorite-new-groovy-trick/' rel='bookmark' title='My favorite new Groovy trick'>My favorite new Groovy trick</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Today at work I was reminded that I didn&#8217;t learn how to use my <a class="zem_slink" href="http://en.wikipedia.org/wiki/Integrated_development_environment" title="Integrated development environment" rel="wikipedia">IDE</a> overnight, and that I&#8217;ve been greedily hoarding where I found good resources for learning how to drive <a class="zem_slink" href="http://www.jetbrains.com/idea/" title="IntelliJ IDEA" rel="homepage">IntelliJ</a> in the fast lane.  So without further ado, here&#8217;s the top places I&#8217;ve found and things I know.</p>
<h2> Links on the IntelliJ site:</h2>
<ol>
<li><strong>1. </strong><a href="http://www.jetbrains.com/idea/documentation/documentation.html">The main documentation page</a></li>
<li><strong>2.</strong> <a href="http://www.jetbrains.com/idea/training/demos.html">Demos and tutorials</a> including a couple of new Groovy support demonstrations</li>
<li><strong>3. </strong><a href="http://www.jetbrains.com/idea/features/25-can.html">25 things you can do with IntelliJ 8 you can&#8217;t do with 7</a></li>
<li><strong>4.</strong> <a href="http://www.jetbrains.com/idea/docs/IntelliJIDEA8_ReferenceCard_Mac.pdf">Mac Keymap reference</a></li>
<li><strong>5.</strong> <a href="http://www.jetbrains.com/idea/docs/IntelliJIDEA8_ReferenceCard.pdf">Windows/Linux keymap reference</a></li>
<li><strong>6.</strong> <a href="http://blogs.jetbrains.com/idea/">The Jetbrains IntelliJ blog.</a> A great way of getting tips from the guys that wrote it, and keeping up to date with improvements.</li>
</ol>
<h2>DZone: Intellij in 7 pages</h2>
<ol>
<li><strong>7.</strong> <a href="http://refcardz.dzone.com/refcardz/intellij-idea-update">The DZone refcard for Intellij</a></li>
</ol>
<h2>My personal faves</h2>
<ol>
<li><strong>8.</strong> Command Shift-A to bring up a search window for actions. This one I think of as <a class="zem_slink" href="http://www.blacktree.com/" title="Quicksilver (software)" rel="homepage">Quicksilver</a> for my IDE.</li>
<li><strong>9.</strong> Alt-Enter to trigger intentions. Problem with your code? Let the IDE suggest a refactor to correct it.</li>
<li><strong>10.</strong>  Ctrl-n for auto-generation of <a class="zem_slink" href="http://java.sun.com" title="Java (software platform)" rel="homepage">Java</a> code. Getter and setter boilerplate getting you down(and you can&#8217;t switch from Java to Groovy)? Want a nice compact toString() on a class with 20 member variables? Let the IDE do the heavy lifting.</li>
<li><strong>11.</strong>  The Javadoc Sync plugin. This goes well with #10 to javadoc all those getters and setters auto-magically.</li>
</ol>
<h2>Add logging using the debugger</h2>
<ol>
<li><strong>12.</strong> Printing to the console is a basic tool for debugging code. Everybody&#8217;s done it &#8211; because it&#8217;s easy and it works. But you often come across scenarios that disallow this quick and satisfying hackish behaviour. Namely when you are debugging into code in a library, this is not necessarily an easy option. Fortunately IntelliJ provides a nice easy way to add console logging through the debugger. You can access the breakpoint configuration dialog either by right clicking on an existing line breakpoint and selecting &#8216;Properties&#8217; or by pressing Command Shift-F8 from the Debug view. From there you configure your line or Exception breakpoint with a &#8216;Suspend policy&#8217; of &#8216;None&#8217; and check the boxes under &#8216;Actions&#8217; to enable logging. A full description of the features can be <a href="http://www.jetbrains.com/idea/webhelp/configuring-breakpoints.html?permalink">found here</a>.
</p>
<p> I find this especially handy when there&#8217;s a problem iterating over a Collection and only one or some of the items in that Collection lead to an error condition during processing. Using this strategy I can provide context as to which cases passed and which failed without having to stop at a bunch of breakpoints and inspect the variables on the stack; I can just concentrate on the failure point and look back at the console output to compare against previous invocations.<br />
Here&#8217;s a couple of screencaps to show configuration for logging the size of a list on a line breakpoint. Note that the Groovy requires a little bit of extra magic, since the debugger gets passed a <a href="http://groovy.codehaus.org/api/groovy/lang/Reference.html">Reference</a> object instead of the raw List.</li>
</ol>

<div class="ngg-galleryoverview" id="ngg-gallery-6-620">

	<!-- Slideshow link -->
	<div class="slideshowlink">
		<a class="slideshowlink" href="http://www.kellyrob99.com/blog/2009/08/18/my-favorite-intellij-resources-tips-and-tricks/?show=slide">
			[Show as slideshow]		</a>
	</div>

	<!-- Piclense link -->
	<div class="piclenselink">
		<a class="piclenselink" href="javascript:PicLensLite.start({feedUrl:'http://www.kellyrob99.com/blog/wp-content/plugins/nextgen-gallery/xml/media-rss.php?gid=6&amp;mode=gallery'});">
			[View with PicLens]		</a>
	</div>
	
	<!-- Thumbnails -->
		
	<div id="ngg-image-26" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/intellij-debugging/groovydebug.png" title="IntelliJ adding logging to a Groovy class through the debugger" class="shutterset_set_6" >
								<img title="groovydebug" alt="groovydebug" src="http://www.kellyrob99.com/blog/wp-content/gallery/intellij-debugging/thumbs/thumbs_groovydebug.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-27" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/intellij-debugging/javadebug.png" title="IntelliJ adding logging to a Java class through the debugger" class="shutterset_set_6" >
								<img title="javadebug" alt="javadebug" src="http://www.kellyrob99.com/blog/wp-content/gallery/intellij-debugging/thumbs/thumbs_javadebug.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 	 	
	<!-- Pagination -->
 	<div class='ngg-clear'></div>
 	
</div>


<h2>Bonus from the Community</h2>
<ol>
<li><strong>13.</strong> <a href="http://jetbrains.dzone.com/articles/grails-12-creates-intellij">Grails returning the favor for the great IntelliJ support.</a></li>
</ol>
<h1>How about you?</h1>
<ol>
<li><strong>14.</strong> Do you know any other good places to learn about IntelliJ and how to get the most out of it? Please don&#8217;t keep it to yourself! I managed to line up a baker&#8217;s dozen, now you&#8217;re on the hook for number 14 smart guy.</li>
</ol>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/60aa60c1-1727-4e9c-9c03-3f9f4094636b/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=60aa60c1-1727-4e9c-9c03-3f9f4094636b" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/08/14/griffon-support-in-latest-intellij-eap/' rel='bookmark' title='Griffon support in latest Intellij EAP'>Griffon support in latest Intellij EAP</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/02/21/developing-faster-with-the-atlassian-intellij-connector/' rel='bookmark' title='Developing Faster with the Atlassian IntelliJ Connector'>Developing Faster with the Atlassian IntelliJ Connector</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/02/08/my-favorite-new-groovy-trick/' rel='bookmark' title='My favorite new Groovy trick'>My favorite new Groovy trick</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/08/18/my-favorite-intellij-resources-tips-and-tricks/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Griffon support in latest Intellij EAP</title>
		<link>http://www.kellyrob99.com/blog/2009/08/14/griffon-support-in-latest-intellij-eap/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=griffon-support-in-latest-intellij-eap</link>
		<comments>http://www.kellyrob99.com/blog/2009/08/14/griffon-support-in-latest-intellij-eap/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 06:23:18 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[eap]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Griffon]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Integrated development environment]]></category>
		<category><![CDATA[IntelliJ IDEA]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[NetBeans]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SpringSource]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=608</guid>
		<description><![CDATA[The IDE world just started to look a little greener for Griffon programmers. Today&#8217;s latest early access version of JetBrains IntelliJ version Maia has initial support for Griffon! It appeared on the JetBrains blogroll a couple of weeks ago, and indeed may have showed up in an earlier release, but today was the first time [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/08/18/my-favorite-intellij-resources-tips-and-tricks/' rel='bookmark' title='My Favorite IntelliJ Resources, Tips and Tricks'>My Favorite IntelliJ Resources, Tips and Tricks</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/02/21/developing-faster-with-the-atlassian-intellij-connector/' rel='bookmark' title='Developing Faster with the Atlassian IntelliJ Connector'>Developing Faster with the Atlassian IntelliJ Connector</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/02/11/a-one-day-griffon-applicationpresentation/' rel='bookmark' title='A One Day Griffon Application/Presentation'>A One Day Griffon Application/Presentation</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>The <a class="zem_slink" href="http://en.wikipedia.org/wiki/Integrated_development_environment" title="Integrated development environment" rel="wikipedia">IDE</a> world just started to look a little greener for <a class="zem_slink" href="http://griffon.codehaus.org" title="Griffon (framework)" rel="homepage">Griffon</a> programmers. Today&#8217;s latest <a href="http://www.jetbrains.net/confluence/display/IDEADEV/Maia+EAP">early access version of JetBrains IntelliJ version Maia</a> has initial support for Griffon!</p>
<p>It appeared on the <a href="http://blogs.jetbrains.com/idea/2009/07/initial-griffon-support/">JetBrains blogroll a couple of weeks ago</a>, and indeed may have showed up in an earlier release, but today was the first time I saw it in action. I couldn&#8217;t find anything about this new feature mentioned explicitly in the release notes but sure enough, it&#8217;s there. Given the similar project structure between <a class="zem_slink" href="http://grails.org" title="Grails (framework)" rel="homepage">Grails</a> and Griffon, and the first class Grails support already available in IntelliJ, it&#8217;s really not too hard to see how this platform is in an ideal position to expand Griffon support.  Beyond that the general Groovy support seems to get better in every release. The EAP is free to try for any holder of an IntelliJ 8.x license and seems to be pretty stable despite the disclaimers &#8211; I highly recommend taking it for a spin, especially if you&#8217;re already using this IDE.  You get properly configured source directories and dependency paths, access to Griffon&#8217;s command line scripts, and even that awesome new Griffon icon shown to mark out the project. What more could you ask for?</p>
<p>JetBrains was beaten to the punch by a <a href="http://blogs.sun.com/geertjan/entry/griffon_alpha_plugin_for_netbeans">NetBeans plugin for Griffon</a> that was released in its initial version before this year&#8217;s Java One conference. I&#8217;m not a NetBeans user myself, but I am a frequent reader of Geertjan Wielenga&#8217;s blog &#8211; he&#8217;s published some great Groovy examples. Even the <a class="zem_slink" href="http://www.eclipse.org/" title="Eclipse (software)" rel="homepage">Eclipse</a> community has finally gotten around to putting out some real Groovy support, largely due to <a class="zem_slink" href="http://www.springsource.com" title="SpringSource" rel="homepage">SpringSource</a>&#8216;s commitment.</p>
<p> Hopefully their recent acquisition by <a class="zem_slink" href="http://www.vmware.com/" title="VMware" rel="homepage">VMWare</a> won&#8217;t distract them from developing it too much <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Regardless of which development environment you feel most comfortable with, there&#8217;s no questioning this is a great time to be a Groovy/Grails/Griffon developer so enjoy!</p>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/f3cf704d-a4a4-4a92-b52f-5c56053d78cd/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=f3cf704d-a4a4-4a92-b52f-5c56053d78cd" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/08/18/my-favorite-intellij-resources-tips-and-tricks/' rel='bookmark' title='My Favorite IntelliJ Resources, Tips and Tricks'>My Favorite IntelliJ Resources, Tips and Tricks</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/02/21/developing-faster-with-the-atlassian-intellij-connector/' rel='bookmark' title='Developing Faster with the Atlassian IntelliJ Connector'>Developing Faster with the Atlassian IntelliJ Connector</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/02/11/a-one-day-griffon-applicationpresentation/' rel='bookmark' title='A One Day Griffon Application/Presentation'>A One Day Griffon Application/Presentation</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/08/14/griffon-support-in-latest-intellij-eap/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using the TestNG DataProvider with Groovy</title>
		<link>http://www.kellyrob99.com/blog/2009/08/09/using-the-testng-dataprovider-with-groovy/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-the-testng-dataprovider-with-groovy</link>
		<comments>http://www.kellyrob99.com/blog/2009/08/09/using-the-testng-dataprovider-with-groovy/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 06:49:58 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[DataProvider]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[TestNG]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=590</guid>
		<description><![CDATA[TestNG is a great tool for testing in Java, and it works even better with a little Groovy thrown in. Just lately I&#8217;ve had a lot of success using the DataProvider pattern. A DataProvider method in TestNG can return either a two dimensional Object array or an Iterator over each of the test parameters. A [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/' rel='bookmark' title='Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code'>Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/14/groovy-and-bash-can-scripting-get-much-easier/' rel='bookmark' title='Groovy and Bash &#8211; can scripting get much easier?'>Groovy and Bash &#8211; can scripting get much easier?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://testng.org/">TestNG</a> is a great tool for testing in Java, and it works even better with a little Groovy thrown in. Just lately I&#8217;ve had a lot of success using the <a href="http://testng.org/javadocs/org/testng/annotations/DataProvider.html">DataProvider</a> pattern.</p>
<p>A DataProvider method in TestNG can return either a two dimensional Object array or an Iterator over each of the test parameters. A consumer of that method will be triggered once time for each set of parameters from the provider. Parameters are injected into the consumer method at execution time.<br />
This greatly eases testing various expectations that run through essentially the same path of execution. </p>
<p>Here&#8217;s the simple method under test, courtesy of <a href="http://groovy-almanac.org/the-inject-method-of-list/">this example on Groovy Almanac</a></p>
<pre class="brush: groovy; title: ; notranslate">
    /**
     * Use the Groovy added List.inject() method to sum a list of numbers.
     */
    def sum(list)
    {
        def sum = list.inject(0) { sum, item -&gt; sum + item }
    }
</pre>
<p>And here&#8217;s the corresponding DataProvider test harness. The test is injected with a List of numbers to sum and the associated total expected for each case.</p>
<pre class="brush: groovy; title: ; notranslate">
    @DataProvider (name = &quot;test1&quot;)
    public Object[][] createListInjectSumData() {
        def array = new Object[3][]
        array[0] = [[1, 2, 3], 6] as Object[]
        array[1] = [[2, 4, 6], 12] as Object[]
        array[2] = [[3, 6, 9], 18] as Object[]
        return array
    }

    @Test (dataProvider = &quot;test1&quot;)
    void testListInjectSummation(list, expectedSum) {
        Assert.assertEquals(new ListInjectExample().sum(list), expectedSum)
    }
</pre>
<p>I&#8217;ve put the maven project I used to demo this up on github <a href="git://github.com/kellyrob99/TestNG-DataProvider-Demo.git">here</a>. Mostly just because I&#8217;m having a great time using <a class="zem_slink" href="http://git-scm.com/" title="Git (software)" rel="homepage">Git</a> lately.</p>
<p> <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/' rel='bookmark' title='Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code'>Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/14/groovy-and-bash-can-scripting-get-much-easier/' rel='bookmark' title='Groovy and Bash &#8211; can scripting get much easier?'>Groovy and Bash &#8211; can scripting get much easier?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/08/09/using-the-testng-dataprovider-with-groovy/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>StreamingMarkupBuilder for Groovy-er xml</title>
		<link>http://www.kellyrob99.com/blog/2009/07/26/streamingmarkupbuilder-for-groovy-er-xml/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=streamingmarkupbuilder-for-groovy-er-xml</link>
		<comments>http://www.kellyrob99.com/blog/2009/07/26/streamingmarkupbuilder-for-groovy-er-xml/#comments</comments>
		<pubDate>Sun, 26 Jul 2009 23:15:32 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Facelets]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[StreamingMarkupBuilder]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[xml declaration]]></category>
		<category><![CDATA[xml namespace]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=569</guid>
		<description><![CDATA[Been having an awful lot of fun lately playing with the Groovy StreamingMarkupBuilder. I&#8217;m not a big fan of xml in general, but it&#8217;s definitely got its uses(configuration and web service data interchange to name just a couple). StreamingMarkBuilder makes it really very painless to create complex xml structures without a whole lot of hassle. [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/05/10/gracelets-and-seam-a-dsl-for-facelets-with-easy-integration/' rel='bookmark' title='Gracelets and Seam &#8211; a DSL for Facelets and Groovy with easy integration'>Gracelets and Seam &#8211; a DSL for Facelets and Groovy with easy integration</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/10/25/grails-ui-datatable-using-xml-for-a-model/' rel='bookmark' title='Grails-UI DataTable using XML for a model'>Grails-UI DataTable using XML for a model</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/' rel='bookmark' title='Groovy and Hibernate Validator for Dynamic Constraints'>Groovy and Hibernate Validator for Dynamic Constraints</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Been having an awful lot of fun lately playing with the Groovy <a href="http://groovy.codehaus.org/Creating+XML+using+Groovy%27s+StreamingMarkupBuilder">StreamingMarkupBuilder</a>. I&#8217;m not a big fan of xml in general, but it&#8217;s definitely got its uses(configuration and web service data interchange to name just a couple).</p>
<p>StreamingMarkBuilder makes it really very painless to create complex xml structures without a whole lot of hassle. There are some excellent examples out there already, but I couldn&#8217;t find one offhand that put all the pieces together.</p>
<p>This example demonstrates how to include the xml declaration, set the encoding, and incorporate namespaces. It also shows how to use iteration to create nodes in the Document. The (somewhat contrived) example code shows one possible way to template Facelet forms based on some simple parameters.</p>
<pre class="brush: groovy; title: ; notranslate">
import groovy.xml.StreamingMarkupBuilder

def inputs = ['FirstName', 'LastName', 'Street', 'City', 'Country']
def controller = 'formController'
def bean = 'formBean'

def builder = new StreamingMarkupBuilder()
builder.encoding = &quot;UTF-8&quot;
def doc = builder.bind {
    mkp.xmlDeclaration()
    mkp.declareNamespace(ui: &quot;http://java.sun.com/jsf/facelets&quot;,
            h: &quot;http://java.sun.com/jsf/html&quot;)
    'ui:composition'(template: '/layout/main.xhtml') {
        'h:form'(id: &quot;${controller}_form&quot;) {
            inputs.each {input -&gt;
                def inputId = input.toLowerCase().replaceAll(' ', '')
                'h:outputLabel'(input, id: inputId, styleClass: 'inputlabel')
                'h:inputText'(id: &quot;${inputId}_input&quot;, value: &quot;${bean}_$inputId&quot;, styleClass: 'inputText')
            }
        }
        'h:commandButton'(id: &quot;${controller}_submit&quot;, action: &quot;#{${controller}.submit}&quot;, styleClass: &quot;submitButton&quot;,
                value: 'Submit')
    }
}
</pre>
<p>And the output looks like this.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;ui:composition xmlns:ui=&quot;http://java.sun.com/jsf/facelets&quot; template=&quot;/layout/main.xhtml&quot; xmlns:h=&quot;http://java.sun.com/jsf/html&quot;&gt;
  &lt;h:form id=&quot;formController_form&quot;&gt;
    &lt;h:outputLabel id=&quot;firstname&quot; styleClass=&quot;inputlabel&quot;&gt;FirstName&lt;/h:outputLabel&gt;
    &lt;h:inputText id=&quot;firstname_input&quot; value=&quot;formBean_firstname&quot; styleClass=&quot;inputText&quot;/&gt;
    &lt;h:outputLabel id=&quot;lastname&quot; styleClass=&quot;inputlabel&quot;&gt;LastName&lt;/h:outputLabel&gt;
    &lt;h:inputText id=&quot;lastname_input&quot; value=&quot;formBean_lastname&quot; styleClass=&quot;inputText&quot;/&gt;
    &lt;h:outputLabel id=&quot;street&quot; styleClass=&quot;inputlabel&quot;&gt;Street&lt;/h:outputLabel&gt;
    &lt;h:inputText id=&quot;street_input&quot; value=&quot;formBean_street&quot; styleClass=&quot;inputText&quot;/&gt;
    &lt;h:outputLabel id=&quot;city&quot; styleClass=&quot;inputlabel&quot;&gt;City&lt;/h:outputLabel&gt;
    &lt;h:inputText id=&quot;city_input&quot; value=&quot;formBean_city&quot; styleClass=&quot;inputText&quot;/&gt;
    &lt;h:outputLabel id=&quot;country&quot; styleClass=&quot;inputlabel&quot;&gt;Country&lt;/h:outputLabel&gt;
    &lt;h:inputText id=&quot;country_input&quot; value=&quot;formBean_country&quot; styleClass=&quot;inputText&quot;/&gt;
  &lt;/h:form&gt;
  &lt;h:commandButton id=&quot;formController_submit&quot; action=&quot;#{formController.submit}&quot; styleClass=&quot;submitButton&quot; value=&quot;Submit&quot;/&gt;
&lt;/ui:composition&gt;
</pre>
<p>Normally StreamingMarkupBuilder output is devoid of whitespace but for readability I rendered it using the <a href="http://uncommentedbytes.blogspot.com/2008/09/format-groovy-streamingmarkupbuilder.html">very handy example provided here</a>. Big thank you to Jeff Sheets for sharing that code!</p>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/05/10/gracelets-and-seam-a-dsl-for-facelets-with-easy-integration/' rel='bookmark' title='Gracelets and Seam &#8211; a DSL for Facelets and Groovy with easy integration'>Gracelets and Seam &#8211; a DSL for Facelets and Groovy with easy integration</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/10/25/grails-ui-datatable-using-xml-for-a-model/' rel='bookmark' title='Grails-UI DataTable using XML for a model'>Grails-UI DataTable using XML for a model</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/' rel='bookmark' title='Groovy and Hibernate Validator for Dynamic Constraints'>Groovy and Hibernate Validator for Dynamic Constraints</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/07/26/streamingmarkupbuilder-for-groovy-er-xml/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>I am a Procedural Programmer</title>
		<link>http://www.kellyrob99.com/blog/2009/07/22/i-am-a-procedural-programmer/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=i-am-a-procedural-programmer</link>
		<comments>http://www.kellyrob99.com/blog/2009/07/22/i-am-a-procedural-programmer/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 08:34:41 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Apache Ant]]></category>
		<category><![CDATA[Apache Maven]]></category>
		<category><![CDATA[Closure]]></category>
		<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[Grape]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Guice]]></category>
		<category><![CDATA[Integrated development environment]]></category>
		<category><![CDATA[Ivy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Programming language]]></category>
		<category><![CDATA[Unit testing]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=538</guid>
		<description><![CDATA[I had occasion today to reflect on what I&#8217;ve learned in the last few years developing software and it occured to me, not much has really changed since I first struggled with Lisp and Scheme in university. I still don&#8217;t completely &#8220;get&#8221; functional programming! Wrapping my head around all those brackets in any derivative of [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/04/14/groovy-and-bash-can-scripting-get-much-easier/' rel='bookmark' title='Groovy and Bash &#8211; can scripting get much easier?'>Groovy and Bash &#8211; can scripting get much easier?</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/19/groovy-and-glazed-lists-with-grape/' rel='bookmark' title='Groovy and Glazed Lists with Grape'>Groovy and Glazed Lists with Grape</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/08/14/griffon-support-in-latest-intellij-eap/' rel='bookmark' title='Griffon support in latest Intellij EAP'>Griffon support in latest Intellij EAP</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I had occasion today to reflect on what I&#8217;ve learned in the last few years developing software and it occured to me, not much has really changed since I first struggled with <a href="http://en.wikipedia.org/wiki/Lisp_%28programming_language%29">Lisp</a> and Scheme in university. I still don&#8217;t completely &#8220;get&#8221; functional programming! Wrapping my head around all those brackets in any derivative of Lisp felt like torture, but maybe that was just academia trying to punish me for my eventual release into a world of programming languages concieved AFTER 1979. Not that Iam in any position to be critical of such seminal ideas &#8211; which after all are at the root of the Groovy Closure I know and love. I do &#8220;get&#8221; Closures, fortunately.</p>
<p> <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>In the last few years I&#8217;ve been exposed to a huge variety of different tools and frameworks, and have followed the transition of <a class="zem_slink" href="http://java.sun.com" title="Java (software platform)" rel="homepage">Java</a> from 1.4 to 1.6(and beyond!) Past time to take a look at just what has changed, and perhaps why it doesn&#8217;t matter so much.</p>
<p></p>
<h1>Build tools and dependency management &#8211; <a class="zem_slink" href="http://ant.apache.org/">Ant</a>, <a class="zem_slink" href="http://maven.apache.org" title="Apache Maven" rel="homepage">Maven</a>, <a class="zem_slink" href="http://ant.apache.org/ivy/">Ivy</a>, <a class="zem_slink" href="http://groovy.codehaus.org/Grape">Grape</a></h1>
<p>I started off in my programming career with lots of&nbsp; build.xml files and eventually made the (at times rough) transition from there to pom.xml. The best part of this: never having to hand-code a classpath again. Worth it right there. Maven adds enough dependency management magic to the build process to make it a nice alternative, and when you factor in the great IDE support available(I&#8217;m looking at you <a class="zem_slink" href="http://www.jetbrains.com/idea/" title="IntelliJ IDEA" rel="homepage">IntelliJ</a>) it&#8217;s almost a no brainer. When you need to switch from one project to another, as has been pretty common in my career at least, being able to open a project at first sight and have your IDE correctly load up and run out of the box is a big plus.</p>
<p>Of late I&#8217;ve been getting more experience with Grape and Ivy. These dependency management tools bring some really elegant simplicity to the table, especially Grape; good-bye to complicated command line &#8220;java -cp &#8230;&#8221; calls when all you want to do is run a little snippet locally and import a jar. Now of course, this journey takes us all the way back to ant, since it is such a close(and apparently integral) part of Ivy. Which is all right in my book &#8211; ant has really stepped up to the challenge in recent history, in no small part due to the community. The Groovy AntBuilder and Gant enable many of the iterative style features so hard to express in xml mostly trivial, greatly simplifying usage of the powerful ant capabilities and making them easier to bring to bear. Now of course, the ability to run both Groovy and ant from with Maven kind of make it a moot point &#8211; if you really want to make your life easy, it pays to get to know all of these technologies and fit them into your build in the most effective way possible.</p>
<p></p>
<h1>Dependency Injection &#8211; <a class="zem_slink" href="http://www.springsource.org/">Spring</a>, Maven, <a href="http://www.seamframework.org">Seam</a>, <a href="http://code.google.com/p/google-guice/">Guice</a></h1>
<p>First time I saw dependency injection in action was with Spring. The IOC principle has since then become central to how I look at software. I mean, if you want to unit test effectively, it&#8217;s pretty much compulsory. And it encourages you away from &#8216;bad&#8217; design patterns &#8211; static method only classes, shared instantiated utility classes, lack of interface abstraction, etc.</p>
<p>Maven and the <a class="zem_slink" href="http://plexus.codehaus.org/">Plexus</a> container makes writing Maven plugins a breeze. Baking functionality into a maven build is really pretty trivial and I have had a lot of success with GMaven plugins for applying static analysis to a build: verifying that all properties in a resource bundle are actually referenced in a web application for instance. It&#8217;s an added bonus that you can easily test your plugin for Maven&#8230; with Maven.</p>
<p>The Seam framework also provides a very nice IOC container and it has been a real pleasure to leverage that power in a real-world application. It certainly facillitates testing &#8211; my preferred stack is TestNG with Unitils to add easy annotation support. It&#8217;s the simple things like @TestedObject to clearly specify intent and @InjectInto to mock out dependencies that make testing outside of the container as painless as possible. Not only does it ease testing, it encourages good modularization of functionality.</p>
<p>Guice is comparatively the new kid on the block, and the dependency injection framework I have the least experience with, but again the idea is sound, and having another implementation that can take advantage of history is a good thing. Webbeans aims to take the paradigm to the next level, and it will be interesting to see how that implementation evolves. Anyway you want to cut it, the picture is pretty clear &#8211; don&#8217;t hardcode your dependencies &#8211; inject them!</p>
<p></p>
<h1>I am a&#8230; Functional Programmer?</h1>
<p>Somehow, since I started writing code &#8211; I started to get it! Closures now make sense to me, currying does not sound like a cooking technique and I realized that however you code certain fundamentals apply.</p>
<ul>
<li>write the code</li>
<li>test the hell out of the code</li>
<li>make sure the code gets USED, because this is the only way you&#8217;re going to find the bugs you didn&#8217;t think of in your tests(*see one line above). And no, you didn&#8217;t think of everything one line above.</li>
</ul>
<p>The real point here is don&#8217;t discriminate &#8211; use the right tools for the job and get the most out of them you can, whether it&#8217;s functional VS procedural, Ant VS Maven, etc ad infinitum. Each tool brings a slightly different skillset to the table and if you want to make your programming life easier, it does pay to know which to use when (and how much). Beyond that, taking the time to pry and prod at the tools you use challenges your assumptions and gives you a greater appreciation of just exactly what is &#8216;going on&#8217; when you hit the Big Green Go button on your build.<br />
Not to mention that all of the tools/frameworks I&#8217;ve described here have LOTS of daily users AND represent some of the most executed(and IMO best written) code out there in the Java+ community. As a developer, you can&#8217;t help but benefit from digging into such code.<br />
Whatever you do, don&#8217;t stay stuck in the past. It just doesn&#8217;t make a whole lot of sense when what you&#8217;re really after is to make your job as easy and painless as possible to do.</p>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/79a1ab53-0c8b-4d37-8a2e-dc7ae208bb0a/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=79a1ab53-0c8b-4d37-8a2e-dc7ae208bb0a" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/04/14/groovy-and-bash-can-scripting-get-much-easier/' rel='bookmark' title='Groovy and Bash &#8211; can scripting get much easier?'>Groovy and Bash &#8211; can scripting get much easier?</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/19/groovy-and-glazed-lists-with-grape/' rel='bookmark' title='Groovy and Glazed Lists with Grape'>Groovy and Glazed Lists with Grape</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/08/14/griffon-support-in-latest-intellij-eap/' rel='bookmark' title='Griffon support in latest Intellij EAP'>Griffon support in latest Intellij EAP</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/07/22/i-am-a-procedural-programmer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gracelets and Seam &#8211; a DSL for Facelets and Groovy with easy integration</title>
		<link>http://www.kellyrob99.com/blog/2009/05/10/gracelets-and-seam-a-dsl-for-facelets-with-easy-integration/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=gracelets-and-seam-a-dsl-for-facelets-with-easy-integration</link>
		<comments>http://www.kellyrob99.com/blog/2009/05/10/gracelets-and-seam-a-dsl-for-facelets-with-easy-integration/#comments</comments>
		<pubDate>Mon, 11 May 2009 04:16:38 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Facelets]]></category>
		<category><![CDATA[Gracelets]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JBoss Seam]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=380</guid>
		<description><![CDATA[Over the last year I&#8217;ve done a lot of work with JBoss Seam, and while it&#8217;s not Grails it&#8217;s also not that bad for a web framework. Facelets is the view technology of choice, and it&#8217;s certainly better than many alternatives, but at the heart it is still xml and all those brackets make me [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/07/26/streamingmarkupbuilder-for-groovy-er-xml/' rel='bookmark' title='StreamingMarkupBuilder for Groovy-er xml'>StreamingMarkupBuilder for Groovy-er xml</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/' rel='bookmark' title='Groovy and Hibernate Validator for Dynamic Constraints'>Groovy and Hibernate Validator for Dynamic Constraints</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/01/07/bamboo-grails-and-git-for-continuous-integration/' rel='bookmark' title='Bamboo, Grails and Git for Continuous Integration'>Bamboo, Grails and Git for Continuous Integration</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Over the last year I&#8217;ve done a lot of work with <a class="zem_slink" href="http://www.seamframework.org" title="JBoss Seam" rel="homepage">JBoss Seam</a>, and while it&#8217;s not <a class="zem_slink" href="http://grails.org" title="Grails (framework)" rel="homepage">Grails</a> it&#8217;s also not that bad for a web framework.  Facelets is the view technology of choice, and it&#8217;s certainly better than many alternatives, but at the heart it is still xml and all those brackets make me dizzy after awhile.  Along comes <a href="http://gracelets.sourceforge.net/index.html">Gracelets</a> to provide a nice builder <a class="zem_slink" href="http://en.wikipedia.org/wiki/Digital_subscriber_line" title="Digital subscriber line" rel="wikipedia">DSL</a> and Groovy integration as a replacement for my xml woes. Yay!  It also brings some great simplification to the creation of component libraries &#8211; including hot deployment.  But enough of the sales pitch, let&#8217;s see if it works.</p>
<p>In order to test drive Gracelets, I took an existing Seam web-app and configured the web.xml with the GraceletsViewHandler in place of the standard SeamListener.  I generally use <a class="zem_slink" href="http://maven.apache.org" title="Apache Maven" rel="homepage">Maven</a> for dependency management, and I couldn&#8217;t find a repository hosting Gracelets so I installed the downloaded jars into my local repository and adding them to the web-app. The JBoss Seam Extension is also required.</p>
<pre class="brush: bash; title: ; notranslate">
mvn install:install-file -Dfile=gracelets-api-2.0.0.jar -DgroupId=gracelets -DartifactId=gracelets-api -Dversion=2.0.0 -Dpackaging=jar -DgeneratePom=true
mvn install:install-file -Dfile=gracelets-impl-2.0.0.RC2.jar -DgroupId=gracelets -DartifactId=gracelets-impl -Dversion=2.0.0.RC2 -Dpackaging=jar -DgeneratePom=true
mvn install:install-file -Dfile=jboss_seam_2.0.0_all-1.0.11.jar -DgroupId=gracelets -DartifactId=jboss-seam-extension -Dversion=1.0.11 -Dpackaging=jar -DgeneratePom=true
</pre>
<pre class="brush: xml; title: ; notranslate">
&lt;dependency&gt;
        &lt;groupid&gt;gracelets&lt;/groupid&gt;
        &lt;artifactid&gt;jboss-seam-extension&lt;/artifactid&gt;
        &lt;version&gt;1.0.11&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
        &lt;groupid&gt;gracelets&lt;/groupid&gt;
        &lt;artifactid&gt;gracelets-api&lt;/artifactid&gt;
        &lt;version&gt;2.0.0&lt;/version&gt;
 &lt;/dependency&gt;
 &lt;dependency&gt;
        &lt;groupid&gt;gracelets&lt;/groupid&gt;
        &lt;artifactid&gt;gracelets-impl&lt;/artifactid&gt;
        &lt;version&gt;2.0.0.RC2&lt;/version&gt;
 &lt;/dependency&gt;
</pre>
<p>The application was deployed as usual and fired up without a problem. For a test page I just created an index.groovy file in the root directory. According to the docs, a .groovy extension trumps .xhtml so that effectively replaced the front page of the app. Here&#8217;s the standard first page of a new web-app(straight from the Gracelets examples), with the xhtml builder.</p>
<pre class="brush: groovy; title: ; notranslate">
xh.html {
     head { title(&quot;Hello World Example&quot;) }

     body {
         print { &quot;Hello World @ &quot; + new Date() }
     }
}
</pre>
<p>Not bad, let&#8217;s compare to the standard Facelets version, using a file based on the standard seam-gen created index.xhtml file. I&#8217;ve bound the instantiation of the Date object to a backing bean, since you can&#8217;t make an inline call to do it a standard Facelets view. I seem to recall seeing that Seam kept a component available to provide the present Date/Time, but I couldn&#8217;t find it offhand today.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;
        &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;f:view contentType=&quot;text/html&quot;
        xmlns=&quot;http://www.w3.org/1999/xhtml&quot;
        xmlns:ui=&quot;http://java.sun.com/jsf/facelets&quot;
        xmlns:h=&quot;http://java.sun.com/jsf/html&quot;
        xmlns:f=&quot;http://java.sun.com/jsf/core&quot;
        xmlns:a=&quot;http://richfaces.org/a4j&quot;
        xmlns:s=&quot;http://jboss.com/products/seam/taglib&quot;&gt;
    &lt;html&gt;
    &lt;head&gt;
        &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;/&gt;
        &lt;title&gt;Hello World Example&lt;/title&gt;
        &lt;ui:insert name=&quot;head&quot;/&gt;
    &lt;/head&gt;
    &lt;body&gt;
    Hello World @ #{backingBean.date}
    &lt;/body&gt;
    &lt;/html&gt;
&lt;/f:view&gt;
</pre>
<p>Notice I&#8217;ve also left the Seam and <a class="zem_slink" href="http://www.jboss.org/jbossrichfaces/" title="Richfaces" rel="homepage">RichFaces</a> tab library namespaces in the xml declaration. Although the Gracelets docs didn&#8217;t seem to easily confirm this, inclusion of the JBoss Seam extension also makes those libraries and their associated builders available by default for Gracelets views. Here&#8217;s a final example to leave you with that incorporates a couple of elements from those libraries and a quick and dirty use of .each for rendering, and even a couple of screenshots to show off the progression.</p>
<pre class="brush: groovy; title: ; notranslate">
def loremIpsum = '''
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin tempor, mauris sed volutpat consequat, risus tellus ultrices
tortor, at sollicitudin felis erat vitae augue. Pellentesque habitant morbi tristique senectus et netus et malesuada fames
ac turpis egestas. Vestibulum tincidunt egestas viverra. Integer ullamcorper, ipsum id malesuada sollicitudin, nisl velit
ultricies purus, eu aliquet diam mi sit amet eros. Quisque arcu orci, consequat dictum vehicula a, pellentesque eu nisl.
'''
xh.html {
     head { title(&quot;Hello World Example&quot;) }
     body {
         s.div(id:'aSeamDiv', rendered:'true') {
            r.panel(header:'A RichFaces Panel') {
                println { &quot;Hello World @ &quot; + new Date() }
                a('MyBlogLink', href: 'http://www.kellyrob99.com/blog')
            }
         }
         r.separator()
         r.spacer()
         r.simpleTogglePanel(header:'A RichFaces TogglePanel'){
            println loremIpsum
         }

         def tableModel = loremIpsum.tokenize()[0..10]
         def tableModel2 = loremIpsum.tokenize()[11..20]
         table {
            tr {
                td {
                    tableModel.each { println it }
                }
                td {
                    tableModel2.each { println it }
                }
            }
         }
     }
}
</pre>
<p>Not bad at all. I won&#8217;t bore you with the equivalent xml version &#8211; suffice it to say it takes up a lot more space.  I haven&#8217;t even touched on the easy component/library features Gracelets provides yet, but I am already quite impressed simply by the replacement of xml with an equivalent but sparser syntax. And I don&#8217;t miss the need for closing tags much either. The documentation for the project is quite complete, rich with examples, at least for the standard jsf components(hint hint &#8211; more examples using Seam and RichFaces would be appreciated!)  Give it a try and decide for yourself, but if it keeps going this way, it might become a reasonable alternative for Grails.</p>
<p> <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<div class="ngg-galleryoverview" id="ngg-gallery-3-380">

	<!-- Slideshow link -->
	<div class="slideshowlink">
		<a class="slideshowlink" href="http://www.kellyrob99.com/blog/2009/05/10/gracelets-and-seam-a-dsl-for-facelets-with-easy-integration/?show=slide">
			[Show as slideshow]		</a>
	</div>

	<!-- Piclense link -->
	<div class="piclenselink">
		<a class="piclenselink" href="javascript:PicLensLite.start({feedUrl:'http://www.kellyrob99.com/blog/wp-content/plugins/nextgen-gallery/xml/media-rss.php?gid=3&amp;mode=gallery'});">
			[View with PicLens]		</a>
	</div>
	
	<!-- Thumbnails -->
		
	<div id="ngg-image-13" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/v1.png" title=" " class="shutterset_set_3" >
								<img title="v1.png" alt="v1.png" src="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/thumbs/thumbs_v1.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-14" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/v2.png" title=" " class="shutterset_set_3" >
								<img title="v2.png" alt="v2.png" src="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/thumbs/thumbs_v2.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-15" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/v3.png" title=" " class="shutterset_set_3" >
								<img title="v3.png" alt="v3.png" src="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/thumbs/thumbs_v3.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-16" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/v4.png" title=" " class="shutterset_set_3" >
								<img title="v4.png" alt="v4.png" src="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/thumbs/thumbs_v4.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-17" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/v4_panelopen.png" title=" " class="shutterset_set_3" >
								<img title="v4_panelopen.png" alt="v4_panelopen.png" src="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/thumbs/thumbs_v4_panelopen.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-18" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/v5.png" title=" " class="shutterset_set_3" >
								<img title="v5.png" alt="v5.png" src="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/thumbs/thumbs_v5.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-19" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/v6.png" title=" " class="shutterset_set_3" >
								<img title="v6.png" alt="v6.png" src="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/thumbs/thumbs_v6.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-20" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/v6_panelopen.png" title=" " class="shutterset_set_3" >
								<img title="v6_panelopen.png" alt="v6_panelopen.png" src="http://www.kellyrob99.com/blog/wp-content/gallery/gracelets/thumbs/thumbs_v6_panelopen.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 	 	
	<!-- Pagination -->
 	<div class='ngg-clear'></div>
 	
</div>


<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/4fdd0aeb-98bb-4937-b9ad-e5a5d2f4eb93/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=4fdd0aeb-98bb-4937-b9ad-e5a5d2f4eb93" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/07/26/streamingmarkupbuilder-for-groovy-er-xml/' rel='bookmark' title='StreamingMarkupBuilder for Groovy-er xml'>StreamingMarkupBuilder for Groovy-er xml</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/' rel='bookmark' title='Groovy and Hibernate Validator for Dynamic Constraints'>Groovy and Hibernate Validator for Dynamic Constraints</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/01/07/bamboo-grails-and-git-for-continuous-integration/' rel='bookmark' title='Bamboo, Grails and Git for Continuous Integration'>Bamboo, Grails and Git for Continuous Integration</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/05/10/gracelets-and-seam-a-dsl-for-facelets-with-easy-integration/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

