<?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; Java</title>
	<atom:link href="http://www.kellyrob99.com/blog/tag/java/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>Why do I Like Gradle?</title>
		<link>http://www.kellyrob99.com/blog/2010/11/13/why-do-i-like-gradle/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=why-do-i-like-gradle</link>
		<comments>http://www.kellyrob99.com/blog/2010/11/13/why-do-i-like-gradle/#comments</comments>
		<pubDate>Sat, 13 Nov 2010 23:53:47 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ant]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[Gradle]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1526</guid>
		<description><![CDATA[Gradle, if you don&#8217;t already know it, is rapidly gaining traction as a strong leader in the next generation of build systems. It builds heavily upon excellent aspects of the Maven and Ant frameworks, yet is pitched as not suffering from the same &#8220;Frameworkitis&#8220;. And I&#8217;ve gotta say &#8211; the results are pretty spectacular. Among [...]
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/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/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[<p><a href="http://gradle.org/">Gradle</a>, if you don&#8217;t already know it, is rapidly gaining traction as a strong leader in the next generation of build systems. It builds heavily upon excellent aspects of the <a href="http://maven.apache.org/">Maven</a> and <a href="http://ant.apache.org/">Ant</a> frameworks, yet is pitched as not suffering from the same &#8220;<a href="http://www.codinghorror.com/blog/2005/11/conversations-with-erich-gamma.html">Frameworkitis</a>&#8220;. And I&#8217;ve gotta say &#8211; the results are pretty spectacular. Among the major selling features, at least as I see it, are:</p>
<ul>
<li>Groovy syntax and a very terse and descriptive dsl that makes build scripts easily comprehensible</li>
<li>flexibility of layout, configuration, organizing build logic &#8211; pretty much everything</li>
<li>incremental builds, based on an easily implementable pattern</li>
<li>convention over configuration paradigm, thank you very much Maven</li>
<li>clear separation of build configuration from execution</li>
<li>extensibility at every level</li>
</ul>
<h2>The most basic Java build</h2>
<pre class="brush: groovy; title: ; notranslate">
apply plugin: 'java'
</pre>
<p>That&#8217;s it. One line of Groovy in a file called &#8216;build.gradle&#8217; and you can build a Java project with a Maven-standardized project layout.</p>
<pre>
├── build.gradle
└── src
    ├── main
    │   ├── java
    │   └── resources
    └── test
        ├── java
        └── resources
</pre>
<p>Included with the Java plugin are tasks to compile, package, test and javadoc your code. You also get <a href="http://gradle.org/latest/docs/userguide/artifact_dependencies_tutorial.html#sec:artifact_configurations">configuration</a> objects to describe the artifacts that your build depends on and those  that it produces. Of course, with this most basic setup these configurations don&#8217;t yet have anything in them, but in a complex build they&#8217;re very handy for isolating the responsibilities of each task. Because you can both configure the existing configurations and add custom ones yourself, it&#8217;s very easy to accommodate a project that follows a different structure, whether that is just differently named source directories or multiple directories that need specific processing. This is VERY handy for legacy builds.</p>
<h2>Incremental builds</h2>
<p>Gradle provides a very easy way to create tasks that are able to execute only if their declared input and/or output artifacts have changed. This makes it trivial to incorporate your custom build behaviour into an incremental build. As an example I&#8217;d like to expand upon something I read by <a href="http://twitter.com/etiennestuder">Etienne Studer</a> in this month&#8217;s <a href="http://jaxenter.com/jaxmag">JAXmag</a>. It&#8217;s a great example of developing an incremental task. First here&#8217;s the task implementation almost verbatim from the article. I&#8217;ve updated it slightly to make the output more readable using FileUtils, and you can examine the file it spits out from the build/reports/size directory that will be automatically created when it executes.</p>
<pre class="brush: groovy; title: ; notranslate">
class Size extends DefaultTask
{
    @InputFiles FileTree inputDir
    @OutputFile File outputFile

    @TaskAction
    void generate()
    {
        def totalSize = inputDir.files.inject(0) { def size, File file -&gt; size + file.size()
        }
        outputFile.text = FileUtils.byteCountToDisplaySize(totalSize)
    }
}
</pre>
<p>If you simply include this class definition in a build file, it will be automatically compiled and available for use elsewhere in the script. It could just as easily be defined in a separate file(local or remote), in a jar on the classpath or in the buildSrc directory of your Gradle project. This flexibility enables developing and evolving tasks in a very agile fashion, encouraging you to publish the results for reuse instead of re-implementing the logic in other projects.<br />
In order to execute this task as part of a build, we first need to configure it. In this case, I&#8217;m configuring it to work on all declared configurations and all source, both code and associated resources. In order to do so, I&#8217;m using a couple of Gradle internal classes, <a href="http://www.gradle.org/latest/docs/javadoc/org/gradle/api/file/FileTree.html">FileTree</a> and <a href="http://www.gradle.org/latest/docs/javadoc/org/gradle/api/tasks/SourceSet.html">SourceSet</a>, which actually sound pretty self-explanatory to me. The key part is the assignment of the &#8216;inputDir&#8217; and &#8216;outputFile&#8217; properties on the task.</p>
<pre class="brush: groovy; title: ; notranslate">
task size(type:Size){
    def filetree = sourceSets.inject(new UnionFileTree()) { FileTree total, SourceSet sourceSet -&gt;
        total += sourceSet.allSource
        total
    }
    inputDir = filetree
    outputFile = file(&quot;$reportsDir/size/size.txt&quot;)
}
</pre>
<p>Just to prove that it&#8217;s working incrementally, here&#8217;s the output from successive invocations. Note that &#8216;UP-TO-DATE&#8217; in the output that indicates the task was skipped the second time around, because none of the inputs changed and the output file hasn&#8217;t been deleted.</p>
<pre class="brush: groovy; title: ; notranslate">
gradle-intro$ gradle size
:size

BUILD SUCCESSFUL

Total time: 2.963 secs

gradle-intro$ gradle size
:size UP-TO-DATE

BUILD SUCCESSFUL

Total time: 2.912 secs
</pre>
<p>This task does actually have a concrete dependency on the Java plugin, since without that convention applied neither the &#8216;sourceSets&#8217; or &#8216;reportsDir&#8217; objects would be present. Here&#8217;s the complete version of the build file that&#8217;s been built so far, 28 lines including imports and spacing.</p>
<pre class="brush: groovy; title: ; notranslate">
import org.apache.commons.io.FileUtils
import org.gradle.api.internal.file.UnionFileTree
import org.gradle.api.tasks.SourceSet

apply plugin: 'java'           

task size(type:Size){
    def filetree = sourceSets.inject(new UnionFileTree()) { FileTree total, SourceSet sourceSet -&gt;
        total += sourceSet.allSource
        total
    }
    inputDir = filetree
    outputFile = file(&quot;$reportsDir/size/size.txt&quot;)
}

class Size extends DefaultTask
{
    @InputFiles FileTree inputDir
    @OutputFile File outputFile

    @TaskAction
    void generate()
    {
        def totalSize = inputDir.files.inject(0) { def size, File file -&gt; size + file.size()
        }
        outputFile.text = FileUtils.byteCountToDisplaySize(totalSize)
    }
}
</pre>
<h2>Sharing your new Task</h2>
<p>The simplest way to share build logic is to &#8216;apply&#8217; it. This simple shorthand covers everything from plugins to local files to remotely hosted resources. Here&#8217;s how easy it is to incorporate this particular task implementation and configuration into a build using a relative file path.</p>
<pre class="brush: groovy; title: ; notranslate">
apply from : '../gradle-intro/build.gradle'
</pre>
<p>And because only a simple http connection is required to share it to a broader base, here&#8217;s how you can reference a copy on this site. Sorry about the .txt extension, but I didn&#8217;t feel like editing php to allow a new filetype today <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">
apply from : 'http://www.kellyrob99.com/blog/wp-content/uploads/downloads/2010/11/gradleSizeTask.txt'
</pre>
<h2>Some other reading</h2>
<p>If you&#8217;re still not sold on Gradle, here&#8217;s some articles I&#8217;ve seen recently that at the very least will give you a better perspective.<br />
<a href="http://community.jboss.org/wiki/Gradlewhy">Hibernate &#8211; Gradle why?</a><br />
<a href="http://jaxenter.com/maven-vs-gradle-vs-ant.1-30682.html">Maven VS Gradle VS Ant</a><br />
Maven to Gradle: <a href="http://www.beeworks.be/maven-to-gradle-part-1/">Part 1</a>, <a href="http://www.beeworks.be/maven-to-gradle-part-2/">Part 2</a>,  <a href="http://www.beeworks.be/maven-to-gradle-part-3/">Part 3</a><br />
<a href="http://kaczanowscy.pl/tomek/2010-11/build-script-length-maven3-polyglot-maven-gradle-ant">A comparison of build script length</a><br />
<a href="http://kaczanowscy.pl/tomek/2009-11/ant-gradle-and-maven-comparison-install-script">Ant/Gradle/Maven comparison</a><br />
<a href="http://java.dzone.com/hibernate-users-learn-gradle">DZone article</a><br />
<a href="http://openmrs-mailing-list-archives.1560443.n2.nabble.com/Maven-vs-Gradle-td4511793.html">OpenMRS Mailing list on Maven VS Gradle</a></p>
<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/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/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/2010/11/13/why-do-i-like-gradle/feed/</wfw:commentRss>
		<slash:comments>10</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>Bamboo, Grails and Git for Continuous Integration</title>
		<link>http://www.kellyrob99.com/blog/2010/01/07/bamboo-grails-and-git-for-continuous-integration/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=bamboo-grails-and-git-for-continuous-integration</link>
		<comments>http://www.kellyrob99.com/blog/2010/01/07/bamboo-grails-and-git-for-continuous-integration/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 05:13:53 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Atlassian]]></category>
		<category><![CDATA[Bamboo]]></category>
		<category><![CDATA[Continuous integration]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Jira]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1015</guid>
		<description><![CDATA[Following up on my recent installation of the Atlassian product suite at home, I had a really positive experience setting up Bamboo to work with several of my recent Grails projects. Bamboo has proven to be a powerful and essential tool at my day job and I&#8217;ve really been looking forward to putting it to [...]
Related posts:<ol>
<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/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/03/21/gource-visualizations-of-the-groovygrailsgriffon-projects/' rel='bookmark' title='Gource Visualizations of the Groovy/Grails/Griffon Projects'>Gource Visualizations of the Groovy/Grails/Griffon Projects</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Following up on my recent installation of the <a class="zem_slink" href="http://www.atlassian.com/" title="Atlassian" rel="homepage">Atlassian</a> product suite at home, I had a really positive experience setting up Bamboo to work with several of my recent Grails projects.  Bamboo has proven to be a powerful and essential tool at my day job and I&#8217;ve really been looking forward to putting it to work for my personal projects.   I&#8217;ve also been using <a class="zem_slink" href="http://git-scm.com/" title="Git (software)" rel="homepage">Git</a> for a repository lately, and while I have nothing but praise for my good friend svn, I have to say the ability to set up a new repository in 2 seconds flat is pretty damn convenient.</p>
<p>Since neither Grails nor Git are by default supported by Bamboo, I grabbed a couple of plugins to enable my home <a class="zem_slink" href="http://en.wikipedia.org/wiki/Continuous_integration" title="Continuous integration" rel="wikipedia">continuous integration</a> system. Bamboo has a very sensible plugin model that allows for adding new capabilites with only a jar file in the right place and a server restart, and a <a href="https://plugins.atlassian.com/plugin/home">fairly rich library of plugins</a>. It&#8217;s also encouraging to see a company that is committed to eating their own dog food &#8211; recently they&#8217;ve moved their plugin resources to <a class="zem_slink" href="http://www.atlassian.com/software/jira" title="JIRA" rel="homepage">Jira</a> studio as you can see on the <a href="https://labs.atlassian.com/wiki/display/GRAILS/Home">Grails plugin home page</a>. This gives you as the consumer of the software access to the wiki&#8217;d documentation, any open issues, and even visibility into when source code changes are committed. I&#8217;m assuming that last is subject to whether or not the plugin source code is open source or not, but still &#8211; pretty nifty.</p>
<p>The Grails plugin instructions speak for themselves in the 3 screen-shots on the one and only wiki page. Anything else you need to know is summarized in a one liner on the &#8220;Builder&#8221; tab when you select the Grails builder: &#8220;Use a new line to seperate Grails commands.&#8221; Gotta love clear, simple instructions. Drop the plugin jar into $BAMBOO_INSTALL_DIR/webapp/WEB-INF/lib, restart Bamboo and <a href="http://confluence.atlassian.com/display/BAMBOO/Configuring+a+new+Builder">configure a new builder for Grails</a>. Took a couple of minutes and knowing where my Grails install was located.</p>

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/bamboo-grails-and-git/addingbamboograilsbuilder.png" title="Adding the builder definition to Bamboo" class="shutterset_singlepic30" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/30__750x_addingbamboograilsbuilder.png" alt="Adding the builder definition to Bamboo" title="Adding the builder definition to Bamboo" />
</a>

<p>A quick Google for &#8220;Bamboo git plugin&#8221; led to a bit of a hypertext chase that <a href="http://github.com/krosenvold/bgit">eventually ended up here</a>.  Looks like this particular plugin has passed through the hands of <a href="http://jira.atlassian.com/browse/BAM-2875">at least a couple of maintainers</a>, but so far it&#8217;s worked exactly as advertised.  And again, loving the dog food analogy, it&#8217;s nice to see a project enabling Git hosted on github. Thanks very much to <a href="http://incodewetrustinc.blogspot.com/">Kristian Rosenvold</a> for running with the ball on this one! Again, drop the jar into $BAMBOO_INSTALL_DIR/webapp/WEB-INF/lib and restart Bamboo. When creating a plan you will now have Git as a choice for a Source Repository. In my case I&#8217;m just using a plain file repository that resides on the build box, but it should work just as well with a remote repository.</p>

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/bamboo-grails-and-git/bamboogitsetup.png" title="Select Git as the source repository for a Bamboo plan" class="shutterset_singlepic31" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/31__750x_bamboogitsetup.png" alt="Select Git as the source repository for a Bamboo plan" title="Select Git as the source repository for a Bamboo plan" />
</a>

<p>Setting up the Grails targets is similarly straightforward. Thanks to <a href="http://today.java.net/pub/a/today/2009/06/23/Grails-and-Continuous-Integration.html">this article</a>, which describes the Grails setup on Hudson, and reminded me about the &#8211;non-interactive flag since obviously the build server isn&#8217;t going to be able to interact with the console. I&#8217;m also using a couple of Grails plugins to provide static source code analysis so my parameters also include -coverage and a call to the codenarc script.</p>

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/bamboo-grails-and-git/bamboograilssetup.png" title="Select Grails as a builder and specify which scripts to call for a Bamboo plan" class="shutterset_singlepic32" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/32__750x_bamboograilssetup.png" alt="Select Grails as a builder and specifying which scripts to call for a Bamboo plan" title="Select Grails as a builder and specifying which scripts to call for a Bamboo plan" />
</a>

<p>I had a little trepidation about how this would all turn out after <a href="http://www.dish2dish.com/confluence/display/NPB/2009/12/26/Grails+and+Tools+In+A+Corporate+World">reading this blog post</a>, but I&#8217;ve had much better results so far in my personal experience. It&#8217;s entirely possible that the key differentiator is wrapping Grails with Maven. It&#8217;s definitely not perfect, but it is <a href="http://www.guntheranderson.com/v/data/gettingb.htm">getting better all the time</a>. Hopefully you have better luck in the future Neil!</p>

<div class="ngg-galleryoverview" id="ngg-gallery-8-1015">

	<!-- Slideshow link -->
	<div class="slideshowlink">
		<a class="slideshowlink" href="http://www.kellyrob99.com/blog/2010/01/07/bamboo-grails-and-git-for-continuous-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=8&amp;mode=gallery'});">
			[View with PicLens]		</a>
	</div>
	
	<!-- Thumbnails -->
		
	<div id="ngg-image-30" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/bamboo-grails-and-git/addingbamboograilsbuilder.png" title="Adding the builder definition to Bamboo" class="shutterset_set_8" >
								<img title="Adding the builder definition to Bamboo" alt="Adding the builder definition to Bamboo" src="http://www.kellyrob99.com/blog/wp-content/gallery/bamboo-grails-and-git/thumbs/thumbs_addingbamboograilsbuilder.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-31" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/bamboo-grails-and-git/bamboogitsetup.png" title="Select Git as the source repository for a Bamboo plan" class="shutterset_set_8" >
								<img title="Select Git as the source repository for a Bamboo plan" alt="Select Git as the source repository for a Bamboo plan" src="http://www.kellyrob99.com/blog/wp-content/gallery/bamboo-grails-and-git/thumbs/thumbs_bamboogitsetup.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-32" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/bamboo-grails-and-git/bamboograilssetup.png" title="Select Grails as a builder and specify which scripts to call for a Bamboo plan" class="shutterset_set_8" >
								<img title="Select Grails as a builder and specifying which scripts to call for a Bamboo plan" alt="Select Grails as a builder and specifying which scripts to call for a Bamboo plan" src="http://www.kellyrob99.com/blog/wp-content/gallery/bamboo-grails-and-git/thumbs/thumbs_bamboograilssetup.png" width="98" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-33" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/bamboo-grails-and-git/bamboorequirementssetup.png" title="All requirements satisfied to run a Bamboo plan!" class="shutterset_set_8" >
								<img title="All requirements satisfied to run a Bamboo plan!" alt="All requirements satisfied to run a Bamboo plan!" src="http://www.kellyrob99.com/blog/wp-content/gallery/bamboo-grails-and-git/thumbs/thumbs_bamboorequirementssetup.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/38734ac1-c6ec-4339-aaf2-b09678979e9b/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=38734ac1-c6ec-4339-aaf2-b09678979e9b" 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/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/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/03/21/gource-visualizations-of-the-groovygrailsgriffon-projects/' rel='bookmark' title='Gource Visualizations of the Groovy/Grails/Griffon Projects'>Gource Visualizations of the Groovy/Grails/Griffon Projects</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/01/07/bamboo-grails-and-git-for-continuous-integration/feed/</wfw:commentRss>
		<slash:comments>2</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>A Techno-Geek&#8217;s Guide to Encyclopedic Knowledge</title>
		<link>http://www.kellyrob99.com/blog/2009/09/09/a-techno-geeks-guide-to-encyclopedic-knowledge/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-techno-geeks-guide-to-encyclopedic-knowledge</link>
		<comments>http://www.kellyrob99.com/blog/2009/09/09/a-techno-geeks-guide-to-encyclopedic-knowledge/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 02:31:49 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Reader]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Griffon]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[knowledge]]></category>
		<category><![CDATA[Lifehacker]]></category>
		<category><![CDATA[Open source]]></category>
		<category><![CDATA[training]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=739</guid>
		<description><![CDATA[Do you make keeping up with technology a priority? Have you found a way to prevent drowning in the vast sea of content AND still keep abreast of everything you want to? Me neither, but here&#8217;s where I go to learn new things, find solutions and keep up with the general state of the union [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/03/21/gource-visualizations-of-the-groovygrailsgriffon-projects/' rel='bookmark' title='Gource Visualizations of the Groovy/Grails/Griffon Projects'>Gource Visualizations of the Groovy/Grails/Griffon Projects</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/06/02/a-grails-app-demoing-the-stackexchange-api/' rel='bookmark' title='A Grails App Demoing the StackExchange API'>A Grails App Demoing the StackExchange API</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>Do you make keeping up with technology a priority? Have you found a way to prevent drowning in the vast sea of content AND still keep abreast of everything you want to? Me neither, but here&#8217;s where I go to learn new things, find solutions and keep up with the general state of the union regarding software I use; not to mention keeping track of what new tools are available to speed development.  This is far from an exhaustive list but I wanted to concentrate on primarily free sources of information and tooling. Yes ladies and gentlemen pretty much everything mentioned on this page requires at most an internet connection and a web browser to use.</p>
<p><strong>DISCLAIMER</strong>: yes, this is heavily geared towards(but not exclusive to) Groovy-esque sources. What can I say &#8211; it&#8217;s where I spend most of my time.</p>
<p><br class="spacer_" /></p>
<h2><span style="text-decoration: underline;">Google&#8230; in General</span></h2>
<p>If you want to find something &#8211; well let&#8217;s just say any service that is so pervasive it <a href="http://www.thefreedictionary.com/Google">becomes a verb</a> in the language might be useful.  Learning how to harness the power of the Google architecture can greatly enhance your learning experience. And I can&#8217;t see myself Bing&#8217;ing anytime soon.</p>
<ol>
<li><strong><a href="http://www.google.com">Google Search</a>:</strong> Knowing and using the <a href="http://www.googleguide.com/advanced_operators_reference.html">Google search syntax</a> properly can be a very powerful tool for finding specific tech-geekie knowledge.</li>
<li><strong><a href="http://www.google.com/reader">Google Reader</a>:</strong> Listening to the right content can save you a lot of time when it comes to getting the most out of your code. Even if you don&#8217;t read it everyday, combined with <a class="zem_slink" title="Google Gears" rel="homepage" href="http://gears.google.com/">Gears</a> and searchability this provides another tool in the fight against techno-ignorance that doesn&#8217;t rely on an internet connection.</li>
<li><strong><a href="https://mail.google.com">Google Mail</a>:</strong> I combine mailing list subscriptions with filters to automatically organize content. Incoming messages from lists are archived and labeled accordingly by filter rules. With Gears installed I&#8217;ve got an off-line searchable database of grassroots questions and answers, similar to what an on-line service like<a href="http://markmail.org/"> MarkMail</a> provides. It&#8217;s hard to be the ongoing discussion of community members sharing their best tips, tricks and gotchas.</li>
<li><a href="http://code.google.com/search/#q=groovy"><strong>Google code</strong></a>: A great place to find open source projects that can assist you at work and provide valuable  learning materials. And yes, the link targets Groovy <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</li>
</ol>
<p><br class="spacer_" /></p>
<h2><span style="text-decoration: underline;">Aggregators</span></h2>
<p>Some kind people do most of the work for you &#8211; taking themed content and putting it all together in one place.</p>
<ol>
<li><a href="http://www.dzone.com"><strong>DZone</strong></a>: One of my favorite sources of  techie style news.</li>
<li><a href="http://www.groovyblogs.org"><strong>GroovyBlogs</strong></a>: A great example of &#8216;eating your own dog food&#8217;, this is a Grails powered site courtesy of one of the authors of <a href="http://www.manning.com/gsmith/">Grails in Action</a>. Most of the Groovy related blog articles I read come from this source.</li>
<li><a href="http://www.grailstutorials.com"><strong>Grails Tutorials</strong></a>: A nice collection of tutorial articles related to Grails and Groovy.</li>
<li><a href="http://gr8forums.org"><strong>GR8Forums</strong></a>: Brand new, this site has the potential to be a great discussion spot.</li>
</ol>
<p><br class="spacer_" /></p>
<h2><span style="text-decoration: underline;">Community Sharing</span></h2>
<p>There are certain places that encourage community and knowledge sharing more than others.</p>
<ol>
<li><strong><a href="http://groovyconsole.appspot.com/">Groovy Console in The Cloud</a>: </strong>This is an amazing example of an application exposing a Groovy console on the Google AppEngine, complete with community support for running, saving and commenting example code.  Since the code is freely available, there&#8217;s also already a <a href="http://code.google.com/p/spock/">Spock</a> console <a href="http://meetspock.appspot.com/">here in the cloud </a> forked/cloned from it.</li>
<li><strong><a href="http://github.com/">Github</a> and <a href="http://gist.github.com/gists">Gists</a>: </strong>More places to share code<strong> </strong>in project and/or snippet form.</li>
<li><a href="http://stackoverflow.com/"><strong>StackOverflow</strong></a>: A community effort to put together almost 300,000(and rising) questions and answers related to programming. If you have a question to ask, head over here &#8211; chances are someone else has already given an answer. It really is impressive how well this still evolving site functions.</li>
<li><strong>Podcasts</strong>: <a href="http://javaposse.com/">JavaPosse</a> and the <a href="http://grailspodcast.com/blog/list">Grails podcast</a> are on top of my list and usually get listened to during my commute to work.There are hundreds of tech related podcasts out there; pick one or two and give them a listen,  you won&#8217;t regret it.</li>
<li><strong><a href="http://mrhaki.blogspot.com/">mrhaki</a></strong><strong> :</strong> OK, this guy gets special mention just for busting out code examples for pretty much every Groovy feature you can possibly imagine. Seriously the guy posts 20+ times a month on average.</li>
</ol>
<p><br class="spacer_" /></p>
<h2><span style="text-decoration: underline;">Home Pages</span></h2>
<p>These aren&#8217;t necessarily up to date at all times, but are great places to start looking for generalized knowledge and additional resource material.</p>
<ol>
<li><a href="http://groovy.codehaus.org/"><strong>Groovy</strong></a>: Pay particular attention to the &#8216;Cookbook Examples&#8217; and the &#8216;Modules&#8217; available to quickly add functionality.</li>
<li><a href="http://grails.org/"><strong>Grails</strong></a>: A particularly rich and well organized site &#8211; with the latest update it&#8217;s also very pretty.</li>
<li><a href="http://griffon.codehaus.org/"><strong>Griffon</strong></a>: The builder documentation linked from here, combined with the example scripts included with <a href="http://www.jroller.com/aalmiray/entry/announcing_swingpad_0_3">SwingPad</a>, get you up to speed quickly on all of the buildery goodness available in Griffon.</li>
</ol>
<p><br class="spacer_" /></p>
<h2><span style="text-decoration: underline;">Useful and Inspiring</span></h2>
<p>These are resources I use to step out of the box and to remind myself that it&#8217;s not only in elegant code that geekiness lies.</p>
<ol>
<li><a href="http://lifehacker.com"><strong>Lifehacker</strong></a>: I get into trouble a lot for this one; in my house whenever someone asks me &#8220;How do I do {fill in the blank}?&#8221; I invariably respond with &#8220;Well what does Lifehacker say?&#8221; My personal favorite is the <a href="http://lifehacker.com/301435/pack-like-a-pro-with-the-bundled-wrapping-method">bundle wrapping method</a>. With a nice mix of techie and common sense goodness, I love to follow this site.</li>
<li><a href="http://makezine.com/"><strong>Make magazine</strong></a>: In need of a DIY project to fill up the weekend? From the <a href="http://makezine.com/mintyboost/">Minty Boost</a> for a $20 portable USB charger to <a href="http://makezine.com/19/">robots</a> this place takes geeking out entirely to the next level. </li>
<li><strong><a href="http://www.jonathancoulton.com/">Jonathon Coulton</a></strong>: With eye-popping geekiness, Jonathon brings us such wonderful classics as &#8220;Code Monkey&#8221; and &#8220;Re Your Brains&#8221; &#8211; and under a Creatives Commons license as well!</li>
</ol>
<p><br class="spacer_" /></p>
<h2><span style="text-decoration: underline;">Twitter</span></h2>
<p>Use with caution. More than any other source of data, this one can end up being seriously distracting. I&#8217;m careful about who I listen to, while simultaneously trying to remind myself that nobody cares what I had for breakfast or how much I enjoyed it. Have you tried Twitter yet? Not as easy as it sounds buster, believe you me. Just wait and see. If you can keep yourself from jumping every time a new Tweet lands at your desktop, this can be the freshest, fastest way to satisfy your tech cravings.</p>
<p><br class="spacer_" /></p>
<h2><span style="text-decoration: underline;">Books</span></h2>
<p>OK, so these aren&#8217;t free, but if you want to jumpstart your knowledge on a particular piece of technology, software or framework, picking up a recent book on the subject can truly help. I try to add a new book to the library every month, but the hard part is really finding the time to read and apply the new knowledge.</p>
<p><br class="spacer_" /></p>
<p><br class="spacer_" /></p>
<p>I don&#8217;t expect that these suggestions are for everyone, but hopefully a few of you out there in the interwebs will find some of them helpful. And feel free to share what works for you if I&#8217;ve missed anything.</p>
<p><br class="spacer_" /></p>
<p><br class="spacer_" /></p>
<p><br class="spacer_" /></p>
<p><br class="spacer_" /></p>
<p><br class="spacer_" /></p>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" title="Reblog this post [with Zemanta]" href="http://reblog.zemanta.com/zemified/7d9558be-298b-4093-8276-447473a3f4d5/"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=7d9558be-298b-4093-8276-447473a3f4d5" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><br />
<script src="http://static.zemanta.com/readside/loader.js" type="text/javascript"></script></p>
<p><br class="spacer_" /></p>
<p><br class="spacer_" /></p>
<p></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/03/21/gource-visualizations-of-the-groovygrailsgriffon-projects/' rel='bookmark' title='Gource Visualizations of the Groovy/Grails/Griffon Projects'>Gource Visualizations of the Groovy/Grails/Griffon Projects</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/06/02/a-grails-app-demoing-the-stackexchange-api/' rel='bookmark' title='A Grails App Demoing the StackExchange API'>A Grails App Demoing the StackExchange API</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/09/09/a-techno-geeks-guide-to-encyclopedic-knowledge/feed/</wfw:commentRss>
		<slash:comments>4</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>
	</channel>
</rss>

