<?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; Grails</title>
	<atom:link href="http://www.kellyrob99.com/blog/tag/grails/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>Hooking into the Jenkins(Hudson) API</title>
		<link>http://www.kellyrob99.com/blog/2011/03/27/hooking-into-the-jenkinshudson-api/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=hooking-into-the-jenkinshudson-api</link>
		<comments>http://www.kellyrob99.com/blog/2011/03/27/hooking-into-the-jenkinshudson-api/#comments</comments>
		<pubDate>Sun, 27 Mar 2011 17:24:09 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[Gradle]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[HTTPBuilder]]></category>
		<category><![CDATA[Hudson]]></category>
		<category><![CDATA[jenkins]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[kellyrob99.com]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1587</guid>
		<description><![CDATA[Which one &#8211; Hudson or Jenkins? Both. I started working on this little project a couple of months back using Hudson v1.395 and returned to it after the great divide happened. I took it as an opportunity to see whether there would be any significant problems should I choose to move permanently to Jenkins in [...]
Related posts:<ol>
<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/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/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>Which one &#8211; Hudson or Jenkins?</h2>
<p>Both. I started working on this little project a couple of months back using Hudson v1.395 and returned to it after the great divide happened. I took it as an opportunity to see whether there would be any significant problems should I choose to move permanently to Jenkins in the future. There were a couple of hiccups- most notably that the new CLI jar didn&#8217;t work right out of the box- but overall v1.401 of Jenkins worked as expected after the switch. The good news is the old version of the CLI jar still works, so this example is actually using a mix of code to get things done. Anyway, the software is great and there&#8217;s more than enough credit to go around.</p>
<p></p>
<h2>The API</h2>
<p>Jenkins/Hudson has a <a href="http://wiki.hudson-ci.org/display/HUDSON/Remote+access+API">handy remote API</a> packed with information about your builds and supports a rich set of functionality to control them, and the server in general, remotely. It is possible to trigger builds, copy jobs, stop the server and even install plugins remotely. You have your choice of XML, JSON or Python when interacting with the APIs of the server.  And, as the build in documentation says, you can find the functionality you need on a relative path from the build server url at:</p>
<blockquote><p>&#8220;/&#8230;/api/ where &#8216;&#8230;&#8217; portion is the object for which you&#8217;d like to access&#8221;.</p></blockquote>
<p>This will show a brief documentation page if you navigate to it in a browser, and will return a result if you add the desired format as the last part of the path. For instance, to load information about the computer running a locally hosted Jenkins server, a get request on this url would return the result in JSON format: http://localhost:8080/computer/api/json.</p>
<pre class="brush: plain; title: ; notranslate">
{
  &quot;busyExecutors&quot;: 0,
  &quot;displayName&quot;: &quot;nodes&quot;,
  &quot;computer&quot;: [
    {
      &quot;idle&quot;: true,
      &quot;executors&quot;: [
        {
        },
        {
        }
      ],
      &quot;actions&quot;: [

      ],
      &quot;temporarilyOffline&quot;: false,
      &quot;loadStatistics&quot;: {
      },
      &quot;displayName&quot;: &quot;master&quot;,
      &quot;oneOffExecutors&quot;: [

      ],
      &quot;manualLaunchAllowed&quot;: true,
      &quot;offline&quot;: false,
      &quot;launchSupported&quot;: true,
      &quot;icon&quot;: &quot;computer.png&quot;,
      &quot;monitorData&quot;: {
        &quot;hudson.node_monitors.ResponseTimeMonitor&quot;: {
          &quot;average&quot;: 111
        },
        &quot;hudson.node_monitors.ClockMonitor&quot;: {
          &quot;diff&quot;: 0
        },
        &quot;hudson.node_monitors.TemporarySpaceMonitor&quot;: {
          &quot;size&quot;: 58392846336
        },
        &quot;hudson.node_monitors.SwapSpaceMonitor&quot;: null,
        &quot;hudson.node_monitors.DiskSpaceMonitor&quot;: {
          &quot;size&quot;: 58392846336
        },
        &quot;hudson.node_monitors.ArchitectureMonitor&quot;: &quot;Mac OS X (x86_64)&quot;
      },
      &quot;offlineCause&quot;: null,
      &quot;numExecutors&quot;: 2,
      &quot;jnlpAgent&quot;: false
    }
  ],
  &quot;totalExecutors&quot;: 2
}
</pre>
<p>Here&#8217;s the same tree rendered using GraphViz.</p>

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/computer.png" title="" class="shutterset_singlepic74" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/74_watermark_700x500_computer.png" alt="computer" title="computer" />
</a>

<p>This functionality extends out in a tree from the root of the server, and you can gate how much of the tree you load from any particular branch by supplying a &#8216;depth&#8217; parameter on your urls. Be careful how high you specify this variable. Testing with a load depth of four against a populous, long-running build server (dozens of builds with thousands of job executions) managed to regularly timeout for me. To give you an idea, here&#8217;s a very rough visualization of the domain at depth three from the root of the api.</p>

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/hudsonapidepth3.png" title="" class="shutterset_singlepic68" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/68_watermark_700x500_hudsonapidepth3.png" alt="hudsonapidepth3" title="hudsonapidepth3" />
</a>

<p>Getting data out of the server is very simple, but the ability to remotely trigger activity on the server is more interesting. In order to trigger a build of a job named &#8216;test&#8217;, a POST on http://localhost:8080/job/test/build does the job. Using the available facilities, it&#8217;s pretty easy to do things like:</p>
<ul>
<li>load a job&#8217;s configuration file, modify it and create a new job by POSTing the new config.xml file</li>
<li>move a job from one build machine to another</li>
<li>build up an overview of scheduled builds</li>
</ul>
<p></p>
<h2>The CLI Jar</h2>
<p>There&#8217;s another way to remotely drive build servers in the CLI jar distributed along with the server. This jar provides simple facilities for executing certain commands remotely on the build server. Of note, this enables installing plugins remotely and executing a remote Groovy shell. I incorporated this functionality with a very thin wrapper around the main class exposed by the CLI jar as shown in the next code sample.</p>
<pre class="brush: groovy; title: ; notranslate">
/**
 * Drive the CLI with multiple arguments to execute.
 * Optionally accepts streams for input, output and err, all of which
 * are set by default to System unless otherwise specified.
 * @param rootUrl
 * @param args
 * @param input
 * @param output
 * @param err
 * @return
 */
def runCliCommand(String rootUrl, List&lt;String&gt; args, InputStream input = System.in,
        OutputStream output = System.out, OutputStream err = System.err)
{
    def CLI cli = new CLI(rootUrl.toURI().toURL())
    cli.execute(args, input, output, err)
    cli.close()
}
</pre>
<p>And here&#8217;s a simple test showing how you can execute a Groovy script to load information about jobs, similar to what you can do from the built-in Groovy script console on the server, which can be found for a locally installed deployment at http://localhost:8080/script.</p>
<pre class="brush: groovy; title: ; notranslate">
def &quot;should be able to query hudson object through a groovy script&quot;()
{
    final ByteArrayOutputStream output = new ByteArrayOutputStream()
    when:
    api.runCliCommand(rootUrl, ['groovysh', 'for(item in hudson.model.Hudson.instance.items) { println(&quot;job $item.name&quot;)}'],
            System.in, output, System.err)

    then:
    println output.toString()
    output.toString().split('\n')[0].startsWith('job')
}
</pre>
<p>Here are some links to articles about the CLI, if you want to learn more :</p>
<ul>
<li><a href="http://wiki.hudson-ci.org/display/HUDSON/Hudson+CLI">Hudson CLI wikidoc</a></li>
<li><a href="http://wiki.jenkins-ci.org/display/JENKINS/Jenkins+CLI">Jenkins CLI wikidoc</a></li>
<li><a href="http://jenkins-php.org/">A template for PHP jobs on Jenkins</a></li>
<li><a href="http://weblogs.java.net/blog/kohsuke/archive/2009/05/hudson_cli_and.html">An article from Kohsuke Kawaguchi</a></li>
<li><a href="http://meera-subbarao.blogspot.com/2010/08/hudson-and-cli.html">A nice tutorial</a></li>
</ul>
<p></p>
<h2>HTTPBuilder</h2>
<p><a href="http://groovy.codehaus.org/modules/http-builder/">HTTPBuilder</a> is my tool of choice when programming against an HTTP API nowadays. The usage is very straightforward and I was able to get away with only two methods to support reaching the entire API: one for GET and one for POST. Here&#8217;s the GET method, sufficient for executing the request, parsing the JSON response, and complete with (albeit naive) error handling.</p>
<pre class="brush: groovy; title: ; notranslate">
/**
 * Load info from a particular rootUrl+path, optionally specifying a 'depth' query
 * parameter(default depth = 0)
 *
 * @param rootUrl the base url to access
 * @param path  the api path to append to the rootUrl
 * @param depth the depth query parameter to send to the api, defaults to 0
 * @return parsed json(as a map) or xml(as GPathResult)
 */
def get(String rootUrl, String path, int depth = 0)
{
    def status
    HTTPBuilder http = new HTTPBuilder(rootUrl)
    http.handler.failure = { resp -&gt;
        println &quot;Unexpected failure on $rootUrl$path: ${resp.statusLine} ${resp.status}&quot;
        status = resp.status
    }

    def info
    http.get(path: path, query: [depth: depth]) { resp, json -&gt;
        info = json
        status = resp.status
    }
    info ?: status
}
</pre>
<p>Calling this to fetch data is a one liner, as the only real difference is the &#8216;path&#8217; variable used when calling the API.</p>
<pre class="brush: groovy; title: ; notranslate">
private final GetRequestSupport requestSupport = new GetRequestSupport()
    ...
/**
 * Display the job api for a particular Hudson job.
 * @param rootUrl the url for a particular build
 * @return job info in json format
 */
def inspectJob(String rootUrl, int depth = 0)
{
    requestSupport.get(rootUrl, API_JSON, depth)
}
</pre>
<p>Technically, there&#8217;s nothing here that limits this to JSON only. One of the great things about HTTPBuilder is that it will happily just try to do the right thing with the response. If the data returned is in JSON format, as these examples are, it gets parsed into a JSONObject. If on the other hand, the data is XML, it gets parsed into a Groovy GPathResult. Both of these are very easily navigable, although the syntax for navigating their object graphs is different.</p>
<p></p>
<h2>What can you do with it?</h2>
<p>My primary motivation for exploring the API of Hudson/Jenkins was to see how I could make managing multiple servers easier. At present I work daily with four build servers and another handful of slave machines, and support a variety of different version branches. This includes a mix of unit and functional test suites, as well as a continuous deployment job that regularly pushes changes to test machines matching our supported platform matrix, so unfortunately things are not quite as simple as copying a single job when branching. Creating the build infrastructure for new feature branches in an automatic, or at least semi-automatic, fashion is attractive indeed, especially since plans are in the works to expand build automation. For a recent 555 day project, I utilized the API layer to build a Grails app functioning as both a cross-server build radiator and a central facility for server management. This proof of concept is capable of connecting to multiple build servers and visualizing job data as well as specific system configuration, triggering builds, and direct linking to each of the connected servers to allow for drilling down further. Here&#8217;s a couple of mock-ups that pretty much show the picture.<br />

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/grailsapp1.png" title="" class="shutterset_singlepic71" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/71_watermark_700x500_grailsapp1.png" alt="grailsapp1" title="grailsapp1" />
</a>
<br />

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/grailsapp2.png" title="" class="shutterset_singlepic73" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/73_watermark_700x500_grailsapp2.png" alt="grailsapp2" title="grailsapp2" />
</a>
</p>
<p></p>
<h2>Just a pretty cool app for installing Jenkins</h2>
<p>This is only very indirectly related, but I came across this very nice and simple Griffon app, called the <a href="http://code.google.com/p/jenkins-assembler/">Jenkins-Assembler</a> which simplifies preparing your build server. It presents you with a list of plugins, letting you pick and choose, and then downloads and composes them into a single deployable war.<br />

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/jenkins-assembler.png" title="" class="shutterset_singlepic75" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/75__x_jenkins-assembler.png" alt="jenkins-assembler" title="jenkins-assembler" />
</a>
</p>
<p></p>
<h2>Enough talking &#8211; where&#8217;s the code???</h2>
<p>Source code related to this article is <a href="https://github.com/kellyrob99/Jenkins-api-tour">available on github</a>.  The tests are more of an exploration of the live API than an actual test of the code in this project. They run against a local server launched using the Gradle Jetty plugin. Finally, here&#8217;s some pretty pictures for you.</p>

<div class="ngg-galleryoverview" id="ngg-gallery-13-1587">

	<!-- Slideshow link -->
	<div class="slideshowlink">
		<a class="slideshowlink" href="http://www.kellyrob99.com/blog/2011/03/27/hooking-into-the-jenkinshudson-api/?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=13&amp;mode=gallery'});">
			[View with PicLens]		</a>
	</div>
	
	<!-- Thumbnails -->
		
	<div id="ngg-image-65" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/computerdepth4.png" title=" " class="shutterset_set_13" >
								<img title="computerdepth4" alt="computerdepth4" src="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/thumbs/thumbs_computerdepth4.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-66" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/gradleconfig.png" title=" " class="shutterset_set_13" >
								<img title="gradleconfig" alt="gradleconfig" src="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/thumbs/thumbs_gradleconfig.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-67" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/hudsonapi.png" title=" " class="shutterset_set_13" >
								<img title="hudsonapi" alt="hudsonapi" src="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/thumbs/thumbs_hudsonapi.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-68" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/hudsonapidepth3.png" title=" " class="shutterset_set_13" >
								<img title="hudsonapidepth3" alt="hudsonapidepth3" src="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/thumbs/thumbs_hudsonapidepth3.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-69" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/lastbuilddepth1.png" title=" " class="shutterset_set_13" >
								<img title="lastbuilddepth1" alt="lastbuilddepth1" src="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/thumbs/thumbs_lastbuilddepth1.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-70" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/overallloaddepth3.png" title=" " class="shutterset_set_13" >
								<img title="overallloaddepth3" alt="overallloaddepth3" src="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/thumbs/thumbs_overallloaddepth3.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-71" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/grailsapp1.png" title=" " class="shutterset_set_13" >
								<img title="grailsapp1" alt="grailsapp1" src="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/thumbs/thumbs_grailsapp1.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-74" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/computer.png" title=" " class="shutterset_set_13" >
								<img title="computer" alt="computer" src="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/thumbs/thumbs_computer.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-73" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/grailsapp2.png" title=" " class="shutterset_set_13" >
								<img title="grailsapp2" alt="grailsapp2" src="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/thumbs/thumbs_grailsapp2.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-75" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/jenkins-assembler.png" title=" " class="shutterset_set_13" >
								<img title="jenkins-assembler" alt="jenkins-assembler" src="http://www.kellyrob99.com/blog/wp-content/gallery/hudson-api/thumbs/thumbs_jenkins-assembler.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 	 	
	<!-- Pagination -->
 	<div class='ngg-clear'></div>
 	
</div>


<!-- 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/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/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/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/03/27/hooking-into-the-jenkinshudson-api/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A Grails App Demoing the StackExchange API</title>
		<link>http://www.kellyrob99.com/blog/2010/06/02/a-grails-app-demoing-the-stackexchange-api/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-grails-app-demoing-the-stackexchange-api</link>
		<comments>http://www.kellyrob99.com/blog/2010/06/02/a-grails-app-demoing-the-stackexchange-api/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 07:12:17 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Application programming interface]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Reader]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[Representational State Transfer]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[Stack Overflow]]></category>
		<category><![CDATA[StackApps]]></category>
		<category><![CDATA[StackExchange]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1367</guid>
		<description><![CDATA[So I was making an attempt to catch up on my Google Reader&#8216;ing this weekend and I came across this post on StackOverflow regarding the shiny new StackExchange API. That and a fresh 1.3.1 drop of Grails seemed like as good a reason as any to hack together a little app suitable for seeing what [...]
Related posts:<ol>
<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/2009/10/25/grails-ui-datatable-using-xml-for-a-model/' rel='bookmark' title='Grails-UI DataTable using XML for a model'>Grails-UI DataTable using XML for a model</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/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>So I was making an attempt to catch up on my <a class="zem_slink" href="http://www.google.com/reader" title="Google Reader" rel="homepage">Google Reader</a>&#8216;ing this weekend and I came across <a href="http://blog.stackoverflow.com/2010/05/stack-exchange-api-contest/">this post on StackOverflow</a> regarding the shiny new <a class="zem_slink" href="http://www.stackexchange.com" title="StackExchange" rel="homepage">StackExchange</a> <a class="zem_slink" href="http://en.wikipedia.org/wiki/Application_programming_interface" title="Application programming interface" rel="wikipedia">API</a>. That and a fresh 1.3.1 drop of <a class="zem_slink" href="http://grails.org" title="Grails (framework)" rel="homepage">Grails</a> seemed like as good a reason as any to hack together a little app suitable for seeing what you can do with said API.<br />
Turns out it&#8217;s not a whole lot, at least not yet. The minor detraction of having  read-only access and limited connects without an API key are more than offset by seeing such a minimal, clean and easy to use interface. According to the grails stats script, it took about this much effort to implement calls to each and every one of the API endpoints for all of the supported domains:</p>
<pre class="brush: xml; title: ; notranslate">
    +----------------------+-------+-------+
    | Name                 | Files |  LOC  |
    +----------------------+-------+-------+
    | Controllers          |     1 |    42 |
    | Groovy Helpers       |     1 |    47 |
    +----------------------+-------+-------+
    | Totals               |     2 |    89 |
    +----------------------+-------+-------+
</pre>
<p>
Please note that this is about as minimal as you could reasonably get away with(and kinda ugly to boot), but nevertheless it does manage to implement a UI and backend for exercising the entire API in a total of 2 gsp files and 1 controller action.  What&#8217;s noticeably missing are some tailored views for each of the different <a class="zem_slink" href="http://json.org/" title="JSON" rel="homepage">JSON</a> responses and the implementation of additional query parameters on the calls.</p>
<p></p>
<h2>StackExchange API</h2>
<p>This is really <a href="http://api.stackoverflow.com/0.8/help">pretty well documented</a> and &#8220;consistent&#8221;. Calls in some cases require an {id} in the url and that&#8217;s about it. Each of the individual calls has its own help page that describes the options, like the <a href="http://api.stackoverflow.com/0.8/help/method?method=badges">badges page</a> for instance. To make things a little more helpful while exploring the API, each of the implemented endpoints in this app are also hyper-linked to the corresponding manual page on api.stackoverflow.com.</p>
<p></p>
<h2><a class="zem_slink" href="http://en.wikipedia.org/wiki/Representational_State_Transfer" title="Representational State Transfer" rel="wikipedia">RESTful</a> Access</h2>
<p>Couldn&#8217;t be a whole lot easier than using <a href="http://groovy.codehaus.org/modules/http-builder/">HttpBuilder</a>, which provides nice and concise ways to execute the GET request, inspect the response and deal with success/failure of the request. Aside from assigning the root domain and method using variables, this is little different from the <a href="http://groovy.codehaus.org/HTTP+Builder">canonical example on codehaus</a>.</p>
<pre class="brush: groovy; title: ; notranslate">
def http = new HTTPBuilder(&quot;http://api.$domain&quot;)
http.request(GET, JSON) {
    uri.path = &quot;/${VERSION}$method&quot;
    headers.'User-Agent' = 'Mozilla/5.0 Ubuntu/8.10 Firefox/3.0.4'
     response.success = { resp, json -&gt;
        answer = json
    }
     response.failure = { resp -&gt;
        answer = &quot;Unexpected error: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}&quot;
    }
}
</pre>
<p>The syntax here could probably get even Groovier using the <a href="http://www.grails.org/plugin/rest">Grails REST client plugin</a> wrappers, and indeed incorporating that plugin is how the HttpBuilder dependency is being provided in this app, but I hit on a working implementation first time out so we&#8217;ll leave that for another day, shall we?</p>
<p></p>
<h2>What&#8217;s it Look Like?</h2>
<p><img src='http://www.kellyrob99.com/blog/wp-content/gallery/stackoverflow-api-grails/stackapps-demo_1275451039026.png' alt='stackapps-demo' class='ngg-singlepic ngg-none'  width='860' height='480'/><br />
Did I mention it was ugly?  Where the API call requires a parameter, you get a text field. Each domain gets its own submit button, officially representing my first attempted usage of g:actionSubmit in Grails. Doesn&#8217;t work quite the way I expected, but it does certainly work. Click a button and you&#8217;re shown the raw JSON result, along with the call you made. In an ugly fashion, or did I say that already? Still, for a couple of hours of hacking, I&#8217;m not unhappy with the result.</p>
<p></p>
<h2>StackApps</h2>
<p>This is where the apps in the contest get shown off and, in a wonderful display of <a href="http://en.wikipedia.org/wiki/Eating_your_own_dog_food">dogfooding</a>, it&#8217;s guess what &#8211; another StackOverflow clone! The page for this application <a href="http://stackapps.com/questions/491/a-grails-app-demoing-the-stackexchange-api">can be found here</a>. And the <a href="http://github.com/kellyrob99/stackoverflow-api-grails">source code is up on github</a> if you&#8217;d like to take a look.</p>
<p></p>
<h2>Next Steps?</h2>
<p>Toying with the idea of porting this to appengine, which would unfortunately mean replacing HttpBuilder and the underlying Apache HttpClient in favor of something that didn&#8217;t use a threaded approach, most likely using <a href="http://code.google.com/appengine/docs/java/urlfetch/">URL fetch</a>. That and some slightly less ugly tabular and/or tree views of the JSON responses would be kinda nice to have.<br />
 <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/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/2009/10/25/grails-ui-datatable-using-xml-for-a-model/' rel='bookmark' title='Grails-UI DataTable using XML for a model'>Grails-UI DataTable using XML for a model</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/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/06/02/a-grails-app-demoing-the-stackexchange-api/feed/</wfw:commentRss>
		<slash:comments>3</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>Gource Visualizations of the Groovy/Grails/Griffon Projects</title>
		<link>http://www.kellyrob99.com/blog/2010/03/21/gource-visualizations-of-the-groovygrailsgriffon-projects/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=gource-visualizations-of-the-groovygrailsgriffon-projects</link>
		<comments>http://www.kellyrob99.com/blog/2010/03/21/gource-visualizations-of-the-groovygrailsgriffon-projects/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 01:58:41 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Cool Toys]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Concurrent Versions System]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[git-svn]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Griffon]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[MacPorts]]></category>
		<category><![CDATA[Mercurial]]></category>
		<category><![CDATA[Open source]]></category>
		<category><![CDATA[Revision control]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[SVN]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1226</guid>
		<description><![CDATA[That&#8217;s a whole lot of Gr8ness in the title, don&#8217;t you think? Ok, ok &#8211; I apologize for the pun. I whipped these up using the open source Gource visualization software and with HD content free on Youtube now, I just had to try that out too. Gource Gource is a software version control visualization [...]
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/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/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>That&#8217;s a whole lot of Gr8ness in the title, don&#8217;t you think? Ok, ok &#8211; I apologize for the pun. I whipped these up using the open source <a href="http://code.google.com/p/gource/">Gource</a> visualization software and with <a href="http://www.google.com/support/youtube/bin/answer.py?hl=en&amp;answer=153665">HD content free on Youtube</a> now, I just had to try that out too.</p>
<h2>Gource</h2>
<p>Gource is a software <a class="zem_slink" href="http://en.wikipedia.org/wiki/Revision_control" title="Revision control" rel="wikipedia">version control</a> visualization program with support for <a class="zem_slink" href="http://git-scm.com/" title="Git (software)" rel="homepage">Git</a>, <a class="zem_slink" href="http://mercurial.selenic.com/" title="Mercurial" rel="homepage">Mercurial</a>, and with a tiny bit of extra effort, <a class="zem_slink" href="http://www.nongnu.org/cvs" title="Concurrent Versions System" rel="homepage">CVS</a> and <a href="http://subversion.tigris.org/">Subversion</a>. It&#8217;s available as a macport install, as is the ffmpeg program used to stitch together a series of screenshots into the final video.&nbsp; All of these visualizations were created with Git or Git-svn. When the Gource program is running it brings up an interactive window so you can interact with it to a degree, affecting the camera, zoom, etc.&nbsp; The default resolution is 1024&#215;768 but I tried to bump it up to 1920&#215;1080. I&#8217;m assuming that stretched the limits of the rendering, as there&#8217;s quite a bit of pixellation in the final product; either that or the ffmpeg params need to be tweaked. The three visualizations on this page were all created using this one-liner command line invocation (broken down here over several lines for readability).</p>
<pre class="brush: bash; title: ; notranslate">
gource -1920x1080 --highlight-all-users --bloom-intensity .3 -a 1 -s .01
     --hide-dirnames --hide-filenames --stop-at-end --output-ppm-stream -
     | ffmpeg -y -b 3000K -r 60 -f image2pipe -vcodec ppm -i -
     -vcodec libx264 -vpre default  gource.mp4
</pre>
<h2>Groovy</h2>
<p>From the initial commit on August 28, 2003, Groovy has come a long way. I tried the Gource provided python script to translate an svn log file into the required format the first time, but cloning the repository with git-svn seemed to produce better results. It&#8217;s interesting to see that the overall structure of the Groovy project doesn&#8217;t look like is has changed very much over the years. I recognized a lot of the names you see on the screen. Be sure to watch the <a class="zem_slink" href="http://en.wikipedia.org/wiki/1080p" title="1080p" rel="wikipedia">1080p</a> version if you&#8217;re having trouble reading the text and see if you can&#8217;t find some recognizable committers.</p>
<p><a href="http://www.kellyrob99.com/blog/2010/03/21/gource-visualizations-of-the-groovygrailsgriffon-projects/"><em>Click here to view the embedded video.</em></a></p>
<h2>Grails</h2>
<p>Starting on Sunday March 14, 2004 here&#8217;s how it all unfolded, at least  from the perspective of the public Git repository. Grails looks like it grew a little more spontaneously than Groovy; there are more frequent restructurings and some transitions that seem to cover a whole lot of ground in very little time. In particular watch out for the burst of activity in the summer of 2009.</p>
<p><a href="http://www.kellyrob99.com/blog/2010/03/21/gource-visualizations-of-the-groovygrailsgriffon-projects/"><em>Click here to view the embedded video.</em></a></p>
<h2>Griffon</h2>
<p>September 17, 2008 marks the first commit for Griffon and this short but sweet video explodes right from the start. Benefiting greatly from the Grails model this project shows a lot of progress in a very short time indeed. Most, if not all, of the names you see here you probably caught in the previous two videos as well.<br />
<p><a href="http://www.kellyrob99.com/blog/2010/03/21/gource-visualizations-of-the-groovygrailsgriffon-projects/"><em>Click here to view the embedded video.</em></a></p></p>
<h2>What&#8217;s the Point?</h2>
<p>Watching these gives me (and maybe you) some appreciation for how much effort over time it takes to bring a new language/framework/technology to maturity and all of the individual contributions that go into it. Gource provides a lot more detail into the actual structure if you want to dig in. For purposes of keeping these images fairly uncluttered I removed file and directory names and just focused on the committers and the general structure. I think I gained a git of insight into how a codebase can evolve, and properly appreciate that organizing the increasing complexity of an ever-growing system over time is not a simple job. Plus they look cool. Enjoy!</p>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/2f2c3e09-4284-4248-b30f-d47242fd57a1/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=2f2c3e09-4284-4248-b30f-d47242fd57a1" 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/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/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/2010/03/21/gource-visualizations-of-the-groovygrailsgriffon-projects/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Developing Faster with the Atlassian IntelliJ Connector</title>
		<link>http://www.kellyrob99.com/blog/2010/02/21/developing-faster-with-the-atlassian-intellij-connector/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=developing-faster-with-the-atlassian-intellij-connector</link>
		<comments>http://www.kellyrob99.com/blog/2010/02/21/developing-faster-with-the-atlassian-intellij-connector/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 19:53:38 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Cool Toys]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Atlassian]]></category>
		<category><![CDATA[Atlassian IntelliJ Connector]]></category>
		<category><![CDATA[Bamboo]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Fisheye]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Integrated development environment]]></category>
		<category><![CDATA[JBoss Seam]]></category>
		<category><![CDATA[Jira]]></category>
		<category><![CDATA[Jira Studio]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1051</guid>
		<description><![CDATA[Once upon a time I used Eclipse as a development environment. It had a lot of things going for it: free(as in beer), rich community involvement, a plethora of plugins and probably my favorite feature: Mylyn. The problem was that it seemed everytime I wanted to upgrade to a newer version, inevitably half of the [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/01/02/atlassian-here-be-dragons/' rel='bookmark' title='Atlassian: Here Be Dragons'>Atlassian: Here Be Dragons</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/08/14/griffon-support-in-latest-intellij-eap/' rel='bookmark' title='Griffon support in latest Intellij EAP'>Griffon support in latest Intellij EAP</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/01/27/thanks-for-the-shirt-atlassian/' rel='bookmark' title='Thanks for the shirt Atlassian!'>Thanks for the shirt Atlassian!</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Once upon a time I used <a class="zem_slink" href="http://www.eclipse.org/" title="Eclipse (software)" rel="homepage">Eclipse</a> as a development environment. It had a lot of things going for it: free(as in beer), rich community involvement, a plethora of plugins and probably my favorite feature: <a href="http://www.eclipse.org/mylyn/">Mylyn</a>. The problem was that it seemed everytime I wanted to upgrade to a newer version, inevitably half of the integrations broke.   Please don&#8217;t get me wrong, Eclipse is AMAZING software and I do still use it occasionally for specific tasks &#8211; but nevertheless I now spend most of my day in <a class="zem_slink" href="http://www.jetbrains.com/idea/" title="IntelliJ IDEA" rel="homepage">IntelliJ</a>. In particular it had better support for Groovy/Grails development and Maven integration &#8211; both of which were essential to my everyday work. Throw in default included support for <a class="zem_slink" href="http://www.seamframework.org" title="JBoss Seam" rel="homepage">JBoss Seam</a>, JSF/Facelets, html and css and I didn&#8217;t really need a lot of plugins anymore. One of the ones I have been using, and that I&#8217;ve watched mature over the course of the last year, is the <a href="http://www.atlassian.com/software/ideconnector/intellij.jsp">Atlassian IntelliJ Connector</a>. Between it and the greatly improved changeset functionality I finally feel like I have a solid replacement for Mylyn&#8217;s excellent task management facilities.</p>
<p>This plugin integrates the IDE with one or more components of the <a class="zem_slink" href="http://www.atlassian.com/" title="Atlassian" rel="homepage">Atlassian</a> application suite. Multiple instances of <a class="zem_slink" href="http://atlassian.com/software/jira" title="JIRA (software)" rel="homepage">Jira</a>, <a class="zem_slink" href="http://www.atlassian.com/software/fisheye" title="FishEye (software)" rel="homepage">Fisheye</a>, <a class="zem_slink" href="http://www.atlassian.com/software/bamboo" title="Bamboo (software)" rel="homepage">Bamboo</a> and <a href="http://www.atlassian.com/software/crucible/">Crucible</a> can all be configured and used to streamline the development workflow.</p>
<p></p>
<h2>Jira</h2>
<p>This is perhaps the most essential piece of the puzzle, and inevitably the part a developer is going to interact with the most &#8211; the issue tracker. From within the IDE Jira master view you can load filters(basically stored searches for issues), do ad hoc searches and start work on a particular issue. If you drill down to a particular issue you can comment on it, assign it to yourself or another user, log work against it and generally manage it in most of the ways you can from the Jira web interface. Granted it&#8217;s not quite as pretty as the web interface, but the essential information and interaction is all there, and if you&#8217;re missing something an action is provided to open any issue in a web browser.</p>
<p>What really works for me is how the interaction supports my general workflow so closely:</p>
<div style="padding-left: 10px;">
<ul>
<li>Look in Jira for an issue to work on</li>
<li>Assign it to myself(if it&#8217;s not already)</li>
<li>Start progress on the issue, which starts a timer and creates a corresponding changeset</li>
<li>Do whatever development work that is required to satisfy the issue, pausing and resuming as necessary for<br />
            the duration of the task
        </li>
<li>Commit the changeset, optionally logging time against the issue and creating a Crucible review for later
        </li>
<li>Rinse and repeat</li>
</ul>
</div>
<p>Granted, I&#8217;m not the best at remembering to pause the timer, but being confronted with the time when I commit forces me to honestly evaluate how much time it took to complete the task when it&#8217;s clearest in my mind. And incidentally, while we&#8217;re here, the option to automatically organize imports in the commit dialog, a built in IDE function, has saved my butt from maven dependency-analyze any number of times.</p>
<p>It&#8217;s also convenient that you can see all comments and attachments for issues &#8211; viewing a screenshot describing a UI issue is pretty much essential after all, don&#8217;t you think?<br />

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/jiraissuedetailview.png" title="Jira detail view for an issue, including access to commentary and attachments." class="shutterset_singlepic53" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/53__x_jiraissuedetailview.png" alt="jiraissuedetailview" title="jiraissuedetailview" />
</a>
</p>
<h2>Bamboo</h2>
<p>So once your code is committed, a build is kicked off on Bamboo. Hopefully all goes well, but if any build you&#8217;re listening to fails the IDE will give you a message to that effect. You also have access to changes, tests and any associated build logs. And whether or not your build does fail, stacktraces from the log are immediately available and clickable in the IDE. In addition, you can manually trigger builds and label or comment them.<br />

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/bamboologview.png" title="Linking Bamboo logs to code in the IDE." class="shutterset_singlepic46" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/46__x_bamboologview.png" alt="bamboologview" title="bamboologview" />
</a>
</p>
<h2>Fisheye</h2>
<p>Integration with Fisheye is bi-directional between the IDE and the Fisheye webview. Context menus are available on right clicks in the IDE that open a file in Fisheye. And in the Fisheye web app clicking an IntelliJ icon will open a file in the IDE. It should be noted that this feature only appears to be available with Fisheye 2. I know because I&#8217;ve been missing it in Jira Studio, which still uses the 1.6 version of Fisheye.<br />

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/fisheyealtf1menu.png" title="Alt-F1 context menu for a file linked to Fisheye." class="shutterset_singlepic50" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/50__x_fisheyealtf1menu.png" alt="fisheyealtf1menu" title="fisheyealtf1menu" />
</a>
<br />

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/fisheyerightclickmenu.png" title="Right click context menu for a file linked to Fisheye." class="shutterset_singlepic52" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/52__x_fisheyerightclickmenu.png" alt="fisheyerightclickmenu" title="fisheyerightclickmenu" />
</a>
</p>
<h2>Crucible</h2>
<p>This is the one integration I&#8217;ve used the least so far, primarily because I don&#8217;t have Crucible installed locally for testing and again it seems a lot of the power of the integration is only available with version 2. The documentation certainly seems to suggest more rich functionality than I&#8217;ve found available anyhow. Fisheye and Crucible are actually bundled together for installation, so the Jira Studio version appears also restricted to the 1.6 version &#8211; for the time being at least. Mostly the Crucible integration is convenient because it provides messaging when reviews are assigned or commented.</p>
<p></p>
<h2>Documentation</h2>
<p>To be perfectly honest, I didn&#8217;t even look for these until writing this blog post. Configuring and using the plugin is very straightforward, provided you&#8217;re familiar with using these Atlassian tools at least. Nevertheless, I did discover a few additional bonuses and as usual <a href="http://confluence.atlassian.com/display/IDEPLUGIN/Atlassian+Connector+for+IntelliJ+IDEA">the docs are both complete and up to date</a>.</p>
<p></p>
<h2>Overall</h2>
<p>Really the point of using this plugin is to significantly reduce context switching; as much as possible your work is concentrated in one interface, and for the vast majority of cases you only need one piece of software running to get the job done. Where context switching is inevitable, this software tries to make it as &#8220;one-click&#8221; as possible. The end result is to put the power of your Atlassian products front and center in the IDE, where us developer types spend most of our working lives. Now, if only Jira Studio gets updated to the latest available software versions, because I&#8217;m dying to try out side-by-side diffs for Crucible reviews in IntelliJ!</p>
<p>Anyhow, if you use Atlassian tools the Connector is well worth checking out. And you Eclipse users aren&#8217;t left in the dark either. I can&#8217;t vouch for it&#8217;s quality, but there is an equivalent plugin for Eclipse available as well. </p>

<div class="ngg-galleryoverview" id="ngg-gallery-10-1051">

	<!-- Slideshow link -->
	<div class="slideshowlink">
		<a class="slideshowlink" href="http://www.kellyrob99.com/blog/2010/02/21/developing-faster-with-the-atlassian-intellij-connector/?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=10&amp;mode=gallery'});">
			[View with PicLens]		</a>
	</div>
	
	<!-- Thumbnails -->
		
	<div id="ngg-image-42" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/atlassianconnectorautoupdate.png" title="The plugin includes its own auto-update functionality, very handy!" class="shutterset_set_10" >
								<img title="atlassianconnectorautoupdate" alt="atlassianconnectorautoupdate" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_atlassianconnectorautoupdate.png" width="81" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-43" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/atlassianconnectorgeneralsettings.png" title="Preferences page of general settings for each application type." class="shutterset_set_10" >
								<img title="atlassianconnectorgeneralsettings" alt="atlassianconnectorgeneralsettings" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_atlassianconnectorgeneralsettings.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-44" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/bamboobuildcomment.png" title="Adding a comment to a completed Bamboo build." class="shutterset_set_10" >
								<img title="bamboobuildcomment" alt="bamboobuildcomment" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_bamboobuildcomment.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-45" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/bamboobuildpopup.png" title="This is the overview information presented when hovering over a build in the Bamboo view." class="shutterset_set_10" >
								<img title="bamboobuildpopup" alt="bamboobuildpopup" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_bamboobuildpopup.png" width="96" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-46" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/bamboologview.png" title="Linking Bamboo logs to code in the IDE." class="shutterset_set_10" >
								<img title="bamboologview" alt="bamboologview" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_bamboologview.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-47" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/bamboooverview.png" title="Overview of Bamboo builds you have configured." class="shutterset_set_10" >
								<img title="bamboooverview" alt="bamboooverview" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_bamboooverview.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-48" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/configuringnewapplications.png" title="Host specific configuration for each of the Atlassian applications." class="shutterset_set_10" >
								<img title="configuringnewapplications" alt="configuringnewapplications" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_configuringnewapplications.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-49" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/createajiraissue.png" title="Creating a new Jira issue from the IDE." class="shutterset_set_10" >
								<img title="createajiraissue" alt="createajiraissue" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_createajiraissue.png" width="77" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-50" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/fisheyealtf1menu.png" title="Alt-F1 context menu for a file linked to Fisheye." class="shutterset_set_10" >
								<img title="fisheyealtf1menu" alt="fisheyealtf1menu" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_fisheyealtf1menu.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-51" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/fisheyeexamplemacroview.png" title="Fisheye view, complete with IntelliJ button to open file directly in IDE." class="shutterset_set_10" >
								<img title="fisheyeexamplemacroview" alt="fisheyeexamplemacroview" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_fisheyeexamplemacroview.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-52" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/fisheyerightclickmenu.png" title="Right click context menu for a file linked to Fisheye." class="shutterset_set_10" >
								<img title="fisheyerightclickmenu" alt="fisheyerightclickmenu" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_fisheyerightclickmenu.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-53" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/jiraissuedetailview.png" title="Jira detail view for an issue, including access to commentary and attachments." class="shutterset_set_10" >
								<img title="jiraissuedetailview" alt="jiraissuedetailview" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_jiraissuedetailview.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-54" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/jiraissuepopup.png" title="This is the overview information presented when hovering over an issue in the Jira view." class="shutterset_set_10" >
								<img title="jiraissuepopup" alt="jiraissuepopup" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_jiraissuepopup.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-55" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/jiraissuesoverview.png" title="Overview of all Jira issues matching a filter or search." class="shutterset_set_10" >
								<img title="jiraissuesoverview" alt="jiraissuesoverview" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_jiraissuesoverview.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-56" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/jirastopwork.png" title="Dialog presented when 'stopping work' on a Jira issue; includes the ability to change the Jira state and log work against the issue." class="shutterset_set_10" >
								<img title="jirastopwork" alt="jirastopwork" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_jirastopwork.png" width="89" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-57" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/jiratoolbaradditions.png" title="Buttons the Connector adds to the top IDE button bar." class="shutterset_set_10" >
								<img title="jiratoolbaradditions" alt="jiratoolbaradditions" src="http://www.kellyrob99.com/blog/wp-content/gallery/atlassian-intellij-connector/thumbs/thumbs_jiratoolbaradditions.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/51641feb-8bfa-4376-b1dc-c90be9a1987f/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=51641feb-8bfa-4376-b1dc-c90be9a1987f" 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/02/atlassian-here-be-dragons/' rel='bookmark' title='Atlassian: Here Be Dragons'>Atlassian: Here Be Dragons</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/08/14/griffon-support-in-latest-intellij-eap/' rel='bookmark' title='Griffon support in latest Intellij EAP'>Griffon support in latest Intellij EAP</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/01/27/thanks-for-the-shirt-atlassian/' rel='bookmark' title='Thanks for the shirt Atlassian!'>Thanks for the shirt Atlassian!</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/02/21/developing-faster-with-the-atlassian-intellij-connector/feed/</wfw:commentRss>
		<slash:comments>0</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>Grails-UI DataTable using XML for a model</title>
		<link>http://www.kellyrob99.com/blog/2009/10/25/grails-ui-datatable-using-xml-for-a-model/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=grails-ui-datatable-using-xml-for-a-model</link>
		<comments>http://www.kellyrob99.com/blog/2009/10/25/grails-ui-datatable-using-xml-for-a-model/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 07:06:05 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Crucible]]></category>
		<category><![CDATA[DataTable]]></category>
		<category><![CDATA[Fisheye]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[google-charts]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[HTTPBuilder]]></category>
		<category><![CDATA[HttpClient]]></category>
		<category><![CDATA[Jira]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[RESTClient]]></category>
		<category><![CDATA[theKaptain]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=836</guid>
		<description><![CDATA[I had a great chance to play with some new stuff this weekend, namely Grails 1.2-M3, the new Grails REST plugin and Groovy in general. Awhile back I wrote some Groovy code to explore the various Jira, Fisheye and Crucible REST api&#8217;s using Apache HttpClient directly, and I wanted to see what it would like [...]
Related posts:<ol>
<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/2009/10/24/groovy-reverse-map-sort-done-easy/' rel='bookmark' title='Groovy reverse map sort done easy'>Groovy reverse map sort done easy</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>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I had a great chance to play with some new stuff this weekend, namely <a href="http://grails.org/1.2-M3+Release+Notes">Grails 1.2-M3</a>, the new <a href="http://grails.org/plugin/rest">Grails REST plugin</a> and Groovy in general. Awhile back I wrote some Groovy code to explore the various Jira, Fisheye and Crucible REST api&#8217;s using Apache HttpClient directly, and I wanted to see what it would like abstracted behind <a href="http://groovy.codehaus.org/modules/http-builder/">HTTPBuilder</a>. With the help of the <a href="http://grails.org/GrailsUI+Plugin">Grails-UI</a> and <a href="http://grails.org/plugin/google-chart">Google-charts</a> plugins, I got some pretty nice views of the data as well.</p>
<p>First off, dealing with a RESTful call was about as simple as I&#8217;ve ever seen. This is the entire code that deals with creating the connection, authenticating, executing a GET, and parsing the returned XML into a &#8216;data&#8217; property on the response.</p>
<pre class="brush: groovy; title: ; notranslate">
    private withFisheye(String url, Map args) {
        withRest(uri: url) {
            auth.basic userName, password
            return get(query: args)
        }
    }
</pre>
<p>Getting XML using <a href="http://www.jroller.com/aalmiray/">Andres&#8217;</a> plugin is extremely simple and we can achieve some pretty nice visualizations of the resulting data very easily as well. In particular I wanted to share how to use an XML response as a backing model for DataTable. The excellent examples provided by <a href="http://weblog.dangertree.net/tag/grailsui/">Matthew Taylor on his blog</a> seemed to concentrate on using GORM to load and sort domain objects to utilize as data models. When using XML as an alternative way to represent the data, and using RESTful calls to populate that data, the available sorting options on a DataTable weren&#8217;t able to function properly without a little extra help.</p>
<p>Consider an list of XML elements like this, which represents a single review in Crucible.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;reviewdata&gt;
    &lt;allowreviewerstojoin&gt;false&lt;/allowreviewerstojoin&gt;
    &lt;author&gt;
        &lt;displayname&gt;Kelly Robinson&lt;/displayname&gt;
        &lt;username&gt;TheKaptain&lt;/username&gt;
    &lt;/author&gt;
    &lt;closedate&gt;20010101T00::00.0000000&lt;/closedate&gt;
    &lt;createdate&gt;20010101T00::00.0000000&lt;/createdate&gt;
    &lt;creator&gt;
        &lt;displayname&gt;Kelly Robinson&lt;/displayname&gt;
        &lt;username&gt;TheKaptain&lt;/username&gt;
    &lt;/creator&gt;
    &lt;description&gt;
        Test review
    &lt;/description&gt;
    &lt;moderator&gt;
        &lt;displayname&gt;Kelly Robinson&lt;/displayname&gt;
        &lt;username&gt;TheKaptain&lt;/username&gt;
    &lt;/moderator&gt;
    &lt;name&gt;
        Test review
    &lt;/name&gt;
    &lt;permaid&gt;
        &lt;id&gt;CR1&lt;/id&gt;
    &lt;/permaid&gt;
    &lt;projectkey&gt;CR&lt;/projectkey&gt;
    &lt;state&gt;Closed&lt;/state&gt;
    &lt;summary&gt;
      Test review
    &lt;/summary&gt;
&lt;/reviewdata&gt;
</pre>
<p>You can leverage this list as a DataTable model by extracting specific elements from the XML, and providing a sorting mechanism based on dynamic map value lookups.</p>
<pre class="brush: groovy; title: ; notranslate">
    private def createReviewDataJson(HttpServletResponse response, Map params, reviews) {
        def list = []
        response.setHeader(&quot;Cache-Control&quot;, &quot;no-store&quot;)
       //build a List of Maps, one for each row in the DataTable
        reviews.reviewData.each {
            list &lt;&lt; [
                    id: it.permaId.id.text(),
                    author: it.author.displayName.text(),
                    creator: it.creator.displayName.text(),
                    moderator: it.moderator.displayName.text(),
                    description: it.description.text(),
                    state: it.state.text()
            ]
        }
       //sort by the 'order' and 'sort' parameters passed in by DataTable
        switch (params.order) {
            case 'asc':
                list.sort { it.&quot;${params.sort}&quot; } //sort by value where key == params.sort
                break
            case 'desc':
                list.sort {a, b -&gt; b.&quot;${params.sort}&quot; &lt;=&gt; a.&quot;${params.sort}&quot; } //reverse sort by value
                break
        }
       //the entire model
        def data = [totalRecords: list.size(), results: list]
        render data as JSON
    }
</pre>
<p>This model can then be rendered using the <gui :datatable=""> tag. Note that this is pretty much a direct copy of a provided example, nothing fancy here.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;gui:datatable id=&quot;statDataTable&quot; draggablecolumns=&quot;true&quot; columndefs=&quot;[
        [id:'id', sortable:true, resizeable:true],
        [author:'author', sortable:true, resizeable:true],
        [creator:'creator', sortable:true, resizeable:true],
        [moderator:'moderator',  sortable:true, resizeable:true],
        [description:'description', sortable:true, resizeable:true, formatter:'textarea'],
        [state:'state', sortable:true, resizeable:true]
    ]&quot; paginatorconfig=&quot;[
        template:'{PreviousPageLink} {PageLinks} {NextPageLink} {CurrentPageReport}',
        pageReportTemplate:'{totalRecords} total records'
    ]&quot; sortedby=&quot;id&quot; controller=&quot;fisheye&quot; action=&quot;${action}&quot; resultslist=&quot;results&quot; rowsperpage=&quot;10&quot;&gt;
</pre>
<p>So for very little work you get a sortable, paginated DataTable, complete with column resizing and dragging. The DataTable is also being rendered using a template, allowing it to be used arbitrarily by controller methods that populate the model with different reviews. Pretty cool if you ask me. I also used the same backing XML model to drive some PieCharts, but that&#8217;s perhaps a topic for another post.</p>
<p> <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
</gui></p>
<p>Related posts:<ol>
<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/2009/10/24/groovy-reverse-map-sort-done-easy/' rel='bookmark' title='Groovy reverse map sort done easy'>Groovy reverse map sort done easy</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>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/10/25/grails-ui-datatable-using-xml-for-a-model/feed/</wfw:commentRss>
		<slash:comments>0</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>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>The first two chapters of Griffon In Action</title>
		<link>http://www.kellyrob99.com/blog/2009/04/01/the-first-two-chapters-of-griffon-in-action/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-first-two-chapters-of-griffon-in-action</link>
		<comments>http://www.kellyrob99.com/blog/2009/04/01/the-first-two-chapters-of-griffon-in-action/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 06:32:52 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Model-view-controller]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Swing]]></category>
		<category><![CDATA[SwingWorker]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=84</guid>
		<description><![CDATA[Documentation up until now has been sparse to be sure, but judging by the first two chapters of the MEAP for Griffon in Action, this book is going to be worth every penny. I&#8217;ve experimented a bit with Griffon a bit lately, but still being somewhat of a Groovy noob, I don&#8217;t think that the [...]
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/2009/04/03/swingset-on-griffon/' rel='bookmark' title='SwingSet on Griffon'>SwingSet on Griffon</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>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Documentation up until now has been sparse to be sure, but judging by the first two chapters of the <a href="http://www.manning.com/about/meap.html">MEAP</a> for <a href="http://www.manning.com/almiray/">Griffon in Action</a>, this book is going to be worth every penny.</p>
<p>I&#8217;ve experimented a bit with <a class="zem_slink" title="Griffon (framework)" rel="homepage" href="http://groovy.codehaus.org/Griffon">Griffon</a> a bit lately, but still being somewhat of a <a href="http://groovy.codehaus.org/">Groovy</a> noob, I don&#8217;t think that the full impact hit me until I started reading the book. Maybe part of the problem is not that it&#8217;s hard to understand, but that it&#8217;s hard to believe that it&#8217;s so easy.</p>
<p>A very clearly defined way of separating the classic <a class="zem_slink" title="Model-view-controller" rel="wikipedia" href="http://en.wikipedia.org/wiki/Model-view-controller">MVC</a>. Injection of views, models, controllers &#8211; all available by convention not by annotation, xml configuration or even having to a refer to a component by name. The transparent access to a variety of builder actions through plugins makes a large toolset available with little or no cost. Clear architectural boundaries exist that guide you to where your code should be developed. The Griffon framework, created with gracious acknowledgement to its forerunner <a class="zem_slink" title="Grails (framework)" rel="homepage" href="http://grails.org">Grails</a> strives to do one thing above all &#8211; make Swing easy.</p>
<p>The power and versatility of Swing has always been obvious to me. The &#8216;magic sauce&#8217; that makes large scale Java Swing applications behave in any sane way has been a little more hazy. The advent of SwingWorker and other enhancements to the Swing toolset and the availability of better documentation have certainly made the landscape a lot more tolerable, but at the end of the day, it&#8217;s still hard to even find good examples of large Swing apps to use as a guideline(well at least it has been for me.) On the other side of the spectrum, I&#8217;m not sure there IS such a thing as a small Swing app. The amount of boilerplate code required is cumbersame, to say the least, and between anonymous inner classes for actions/listeners and correct handling of business logic and the <a class="zem_slink" title="Event dispatching thread" rel="wikipedia" href="http://en.wikipedia.org/wiki/Event_dispatching_thread">EDT</a> by the time you&#8217;ve finished doing anything moderately significant you&#8217;re already a couple 1000 lines in.</p>
<p>Griffon takes all that and hides it behind a curtain. Expanding on the already powerful SwingBuilder capabilities, it provides a quick and easy way to develop complex Swing applications. Utilizing @Binding to provide easy view/model interaction and baking the Observer pattern right into the framework make it beyond simple to deal with <a class="zem_slink" title="Graphical user interface" rel="wikipedia" href="http://en.wikipedia.org/wiki/Graphical_user_interface">GUI</a> events. And the pattern for dealing with EDT issues couldn&#8217;t be much more straightforward.</p>
<pre class="brush: groovy; title: ; notranslate">

doOutside {
.... do whatever you need to do off of the EDT
doLater { ... come back to the EDT when you're done to update widgets }
}
</pre>
<p>I&#8217;m pretty sure that&#8217;s an easy enough pattern that I will never again forget the cost of doing&#8230; well pretty much anything that takes +1 second while blocking the EDT.</p>
<p>Personally, I&#8217;ve run into a couple of unexpected results when trying to utilize the webstart version of the application, but other than that everything has worked exactly as advertised. And at the end of the day I&#8217;m willing to chalk that up to my misuse of the system. I&#8217;ll tell you for sure when I get to that chapter of the book. Which will probably be about 2 days after the authors publish it.</p>
<p> <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>So far my impression of the pre-release chapters of the book are pretty good &#8211; well written, clear and above all &#8211; the code samples work. Kudos to the authors <a href="http://www.jroller.com/aalmiray/">Andres Almiray</a>,<a href="http://shemnon.com/speling/"> Danno Ferrin</a> and <a href="http://blogs.sun.com/geertjan/">Geertjan Wielenga</a>.&nbsp; Look forward to the rest of the book boys, and to writing some new Swing apps with Griffon!</p>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/07d75949-b8da-4090-a057-6c9c6b02b056/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=07d75949-b8da-4090-a057-6c9c6b02b056" 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/2009/04/03/swingset-on-griffon/' rel='bookmark' title='SwingSet on Griffon'>SwingSet on Griffon</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>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/04/01/the-first-two-chapters-of-griffon-in-action/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Fun day playing with new Stuff</title>
		<link>http://www.kellyrob99.com/blog/2009/03/15/fun-day-playing-with-new-stuff/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=fun-day-playing-with-new-stuff</link>
		<comments>http://www.kellyrob99.com/blog/2009/03/15/fun-day-playing-with-new-stuff/#comments</comments>
		<pubDate>Sun, 15 Mar 2009 19:56:46 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Griffon]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Model-view-controller]]></category>
		<category><![CDATA[Swing]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=50</guid>
		<description><![CDATA[Today was a pretty great day, I must say. I got a chance to work with the brand new Griffon framework and must say &#8211; the combination of clear MVC architecture, Grails style convention over configuration and already powerful plugin selection make it pretty sexy. The early support for cobertura code coverage and fest GUI [...]
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/03/07/playing-with-the-new-grails/' rel='bookmark' title='Playing with the new Grails :)'>Playing with the new Grails :)</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/03/swingset-on-griffon/' rel='bookmark' title='SwingSet on Griffon'>SwingSet on Griffon</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Today was a pretty great day, I must say.</p>
<p>I got a chance to work with the brand new <a class="zem_slink" title="Griffon (framework)" rel="homepage" href="http://groovy.codehaus.org/Griffon">Griffon</a> framework and must say &#8211; the combination of clear <a class="zem_slink" title="Model-view-controller" rel="wikipedia" href="http://en.wikipedia.org/wiki/Model-view-controller">MVC</a> architecture, <a class="zem_slink" title="Grails (framework)" rel="homepage" href="http://grails.org">Grails</a> style convention over configuration and already powerful plugin selection make it pretty sexy.</p>
<p>The early support for cobertura <a class="zem_slink" title="Code coverage" rel="wikipedia" href="http://en.wikipedia.org/wiki/Code_coverage">code coverage</a> and fest <a class="zem_slink" title="GUI software testing" rel="wikipedia" href="http://en.wikipedia.org/wiki/GUI_software_testing">GUI testing</a> are both appealing to any developer that appreciates the need for testing your application.  I&#8217;m still undecided on the Grails-like adoption of storing project information in a &#8220;.griffon&#8221; folder in the user directory and completely outside of the actual project directory structure. With luck, future versions will allow for incorporating maven to handle dependency management and get me past my FUD on that one, something that the latest Grails supports. I haven&#8217;t yet tried that new feature out in Grails out so I&#8217;m not entirely sure how well it works, but the docs say that there is a provided archetype and that all of the familiar Grails targets are <a href="http://www.grails.org/Maven+Integration">mirrored in the maven goals</a>.</p>
<p>Being able to add additional Groovy style builders as plugins is about as transparent as it gets &#8211; install the plugin and you can immediately incorporate that builder anywhere in the application.  The only builder component set that I have had a chance to work with previously is <a href="https://swingx.dev.java.net/">SwingX</a>, but anyone who&#8217;s had the opportunity to use a JXTable in place of the vanilla JTable can immediately see the advantage! And the JDirectoryChooser from <a href="http://www.l2fprod.com/">l2fprod</a> is a powerful alternative to the <a class="zem_slink" title="Swing (Java)" rel="wikipedia" href="http://en.wikipedia.org/wiki/Swing_%28Java%29">Swing</a> built-in JFileChooser.</p>
<p>The crown jewel so far however seems to be  the <a href="http://griffon.codehaus.org/Wizard+Plugin">wizard plugin</a>. This addresses what is  a very common scenario in any process related application:</p>
<ul>
<li> collect User input in a series of steps</li>
<li>validate the input at each step</li>
<li>allow the User  to go back and review or change any inputs</li>
<li>apply all of the input to an underlying business process</li>
<li>provide feedback as to the result</li>
</ul>
<p>The <a href="https://wizard.dev.java.net/">wizard framework</a> worked pretty much as advertised right out of the box and, although the project seems to have stalled (couldn&#8217;t seem to  find any updates since mid-2008) , when integrated so well with Griffon it seems a very good candidate for building lightweight applications &#8211; installers in particular jump to mind.</p>
<p>Any way you look at it &#8211; for a project as newly arrived as Griffon, it&#8217;s already promising to be a very powerful enabler. Thanks to <a href="http://www.jroller.com/aalmiray/">Andres Almiray</a> and everyone else involved in the project. I look forward to using Griffon more in the future.</p>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" title="Zemified by Zemanta" href="http://reblog.zemanta.com/zemified/a8105dd0-7c00-4551-8e80-5731041a87c6/"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=a8105dd0-7c00-4551-8e80-5731041a87c6" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related"><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/03/07/playing-with-the-new-grails/' rel='bookmark' title='Playing with the new Grails :)'>Playing with the new Grails :)</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/03/swingset-on-griffon/' rel='bookmark' title='SwingSet on Griffon'>SwingSet on Griffon</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/03/15/fun-day-playing-with-new-stuff/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

