<?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</title>
	<atom:link href="http://www.kellyrob99.com/blog/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>Mon, 11 Mar 2013 04:37:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Groovy and HTTP Servers</title>
		<link>http://www.kellyrob99.com/blog/2013/03/10/groovy-and-http-servers/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy-and-http-servers</link>
		<comments>http://www.kellyrob99.com/blog/2013/03/10/groovy-and-http-servers/#comments</comments>
		<pubDate>Mon, 11 Mar 2013 04:37:05 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Gradle]]></category>
		<category><![CDATA[Groovlet]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[HTTPBuilder]]></category>
		<category><![CDATA[HttpServer]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Restlet]]></category>
		<category><![CDATA[Spock]]></category>
		<category><![CDATA[theKaptain]]></category>
		<category><![CDATA[vert.x]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=2152</guid>
		<description><![CDATA[This article originally appeared in the January 2013 issue of GroovyMag. There&#8217;s no denying that the World Wide Web has become absolutely integral for information storage and delivery. There are more than 600 million sites serving up over 80 billion individual pages and many more pages and web services being added every day(http://news.netcraft.com/archives/2012/09/10/september-2012-web-server-survey.html). And behind [...]<div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2013/02/10/groovy-and-http/' rel='bookmark' title='Groovy and HTTP'>Groovy and HTTP</a></li>
<li><a href='http://www.kellyrob99.com/blog/2012/05/27/github-social-graphs-with-groovy-and-graphviz/' rel='bookmark' title='GitHub Social Graphs with Groovy and GraphViz'>GitHub Social Graphs with Groovy and GraphViz</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>
</ol>
</div>
]]></description>
			<content:encoded><![CDATA[<p><em>This article originally appeared in the January 2013 issue of <a href="http://www.groovymag.com/">GroovyMag</a>.</em></p>
<blockquote><p>
There&#8217;s no denying that the World Wide Web has become absolutely integral for information storage and delivery. There are more than 600 million sites serving up over 80 billion individual pages and many more pages and web services being added every day(<a href="http://news.netcraft.com/archives/2012/09/10/september-2012-web-server-survey.html" target="_blank">http://news.netcraft.com/archives/2012/09/10/september-2012-web-server-survey.html</a>). And behind each site is – you guessed it! &#8211; a web server. Nowadays we have a large number of JVM web server alternatives for serving up content, and some serious Groovy and polyglot contenders as well. In this article I&#8217;ll detail some of the alternatives with a focus on embeddable options, and describe what Groovy can do to make things easier than traditional Java-only implementation and configuration. We&#8217;ll configure some different servers to host a single service that reverses a  query parameter and returns the result. All of these solutions can be embedded in a Groovy program and require little or no external configuration.<br />
Note: Some of the solutions described are appropriate for a production environment while others are more suitable for smaller tasks like serving documents exclusively for an internal network or providing simple testing environments.
</p></blockquote>
<p></p>
<h2>The test project</h2>
<p>In order to provide an environment for standing up multiple web servers and demonstrating various HTTP requests, we&#8217;ll be using a Gradle build and some simple Spock tests. The full source code is available at <a href="https://github.com/kellyrob99/groovy-http" title="https://github.com/kellyrob99/groovy-http" target="_blank">https://github.com/kellyrob99/groovy-http</a> and I hope you&#8217;ll clone a copy to take a closer look. This is the same project previously used(GroovyMag December 2012) to detail Groovy for working with http clients but expanded to look at the server-side capabilities as well. It includes the Gradle wrapper, so you should be able to check it out and run all tests with a simple invocation of <em>./gradlew build</em>.</p>
<p></p>
<h2>Java 1.6 HttpServer</h2>
<p>The simplest alternative to serve up content with no external library dependencies in Java is the HttpServer included starting in Java 1.6. Standing up a server is extremely simple, requiring no external configuration – or much of anything else really. You simply create the server, declare some contexts(which match to paths) and assign a handler for each context. The entire code in Groovy for configuring the server to host our &#8216;reverse&#8217; service is shown in Listing 1.</p>
<pre class="brush: groovy; title: ; notranslate">
//configuring a Java 6 HttpServer
InetSocketAddress addr = new InetSocketAddress(HTTP_SERVER_PORT)
httpServer = com.sun.net.httpserver.HttpServer.create(addr, 0)
httpServer.with {
    createContext('/', new ReverseHandler())
    createContext('/groovy/', new GroovyReverseHandler())
    setExecutor(Executors.newCachedThreadPool())
    start()
}
</pre>
<p><strong>Listing 1: Configuring an HttpServer in Groovy</strong></p>
<p>
So we&#8217;re binding to a port for incoming requests, assigning a handler for all requests on the root context path, configuring the server with a thread pool and starting it up. The only part we have to supply are the handlers, of which a Java version implementing HttpHandler is shown in Listing 2. All it does is return the single expected &#8216;string&#8217;  parameter in reverse. It also performs some simple error handling in case the parameter is missing and returns an HTTP 400 Bad request code in this case.</p>
<pre class="brush: java; title: ; notranslate">
class ReverseHandler implements HttpHandler {
    @Override
    public void handle(HttpExchange httpExchange) throws IOException
    {
        String requestMethod = httpExchange.getRequestMethod();
        if (requestMethod.equalsIgnoreCase(&quot;GET&quot;)) {
            Headers responseHeaders = httpExchange.getResponseHeaders();
            responseHeaders.set(&quot;Content-Type&quot;, &quot;text/plain&quot;);
            OutputStream responseBody = httpExchange.getResponseBody();

            final String query = httpExchange.getRequestURI().getRawQuery();
            if (query == null || !query.contains(&quot;string&quot;)) {
                httpExchange.sendResponseHeaders(400, 0);
                return;
            }

            final String[] param = query.split(&quot;=&quot;);
            assert param.length == 2 &amp;&amp; param[0].equals(&quot;string&quot;);

            httpExchange.sendResponseHeaders(200, 0);
            responseBody.write(new StringBuffer(param[1]).reverse().toString().getBytes());
            responseBody.close();
        }
    }
}

</pre>
<p><strong>Listing 2: Simple handler for HttpServer requests</strong><br />
</p>
<p>We can make this somewhat less verbose by coding the handler in Groovy(see the <a href="https://github.com/kellyrob99/groovy-http/blob/master/src/main/groovy/org/kar/http/GroovyReverseHandler.groovy" title="GroovyReverseHandler" target="_blank">GroovyReverseHandler</a> in the source code), but the very low level API makes the difference in this example pretty small. More importantly, since we can code both the HttpHandler implementation and the server code into a single Groovy script, we can launch a simple web server from the command line with ease, i.e. groovy server.groovy<br />
You&#8217;re not going to want to use this for hosting an entire web site, but it is perfectly usable for serving up small amounts of content, providing simple services or perhaps mocking up services for testing a client implementation. </p>
<p></p>
<h2>Embedded Jetty</h2>
<p>This  is a complete solution for including all of the power of Jetty within your application. Since Jetty is a Servlet container, we can immediately make use of the GroovyServlet available in the standard Groovy distribution and serve up Groovlets that can be created and modified dynamically at runtime. First, let&#8217;s configure a Jetty 8 server and context to serve files using the GroovyServlet, as shown in Listing 3.</p>
<pre class="brush: groovy; title: ; notranslate">
//configuring Jetty 8 with GroovyServlet support
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS)
context.with {
    contextPath = '/'
    resourceBase = 'src/main/webapp'
    addServlet(GroovyServlet, '*.groovy')
}
jettyServer = new Server(JETTY_SERVER_PORT)
jettyServer.with {
    setHandler(context)
    start()
}
</pre>
<p><strong>Listing 3:  Configuring Jetty 8 with GroovyServlet</strong><br />
</p>
<p>This will serve up any files under the directory src/main/webapp with the suffix .groovy. These files are compiled on the fly and the GroovyServlet detects if the files are modified so that it can recompile them as necessary. For the purpose of our simple &#8216;reverse&#8217; service, the code in Listing 4 shows a  Groovlet implementation. Because within the Groovlet our output is wired into the Servlet output stream, a simple println is sufficient for writing back a limited response. It&#8217;s simple things like this that make you almost forget that you&#8217;re coding a Servlet as so much of the normal boilerplate involved in coding one isn&#8217;t required.</p>
<pre class="brush: groovy; title: ; notranslate">
import javax.servlet.http.HttpServletResponse

final string = request.parameterMap.string
if (!string || string.size() != 1){
    response.setStatus(HttpServletResponse.SC_BAD_REQUEST)
    return
}
print URLDecoder.decode(string[0], 'UTF-8').reverse()
</pre>
<p><strong>Listing 4: Groovlet which returns the passed in parameter in reverse</strong><br />
</p>
<p>Notice that in this case the passed in parameters are unmarshalled for us and available in the request.parameterMap variable. And I hope that you agree this implementation is significantly less verbose and easier to understand that the HttpHandler we defined earlier to do the same thing in Java.<br />
Perhaps more importantly, this entire web server can be defined and executed as a Groovy script with the help of a single @Grab annotation. The full script is shown in Listing 5.</p>
<pre class="brush: groovy; title: ; notranslate">
@Grab('org.eclipse.jetty.aggregate:jetty-all-server:8.1.0.v20120127')
import org.eclipse.jetty.servlet.ServletContextHandler
import groovy.servlet.GroovyServlet
import org.eclipse.jetty.server.Server

int JETTY_SERVER_PORT = 8094
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS)
context.with {
    contextPath = '/'
    resourceBase = 'src/main/webapp'
    addServlet(GroovyServlet, '*.groovy')
}
jettyServer = new Server(JETTY_SERVER_PORT)
jettyServer.with {
    setHandler(context)
    start()
}
</pre>
<p><strong>Listing 5: Groovy script which launches a Jetty web server in under 20 lines</strong><br />
</p>
<p>Jetty is a very versatile server platform and Groovy makes it extremely easy to stand up and work with. The full scope of capabilities is definitely beyond the scope of this article, but if you can do it with Jetty in a plain Java environment, you can do it in Groovy as well – just with less typing <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<p>And with just-Java you would definitely need to configure some extra pieces in order to get going, whereas Groovy can do it using nothing more than the default tools that come along with the distribution(and an internet connection, of course).  If you are in need of a lightweight web server for pretty much any purpose this would be my first suggestion. Oh, and unlike deploying Jetty in a stand-alone fashion, there&#8217;s no XML configuration required – always a bonus in my books.</p>
<p></p>
<h2>Restlet and Groovy-Restlet</h2>
<p><a href="http://www.restlet.org/" target="_blank">Restlet</a> is a platform specifically designed to help build RESTful applications quickly and reliably. I&#8217;m not personally very familiar with it, but having developed and worked with many different REST APIs I definitely appreciate the idea of a framework designed specifically for the use case. Java classes in the Restlet API are mapped directly to the REST concepts, making it very easy to implement the required services while abstracting away any specific protocol being used to communicate between resources. The <a href="http://docs.codehaus.org/display/GROOVY/GroovyRestlet" target="_blank">Groovy-Restlet project</a> adds a DSL built extending Groovy&#8217;s FactoryBuilderSupport class to the equation. In the simplest case, we create a GroovyRestlet object and configure our Restlet system using an external Groovy file expressing the DSL. Listing 6 shows the code used to bootstrap the Restlet application. Notice how we&#8217;re passing in a variable for the port to be used during the script evaluation.</p>
<pre class="brush: groovy; title: ; notranslate">
//configuring a Restlet Server and Client using an external dsl file
GroovyRestlet gr = new GroovyRestlet()
gr.builder.setVariable('port', RESTLET_SERVER_PORT)
(restletClient, restletServer) = gr.build(new File('src/test/resources/restlet/reverseRestlet.groovy').toURI()) as List
</pre>
<p><strong>Listing 6: Initializing a Restlet application in Groovy</strong><br />
</p>
<p>Here we&#8217;re using the Groovy multiple assignment feature so that we can return handles to both the org.restlet.Server and org.restlet.Client objects created in the script. The DSL script  shown in Listing 7 shows how these objects are initialized. This is our &#8216;reverse&#8217; service implemented taking advantage of some of the niceties of Restlet, including easy parameter parsing using the Form abstraction, easy HTTP status handling and the ability to immediately create a matching Client for a Server.</p>
<pre class="brush: groovy; title: ; notranslate">
import org.restlet.data.*

def myPort = builder.getVariable('port')
def server = builder.server(protocol: protocol.HTTP, port: myPort) {
    restlet(handle: {Request req, Response resp -&gt;
        Form form = req.resourceRef.queryAsForm
        if (form.isEmpty() || !form[0].name == 'string') {
            resp.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, &quot;Missing 'string' param&quot;)
        }
        else {
            resp.setEntity(form[0].value.reverse(), mediaType.TEXT_PLAIN)
        }
    })
}
server.start();

def client = builder.client(protocol: protocol.HTTP)

[client, server] //return a list so we can work with the client and eventually stop the server
</pre>
<p><strong>Listing 7: Groovy-Restlet configuration DSL</strong><br />
</p>
<p>We can test the Client behaviour for correct execution and for error conditions using Spock, as shown in Listings 8 and 9 respectively. </p>
<pre class="brush: groovy; title: ; notranslate">
def &quot;restlet reverse test&quot;() {
    when: 'We use the Restlet Client to execute a GET request against the Restlet Server'
    String response = restletClient.get(&quot;http://localhost:$RESTLET_SERVER_PORT/?string=$TEST_STRING&quot;).entity.text

    then: 'We get the same text back in reverse'
    TEST_STRING.reverse() == response
}
</pre>
<p><strong>Listing 8: Executing a GET request with the Restlet Client</strong><br />
</p>
<p>Restlet also exposes some handy methods for inspecting error status and messaging in Listing 9.</p>
<pre class="brush: groovy; title: ; notranslate">
def &quot;restlet failure with client error&quot;() {
    when: 'We forget to include the required parameter to Restlet'
    org.restlet.data.Response response = restletClient.get(&quot;http://localhost:$RESTLET_SERVER_PORT&quot;)

    then: 'An exception is thrown and we get an HTTP 400 response indicated as a client error'
    response.status.isClientError()
    !response.status.isServerError()
    response.status.code == 400
    response.status.description == MISSING_STRING_PARAM
    null == response.entity.text
}
</pre>
<p><strong>Listing 9: Executing a failing GET request with the Restlet Client</strong><br />
</p>
<p>The Groovy-Restlet DSL makes it fairly easy to configure a Restlet application but I wouldn&#8217;t necessarily suggest it for “real world” use. For one thing, it only works with an older version of Restlet, and for another it does not appear to be actively maintained. There&#8217;s a sparsity of documentation available but that&#8217;s not really a problem if you&#8217;re willing to check out and read the very small implementation and available examples. It would be nice to see this project updated to utilize the latest Restlet version, in which case it would be a lot more attractive to keep up with. That said, you can still deploy a complete web server using this all of this technology in a single Groovy script.</p>
<p></p>
<h2>Embedded vert.x</h2>
<p>The vert.x project(http://vertx.io/) describes itself as:</p>
<blockquote><p>
“Vert.x is the framework for the next generation of asynchronous, effortlessly scalable, concurrent applications.<br />
Vert.x is an event driven application framework that runs on the JVM &#8211; a run-time with real concurrency and unrivaled performance. Vert.x then exposes the API in Ruby, Java, Groovy, JavaScript and Python. So you choose what language you want to use. Scala and Clojure support is on the roadmap too.”
</p></blockquote>
<p>Essentially vert.x provides a <a href="http://en.wikipedia.org/wiki/Reactor_pattern" target="_blank">Reactor pattern</a> based server platform that supports polyglot programming at its lowest level. It has also been touted as a JVM polyglot alternative to Node.js. You can install vert.x locally and then use its command line program vertx to load specifications from files written in Groovy, JavaScript, Ruby and other languages. Or you can embed the library in the JVM program of choice and configure it directly in code. For Groovy at least, the syntax is almost identical and looks like that shown in Listing 10 for configuring a org.vertx.groovy.core.http.HttpServer object.</p>
<pre class="brush: groovy; title: ; notranslate">
Vertx vertx = Vertx.newVertx()
final org.vertx.groovy.core.http.HttpServer server = vertx.createHttpServer()
server.requestHandler { HttpClientRequest req -&gt;
    if (req.params['string'] == null) {
        req.response.with {
            statusCode = 400
            statusMessage = MISSING_STRING_PARAM
            end()
        }
    }
    else {
        req.response.end(req.params['string'].reverse())
    }

}.listen(VERTX_PORT, 'localhost')
</pre>
<p><strong>Listing 10: Configuring a vert.x HttpServer in Groovy</strong><br />
</p>
<p>Vert.x will automatically unmarshall parameters into a Map for us, and the HttpClientRequest class used in the handler provides access to a variety of convenience method for interacting with both the request and response objects.<br />
Creating a org.vertx.groovy.core.http.HttpClient object is even easier and demonstrated in Listing 11.</p>
<pre class="brush: groovy; title: ; notranslate">
def client = vertx.createHttpClient(port: VERTX_PORT, host: 'localhost')
</pre>
<p><strong>Listing 11: One liner to create a vert.x HttpClient in Groovy</strong><br />
</p>
<p>Interacting with this client is very easy and again provides convenience methods for dealing with the response, including buffering the returned data. It should be noted that in this particular example we&#8217;re negating that last benefit by calling toString() on the returned buffer for convenience. Assertions are embedded in the code in Listing 12 as I&#8217;m pulling it directly from a Spock test exercising the vert.x client.</p>
<pre class="brush: groovy; title: ; notranslate">
client.getNow(&quot;/&quot;) { resp -&gt;
    400 == resp.statusCode
    MISSING_STRING_PARAM == resp.statusMessage
}

client.getNow(&quot;/?string=$TEST_STRING&quot;) { resp -&gt;
    200 == resp.statusCode
    resp.dataHandler { buffer -&gt;
        TEST_STRING.reverse() == buffer.toString()
    }
}
</pre>
<p><strong>Listing 12: Exercising GET requests for passing and failing conditions using a vert.x Client in a Spock test</strong><br />
</p>
<p>This is pretty much the simplest possible example, and really doesn&#8217;t do a good job of showing off the features of vert.x. The platform boasts a public repository for sharing and accessing modules, a built in event bus for communicating internally and externally and a concurrency model that allows you to forget about synchronizing code and concentrate on business logic – among other things. Asynchronous servers like this and node.js are almost certainly going to continue playing a bigger part on the internet with the enormous increase in web service usage. They provide some answers to classic scaling problems, and are a very natural fit with newer technology requirements like WebSockets.</p>
<p><em>Note that since vert.x depends on the asynchronous NIO features in Java 7, it will only work with Java versions higher than 1.7</em></p>
<p></p>
<h2>Other alternatives</h2>
<p>This is hardly an exhaustive list of the web server platforms nowadays supporting Groovy and/or polyglot capabilities. Some others include:</p>
<ul>
<li>Graffitti is inspired by the Ruby Sinatra server and implemented entirely in Groovy. The project is hosted at <a href="https://github.com/webdevwilson/graffiti" target="_blank">https://github.com/webdevwilson/graffiti</a></li>
<li>Ratpack is again a Groovy port of the Sinatra server. The project is hosted at <a href="https://github.com/tlberglund/Ratpack" target="_blank">https://github.com/tlberglund/Ratpack</a></li>
<li>The Google App Engine can be used to serve up Servlets/Groovlets and the Gaelyk framework greatly simplifies interacting with the available Google services. Gaelyk is hosted at <a href="https://github.com/gaelyk/gaelyk" target="_blank">https://github.com/gaelyk/gaelyk</a></li>
<li>Gretty is a very promising Groovy wrapper around the Java Netty(<a href="https://netty.io/" target="_blank">https://netty.io/</a>) server, providing a DSL for simplified declaration and configuration of Netty components. Unfortunately this project appears largely dormant and does not appear to work with newer versions of Groovy. The code is hosted at <a href="https://github.com/groovypp/gretty" target="_blank">https://github.com/groovypp/gretty</a>. Vert.x also employs Netty under the hood to get things done.</li>
</ul>
<p>As usual, anything you can get done in Java you can also get done in Groovy. We&#8217;ve covered a few of the available options for creating and interacting with a variety of open source web servers that run on the JVM. More and more there is support for polyglot programming on the JVM, and hopefully this article has given you some ideas for using Groovy to help you be more productive with web server development. In particular, where a particular platform provides a fluent interface or DSL(like Groovy-Restlet and vert.x do) for configuration the benefits are immediately apparent. For me personally, the main benefits can be summarized as:</p>
<ul>
<li>less code to maintain due to basic Groovy syntactic sugar for common functions and availability of DSLs to create expressive code in a terse fashion</li>
<li>removal of the need for XML configuration common in most web server deployment environments </li>
<li>ability to encapsulate all functionality into a single script for deployment, depending only on having Groovy available to run the script</li>
</ul>
<p>Please give some of these ideas a try, and I would love to hear back from you regarding your own experiences using Groovy and HTTP.</p>
<p></p>
<h2>Learn more</h2>
<ul>
<li>The size of the web today on <a href="http://news.netcraft.com/archives/2012/09/10/september-2012-web-server-survey.html" target="_blank">http://news.netcraft.com/archives/2012/09/10/september-2012-web-server-survey.html</a></li>
<li>A comparison of reactor based servers on <a href="http://blog.andrewvc.com/vertx-node-on-ropes" target="_blank">http://blog.andrewvc.com/vertx-node-on-ropes</a></li>
<li>
A great roundup of alternative servers you can use with Groovy at <a href="http://theholyjava.wordpress.com/2012/04/04/exposing-functionality-over-http-with-groovy-and-ultra-lightweight-http-servers/" target="_blank">http://theholyjava.wordpress.com/2012/04/04/exposing-functionality-over-http-with-groovy-and-ultra-lightweight-http-servers/</a>
	</li>
<li>Groovy-Restlet <a href="http://code.google.com/p/groovy-restlet/wiki/RestletTutorialExample" target="_blank">http://code.google.com/p/groovy-restlet/wiki/RestletTutorialExample</a></li>
<li>vert.x
<ul>
<li><a href="http://vertx.io" target="_blank">http://vertx.io</a>/</li>
<li><a href="http://vertx.io/groovy_web_tutorial.html" target="_blank">http://vertx.io/groovy_web_tutorial.html</a></li>
</ul>
</li>
<li>Gretty
<ul>
<li><a href="http://groovy.dzone.com/articles/512000-concurrent-websockets" target="_blank">http://groovy.dzone.com/articles/512000-concurrent-websockets</a></li>
<li><a href="https://github.com/groovypp/gretty" target="_blank">https://github.com/groovypp/gretty</a></li>
</ul>
</li>
<li>Netty
<ul>
<li><a href="http://michaelangela.wordpress.com/2009/12/14/simpler-java-asynch-io/" target="_blank">http://michaelangela.wordpress.com/2009/12/14/simpler-java-asynch-io/</a> </li>
<li><a href="http://seeallhearall.blogspot.ca/2012/06/netty-tutorial-part-15-on-channel.html" target="_blank">http://seeallhearall.blogspot.ca/2012/06/netty-tutorial-part-15-on-channel.html</a></li>
</ul>
</li>
<li>Jetty + Groovlets
<ul>
<li><a href="http://www.redtoad.ca/ataylor/2012/02/simple-servlets-in-groovy/" target="_blank">http://www.redtoad.ca/ataylor/2012/02/simple-servlets-in-groovy/</a></li>
<li><a href="http://mrhaki.blogspot.ca/2009/10/groovy-goodness-groovlets-as.html" target="_blank">http://mrhaki.blogspot.ca/2009/10/groovy-goodness-groovlets-as.html</a></li>
</ul>
</li>
<li>HttpServer related
<ul>
<li><a href="http://docs.oracle.com/javase/6/docs/jre/api/net/httpserver/spec/index.html" target="_blank">http://docs.oracle.com/javase/6/docs/jre/api/net/httpserver/spec/index.html</a></li>
<li><a href="http://josefbetancourt.wordpress.com/2011/04/10/embedded-httpserver-groovy-app/" target="_blank">http://josefbetancourt.wordpress.com/2011/04/10/embedded-httpserver-groovy-app/</a></li>
<li><a href="http://alistairisrael.wordpress.com/2009/09/02/functional-http-testing-with-sun-java-6-httpserver/" target="_blank">http://alistairisrael.wordpress.com/2009/09/02/functional-http-testing-with-sun-java-6-httpserver/</a></li>
</ul>
</li>
</ul>
<!-- 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><div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2013/02/10/groovy-and-http/' rel='bookmark' title='Groovy and HTTP'>Groovy and HTTP</a></li>
<li><a href='http://www.kellyrob99.com/blog/2012/05/27/github-social-graphs-with-groovy-and-graphviz/' rel='bookmark' title='GitHub Social Graphs with Groovy and GraphViz'>GitHub Social Graphs with Groovy and GraphViz</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>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2013/03/10/groovy-and-http-servers/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Groovy and HTTP</title>
		<link>http://www.kellyrob99.com/blog/2013/02/10/groovy-and-http/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy-and-http</link>
		<comments>http://www.kellyrob99.com/blog/2013/02/10/groovy-and-http/#comments</comments>
		<pubDate>Sun, 10 Feb 2013 17:31:49 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Gradle]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[HTTPBuilder]]></category>
		<category><![CDATA[HttpClient]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Spock]]></category>
		<category><![CDATA[theKaptain]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=2075</guid>
		<description><![CDATA[This article originally appeared in the December 2012 issue of GroovyMag. Some different ways that Groovy makes interacting with the web easier One of the major benefits of Groovy is how it simplifies some of the common scenarios we deal with in Java. Complex code with conditionals, error handling and many other concerns can be [...]<div class='yarpp-related-rss'>

Related posts:<ol>
<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/2012/05/27/github-social-graphs-with-groovy-and-graphviz/' rel='bookmark' title='GitHub Social Graphs with Groovy and GraphViz'>GitHub Social Graphs with Groovy and GraphViz</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>
</ol>
</div>
]]></description>
			<content:encoded><![CDATA[<p><em>This article originally appeared in the December 2012 issue of <a href="http://www.groovymag.com/">GroovyMag</a>.</em></p>
<h1>Some different ways that Groovy makes interacting with the web easier</h1>
<blockquote><p>
One of the major benefits of Groovy is how it simplifies some of the common scenarios we deal with in Java. Complex code with conditionals, error handling and many other concerns can be expressed in a very concise and easily understandable fashion. This article will touch on some convenient Groovy-isms related to interacting with content over HTTP. First we&#8217;ll look at some of the syntactic sugar added to the standard Java classes that simplify GET and POST requests, and then we&#8217;ll take a look at how the <a href="http://groovy.codehaus.org/modules/http-builder/" title="HTTPBuilder" target="_blank">HTTPBuilder</a> module provides a DSL for using the <a href="http://hc.apache.org/httpclient-3.x/" title="HttpClient" target="_blank">HttpClient</a> library.
</p></blockquote>
<p></p>
<h2>The test project</h2>
<p>In order to provide an environment for putting up a website and demonstrating various HTTP requests, we&#8217;ll be using the Gradle Jetty plugin and some simple <a href="http://groovy.codehaus.org/Groovlets" title="Groovlets" target="_blank">Groovlets</a>. The full source code is available at <a href="https://github.com/kellyrob99/groovy-http" title="https://github.com/kellyrob99/groovy-http" target="_blank">https://github.com/kellyrob99/groovy-http</a> and I hope you&#8217;ll clone a copy to take a closer look. The simple index page contains the &#8216;hello world&#8217; content shown in Listing 1.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Groovy HTTP&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;hello world&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p><strong>Listing 1: Our &#8216;hello world&#8217; index page used for testing</strong></p>
<p>We&#8217;ll start with the simplest available methods for interacting with HTTP using Groovy and no additional library support.</p>
<p></p>
<h2>Groovy methods added to String and URL</h2>
<p>The <a href="http://groovy.codehaus.org/api/org/codehaus/groovy/runtime/DefaultGroovyMethods.html" title="DefaultGroovyMethods" target="_blank">DefaultGroovyMethods</a> class provides a couple of very handy methods to enhance the default operation of the String and URL classes. In particular for String we have a new toURL() method and, for URL, the text property. In addition, the URL class is enhanced with convenience methods for working with associated InputStream and OutputStreams.</p>
<p></p>
<h3>String.toURL()</h3>
<p>This is a small gain as all you&#8217;re really doing is avoiding a call to new <a href="http://docs.oracle.com/javase/6/docs/api/java/net/URL.html#URL%28java.lang.String%29" title="URLConstructor" target="_blank">URL(String spec)</a>.  The difference in keystrokes isn&#8217;t large but, combined with some other MetaClass benefits of Groovy, it can be very helpful for creating fluent and easily understandable code.</p>
<p></p>
<h3>URL.text()</h3>
<p>This seemingly small addition to the API of the URL class abstracts away a lot of the usual boilerplate involved in streaming content over a <a href="http://docs.oracle.com/javase/6/docs/api/java/net/URLConnection.html" title="URLConnection" target="_blank">URLConnection</a>. Underneath the hood is a very sensible implementation that buffers the underlying connection and automatically handles the closing of all resources for you. For most use cases the default behaviour is likely to be sufficient but, if not, there are overloaded URL.text(String charset) and URL.text(Map parameters, String charset) methods that allow for modification and handle more specifics of the connection configuration.<br />
The one line invocation in Listing 2 demonstrates how to load an html page, returning the raw html as a String.</p>
<pre class="brush: groovy; title: ; notranslate">
String html = 'http://localhost:8081/groovy-http'.toURL().text
</pre>
<p><strong>Listing 2: One liner to initiate an HTTP GET request for an html page</strong></p>
<p>There&#8217;s still a lot that could go wrong using this shorthand syntax for an HTTP request, as several exceptions might be thrown depending on whether or not the url is correctly formatted, or if the content specified doesn&#8217;t exist. The <a href="http://code.google.com/p/spock/" title="Spock" target="_blank">Spock</a> test shown in Listing 3 exercises both of these conditions. Note that a 404 response will result in a FileNotFoundException.</p>
<pre class="brush: groovy; title: ; notranslate">
@Unroll(&quot;The url #url should throw an exception of type #exception&quot;)
def &quot;exceptions can be thrown converting a String to URL and accessing the text&quot;() {
    when:
    String html = url.toURL().text

    then:
    def e = thrown(exception)

    where:
    url                          | exception
    'htp://foo.com'              | MalformedURLException
    'http://google.com/notThere' | FileNotFoundException
}
</pre>
<p><strong>Listing 3: Spock test showing some possible failure conditions for our GET request</strong></p>
<p>For comparison let&#8217;s take a look at what the same GET request looks like using a URL in Java, shown in Listing 4.</p>
<pre class="brush: java; title: ; notranslate">
URL html = new URL('http://localhost:8081/groovy-http/index.html');
URLConnection urlConnection = html.openConnection();
BufferedReader reader = new BufferedReader(
	new InputStreamReader(urlConnection.getInputStream()));
StringBuffer response = new StringBuffer();
String inputLine;
while ((inputLine = reader.readLine()) != null)
{
	response.append(inputLine)
}
reader.close();
</pre>
<p><strong>Listing 4: The Java version of reading from a URLConnection (based on the canonical example from Oracle.com)</strong></p>
<p>There&#8217;s still no error handling in place in the Java version which is obviously a much more verbose way to load the same data.</p>
<p></p>
<h3>POST with URL streams</h3>
<p>Similarly to simplifying GET requests, executing a POST using Groovy can take advantage of some of the enhancements to common Java classes. In particular, simplified stream handling allows for tight, correct and expressive coding. Listing 5 shows a Spock test configuring the URLConnection, POSTing some data and reading back the result from the connection.</p>
<pre class="brush: groovy; title: ; notranslate">
private static final String POST_RESPONSE = 'Successfully posted [arg:[foo]] with method POST'    

def &quot;POST from a URLConnection&quot;() {
    when:
    final HttpURLConnection connection = makeURL('post.groovy').toURL().openConnection()
    connection.setDoOutput(true)
    connection.outputStream.withWriter { Writer writer -&gt;
        writer &lt;&lt; &quot;arg=foo&quot;
    }

    String response = connection.inputStream.withReader { Reader reader -&gt; reader.text }

    then:
    connection.responseCode == HttpServletResponse.SC_OK
    response == POST_RESPONSE
}
</pre>
<p><strong>Listing 5: POST request using Groovy and a URLConnection</strong></p>
<p>Notice that we don&#8217;t have to explicitly cast the connection to <a href="http://docs.oracle.com/javase/6/docs/api/java/net/HttpURLConnection.html" title="HttpUrlConnection" target="_blank">HttpUrlConnection</a> in order to get the responseCode back, and that we don&#8217;t have to explicitly close any of the streams used. Also, we don&#8217;t need to create local variables for the Reader/Writer object as we would have to in Java; similarly no calls to &#8216;new&#8217; are required, as Object creation is all hidden behind the convenience methods. The equivalent Java code requires four calls to new and two to close(), as well as much more involved code for extracting the result. The canonical example of how to do this in Java can be seen on <a href="http://docs.oracle.com/javase/tutorial/networking/urls/readingWriting.html" title="http://docs.oracle.com/javase/tutorial/networking/urls/readingWriting.html" target="_blank">http://docs.oracle.com/javase/tutorial/networking/urls/readingWriting.html<br />
</a><br />
Note that you can also parse response content very easily using the <a href="http://groovy.codehaus.org/api/groovy/util/XmlSlurper.html" title="XmlSlurper" target="_blank">XmlSlurper</a> / <a href="http://groovy.codehaus.org/api/groovy/util/XmlParser.html" title="XmlParser" target="_blank">XmlParser</a> and <a href="http://groovy.codehaus.org/gapi/groovy/json/JsonSlurper.html" title="JsonSlurper" target="_blank">JsonSlurper</a> classes included in the standard Groovy distribution.</p>
<p></p>
<h2>HttpClient and HTTPBuilder make things even easier</h2>
<p>The reality is that in most modern Java applications developers have some nice alternatives to directly working with URL and URLConnection objects for working with HTTP. One of the more popular libraries available is HttpClient and its successor <a href="http://hc.apache.org/" title="HttpComponents" target="_blank">HttpComponents</a>. Wrappers for all of the HTTP verbs are provided which simplifies configuration, execution and consumption of responses. Listing 6 shows a Spock test using HttpClient and mirroring our prior GET examples.</p>
<pre class="brush: groovy; title: ; notranslate">
def &quot;HttpClient example in Java&quot;() {
    when:
    HttpClient httpclient = new DefaultHttpClient();
    HttpGet httpget = new HttpGet(makeURL(&quot;helloWorld.groovy&quot;));
    ResponseHandler&lt;String&gt; responseHandler = new BasicResponseHandler();
    String responseBody = httpclient.execute(httpget, responseHandler);

    then:
    responseBody == HELLO_WORLD_HTML
}
</pre>
<p><strong>Listing 6: HttpClient GET example</strong></p>
<p>This can be further reduced if there is no need for keeping the intermediate variables around. In fact, we can get it down to the single line shown in Listing 7.</p>
<pre class="brush: groovy; title: ; notranslate">
String response = new DefaultHttpClient().execute(new HttpGet(makeURL(&quot;helloWorld.groovy&quot;)), new BasicResponseHandler())
</pre>
<p><strong>Listing 7: HttpClient GET one-liner</strong></p>
<p>This is obviously a lot easier on the eyes and very clear in intent. The HttpClient library also has convenience mechanisms for declaring common behaviour across connections, an API for providing custom response parsing implementations and automatic handling for (most of) the underlying resource streams and connections. For those of us using Groovy, there&#8217;s a nice wrapper for HttpClient called HTTPBuilder that adds a DSL-style configuration mechanism and some very nice features in terms of error handling and content parsing. Listing 8 shows our standard GET example again, this time working against an object called http assigned from <em>new HTTPBuilder(Object uri)</em>. Note that we&#8217;re using Groovy&#8217;s multiple assignment feature to return and assign multiple values from our Closure.</p>
<pre class="brush: groovy; title: ; notranslate">
def &quot;GET with HTTPBuilder&quot;() {
    when:
    def (html, responseStatus) = http.get(path: 'helloWorld.groovy', contentType: TEXT) { resp, reader -&gt;
        [reader.text, resp.status]
    }

    then:
    responseStatus == HttpServletResponse.SC_OK
    html == HELLO_WORLD_HTML
}
</pre>
<p><strong>Listing 8: Spock test showing Groovy HTTPBuilder GET support</strong></p>
<p>If you noticed in Listing 8 I explicitly set the request with <em>contentType: TEXT</em>, it&#8217;s because HTTPBuilder by default provides automatic response content type detection and parsing. Since I&#8217;m requesting an xml document, HTTPBuilder can automatically parse the result with Groovy&#8217;s XmlSlurper. HTTPBuilder can also detect that it is an html page and pass the response through NekoHTML first to ensure that you&#8217;re working with a well-formed document. Listing 9 shows the slight difference in how we could interact with the parsed response content and the reader in our Closure from Listing 8 is quietly replaced with a GPathResult referring to the parsed content.</p>
<pre class="brush: groovy; title: ; notranslate">
def &quot;GET with HTTPBuilder and automatic parsing&quot;() {
    when:
    def (html, responseStatus) = http.get(path: 'helloWorld.groovy') { resp, reader -&gt;
        [reader, resp.status]
    }

    then:
    responseStatus == HttpServletResponse.SC_OK
    html instanceof GPathResult
    html.BODY.P.text() == 'hello world'
}
</pre>
<p><strong>Listing 9: automatic detection and parsing of xml </strong></p>
<p>It&#8217;s unlikely that you&#8217;re going to be parsing a lot of html this way but with the abundance of xml services available nowadays automated parsing can be very helpful. The same applies for JSON and if we give a hint as to the contentType we can get back a parsed JSONObject when interacting with such services as shown in Listing 10.</p>
<pre class="brush: groovy; title: ; notranslate">
def &quot;GET with HTTPBuilder and automatic JSON parsing&quot;() {
    when:
    def (json, responseStatus) = http.get(path: 'indexJson.groovy', contentType: JSON) { resp, reader -&gt;
        [reader, resp.status]
    }

    then:
    responseStatus == HttpServletResponse.SC_OK
    json instanceof JSONObject
    json.html.body.p == 'hello world'
}
</pre>
<p><strong>Listing 10: automatic parsing of JSON responses</strong></p>
<p>The HTTPBuilder module also has some convenience methods for handling failure conditions. By allowing for specifying both default failure handlers and specific behaviour for individual requests you&#8217;ve got lots of options at your disposal. Listing 11 shows how to define a default failure handler that simply traps the response code. Note that the Closure used for hading GET response is never run since in this case the page we&#8217;re requesting results in an HTTP 404 Not Found response code.</p>
<pre class="brush: groovy; title: ; notranslate">
def &quot;GET with HTTPBuilder and error handling&quot;() {
    when:
    int responseStatus
    http.handler.failure = { resp -&gt;
        responseStatus = resp.status
    }
    http.get(path: 'notThere.groovy', contentType: TEXT) { resp, reader -&gt;
        throw new IllegalStateException('should not be executed')
    }

    then:
    responseStatus == HttpServletResponse.SC_NOT_FOUND
}
</pre>
<p><strong>Listing 11: Defining a failure handler with HTTPBuilder</strong></p>
<p>POSTing data with HTTPBuilder is also very straightforward, requiring only an additional body parameter as shown in Listing 12.</p>
<pre class="brush: groovy; title: ; notranslate">
def &quot;POST with HTTPBuilder&quot;() {
    when:
    def (response, responseStatus) = http.post(path: 'post.groovy', body: [arg: 'foo']) { resp, reader -&gt;
        [reader.text(),resp.status]
    }

    then:
    responseStatus == HttpServletResponse.SC_OK
    response == POST_RESPONSE
}
</pre>
<p><strong>Listing 12: POST using HTTPBuilder</strong></p>
<p>HTTPBuilder also provides some more specific abstractions for dealing with certain scenarios. There&#8217;s RESTClient for dealing with RESTful webservices in a simplified manner, there&#8217;s AsyncHTTPBuilder for asynchronously executing requests and for the Google App Engine, which doesn&#8217;t allow socket based connections, there&#8217;s the HttpURLClient which wraps HttpUrlConnection usage.</p>
<p></p>
<h2>Conclusion</h2>
<p>Hopefully this has given you a taste for what Groovy can do to help you with HTTP interactions and gives you some ideas for making your own HTTP client applications a bit Groovier.</p>
<p></p>
<h2>More reading</h2>
<ul>
<li><a href="http://docs.oracle.com/javase/tutorial/networking/urls/readingWriting.html" target="_blank">http://docs.oracle.com/javase/tutorial/networking/urls/readingWriting.html</a></li>
<li><a href="http://docs.oracle.com/javase/tutorial/networking/urls/readingWriting.html" target="_blank">http://stackoverflow.com/questions/2793150/how-to-use-java-net-urlconnection-to-fire-and-handle-http-requests</a></li>
<li>The HTTPBuilder website <a href="http://groovy.codehaus.org/modules/http-builder/" target="_blank">http://groovy.codehaus.org/modules/http-builder/</a></li>
<li>The HttpComponents website <a href="http://hc.apache.org/index.html" target="_blank">http://hc.apache.org/index.html</a></li>
<li>The source code that goes along with this article on github at <a href="https://github.com/kellyrob99/groovy-http" target="_blank">https://github.com/kellyrob99/groovy-http</a>. This project includes the Gradle wrapper so you should be able to just clone the repository and start using it without installing any additional software(other than Java, of course). You can run all of the tests with ./gradlew clean build and you can start the webserver with ./gradlew jettyRun</li>
</ul>
<p>Next month we&#8217;ll take a closer look at how Groovy can simplify working with a variety of embedded http server alternatives &#8211; see you then!</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<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/2012/05/27/github-social-graphs-with-groovy-and-graphviz/' rel='bookmark' title='GitHub Social Graphs with Groovy and GraphViz'>GitHub Social Graphs with Groovy and GraphViz</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>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2013/02/10/groovy-and-http/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Kuler iTerm2 Themes with Groovy Scripting</title>
		<link>http://www.kellyrob99.com/blog/2012/12/08/kuler-iterm2-themes-with-groovy-scripting/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=kuler-iterm2-themes-with-groovy-scripting</link>
		<comments>http://www.kellyrob99.com/blog/2012/12/08/kuler-iterm2-themes-with-groovy-scripting/#comments</comments>
		<pubDate>Sat, 08 Dec 2012 18:22:00 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[iTerm]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[kuler]]></category>
		<category><![CDATA[Open source]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[StreamingMarkupBuilder]]></category>
		<category><![CDATA[SwingBuilder]]></category>
		<category><![CDATA[theKaptain]]></category>
		<category><![CDATA[XmlSlurper]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=2036</guid>
		<description><![CDATA[Having recently purchased a new MBP laptop, I was going through the usual new computer activities and installing one of my favorite apps, the iTerm2 terminal program. This program really shines for managing multiple terminal windows, and recently they added the ability to easily import and export color themes for sharing. I, of course, got [...]<div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/' rel='bookmark' title='Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code'>Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/14/groovy-and-bash-can-scripting-get-much-easier/' rel='bookmark' title='Groovy and Bash &#8211; can scripting get much easier?'>Groovy and Bash &#8211; can scripting get much easier?</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/10/more-griffonfest-testing/' rel='bookmark' title='More Groovy/Griffon/FEST Testing'>More Groovy/Griffon/FEST Testing</a></li>
</ol>
</div>
]]></description>
			<content:encoded><![CDATA[<p>Having recently purchased a new MBP laptop, I was going through the usual new computer activities and installing one of my favorite apps, the <a href="http://www.iterm2.com">iTerm2</a> terminal program. This program really shines for managing multiple terminal windows, and recently they added the ability to easily <a href="http://code.google.com/p/iterm2/wiki/ColorGallery">import and export color themes for sharing</a>. I, of course, got immediately distracted with a shiny new feature and ended up spending an afternoon writing some code to try it out. Along the way I grabbed some color themes from the <a href="http://kuler.adobe.com">Adobe Kuler site</a>, built a quick and dirty SwingBuilder script to visualize the themes and wrote a script for emitting <a href="https://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man5/plist.5.html">Apple plist files</a> suitable for import into iTerm2. </p>
<h2>Adobe Kuler</h2>
<p>This is a nice resource for finding and building color themes primarily intended for web consumption. Each theme boils down to five colors represented as hexadecimal which can be applied to a layout design in a fairly predictable pattern. In addition to using the website directly, <a href="http://learn.adobe.com/wiki/display/kulerdev/B.+Feeds">RSS feeds</a> are made available for accessing shared themes. This makes grabbing a handful of themes for experimentation very easy to accomplish with the Groovy XmlSlurper.</p>
<p>Here&#8217;s an excerpt of the RSS feed we&#8217;re parsing, representing a five color theme named &#8216;Feeling Etsy&#8217;.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;item&gt;
      &lt;title&gt;Theme Title: Feeling Etsy&lt;/title&gt;
      &lt;link&gt;http://kuler.adobe.com/index.cfm#themeID/1892986&lt;/link&gt;
      &lt;guid&gt;http://kuler.adobe.com/index.cfm#themeID/1892986&lt;/guid&gt;
      &lt;enclosure xmlns=&quot;http://www.solitude.dk/syndication/enclosures/&quot;&gt;
        &lt;title&gt;Feeling Etsy&lt;/title&gt;
        &lt;link length=&quot;1&quot; type=&quot;image/png&quot;&gt;
          &lt;url&gt;http://kuler-api.adobe.com/kuler/themeImages/theme_1892986.png&lt;/url&gt;
        &lt;/link&gt;
      &lt;/enclosure&gt;
      &lt;description&gt;
				 &amp;lt;img src=&quot;http://kuler-api.adobe.com/kuler/themeImages/theme_1892986.png&quot; /&amp;gt;&amp;lt;br /&amp;gt;
				 
				 Artist: kenzia.studio&amp;lt;br /&amp;gt;
				 ThemeID: 1892986&amp;lt;br /&amp;gt;
				 Posted: 05/02/2012&amp;lt;br /&amp;gt;
				 
					 Tags: 
					 community...., join, lifestyle, share, vintage
				 &amp;lt;br /&amp;gt;	
				 
					Hex:
					DCEBDD, A0D5D6, 789AA1, 304345, AD9A27&lt;/description&gt;

...
</pre>
<p>And <a href="https://gist.github.com/2945511">here&#8217;s parsing code</a> that queries for 100 of the &#8216;top rated&#8217; and 100 of the &#8216;popular&#8217; themes, serializing them out to a Groovy script file. There&#8217;s going to be some overlap in these two sets, so the end result is somewhat less than 200 themes.</p>
<pre class="brush: groovy; title: ; notranslate">
/**
 * Reads RSS feeds from kuler and extracts the hexadecimal representation of each five element theme, writing those
 * values to a file.
 */
def feeds = [
        new URL(&quot;http://kuler-api.adobe.com/feeds/rss/get.cfm?itemsPerPage=100&amp;listType=rating&quot;),
        new URL(&quot;http://kuler-api.adobe.com/feeds/rss/get.cfm?itemsPerPage=100&amp;listType=popular&quot;)
]
def mappedThemes = [:]
def slurp = {rssXML, themes -&gt;
    def xml = new XmlSlurper().parseText(rssXML)
    xml.channel.item.each { theme -&gt;
        println theme.title
        def desc = theme.description.toString().split('\n')
        def hex = desc[-1]
        hex = hex.replaceAll('\t', '')
        hex = hex.replaceAll(' ', '')
        themes.put(theme.title.toString().replaceAll('Theme Title:', '').trim().replaceAll(' ', '_')
                .replaceAll('\'', '_').toLowerCase(), hex.split(','))
    }
}

feeds.each { URL url -&gt;
    slurp(url.text, mappedThemes)
}

println mappedThemes.keySet().size()

def themeMapFile = new File(&quot;kulerThemeMap-${new Date().format('yyMMddHHmmss')}.groovy&quot;)
themeMapFile &lt;&lt; &quot;themeMap = ${mappedThemes.inspect()}&quot;
themeMapFile.absolutePath
</pre>
<p>The end result is a Groovy script file containing a single Map type variable named &#8216;themeMap&#8217; in the global scope. This file can be interpreted by a GroovyShell to extract the Map of themes easily &#8211; not the best way to serialize the data but I actually wrote this parsing code a couple of years back and just wanted to quickly incorporate it into today&#8217;s efforts so I left it as is. </p>
<p>Output in the file is just a Map of the theme name to the five corresponding hexadecimal color codes.</p>
<pre class="brush: groovy; title: ; notranslate">
themeMap = ['pie_party__for_all_kulerist!!!':['690011', 'BF0426', 'CC2738', 'F2D99C', 'E5B96F'],
 'pear_lemon_fizz':['04BFBF', 'CAFCD8', 'F7E967', 'A9CF54', '588F27'],
 'feeling_etsy':['DCEBDD', 'A0D5D6', '789AA1', '304345', 'AD9A27'],
 'phaedra':['FF6138', 'FFFF9D', 'BEEB9F', '79BD8F', '00A388'], 
...
</pre>
<h2>Visualizing the Themes</h2>
<p>In order to see which of these themes might look OK in iTerm I wrote a SwingBuilder script that reads in the script file output from the last step, like so:</p>
<pre class="brush: groovy; title: ; notranslate">
assert args.size() == 1, '''The name or path to a file containing a themeMap 
script variable must be supplied on the command line'''

def themeMapFileName = args[0]
Binding binding = new Binding()
new GroovyShell(binding).evaluate(new File(themeMapFileName))
assert binding.hasVariable('themeMap'), &quot;${args[0]} file must contain a Map variable named themeMap&quot;
def themeMap = binding.themeMap as TreeMap
</pre>
<p>The Swing app just has a simple 2 column layout to display the name of the theme on the left and colored labels for each of the theme colors. Looks like this:</p>

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/kuler-iterm2-themes-with-groovy-scripting/kulerthemevisualization.png" title="" class="shutterset_singlepic94" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/94_watermark_900x450_kulerthemevisualization.png" alt="kulerthemevisualization" title="kulerthemevisualization" />
</a>

<p>Having worked on Swing apps in plain-Jane Java professionally before, I&#8217;m still always astounded at how much less code you can write with Groovy and SwingBuilder. Here&#8217;s the 30 lines it takes to do the GUI and here&#8217;s <a href="https://gist.github.com/2945613">the full file on github</a>.</p>
<pre class="brush: groovy; title: ; notranslate">
def swing = new groovy.swing.SwingBuilder()
def mainPanel = swing.panel() {
    boxLayout(axis: javax.swing.BoxLayout.Y_AXIS)
    label(text: &quot;Showing ${themeMap.size()} themes&quot;)
    scrollPane() {
        panel() {
            boxLayout(axis: javax.swing.BoxLayout.Y_AXIS)
            themeMap.each { key, value -&gt;
                panel(border:  emptyBorder(3)) {
                    gridLayout(columns: 2, rows: 1)
                    label(text: key)
                    value.each {
                        def color = Color.decode(&quot;#&quot; + it)
                        int colorSize = 50
                        label(opaque: true, toolTipText: it, background: color, foreground: color,
                                preferredSize: [colorSize, colorSize] as Dimension,
                                border: lineBorder(color:Color.WHITE, thickness:1))
                    }
                }
            }
        }
    }
}
def frame = swing.frame(title: 'Frame') {
    scrollPane(constraints: SwingConstants.CENTER) {
        widget(mainPanel)
    }
}
frame.pack()
frame.show()
</pre>
<h2>Creating the iTerm plist Files</h2>
<p>The iTerm color presets define some &#8216;Basic Colors&#8217; and some &#8216;ANSI Colors&#8217;. The basic ones cover: Foreground, Background, Bold, Selection, Selected Text, Cursor and Cursor Text. Seeing as we&#8217;ve got seven of these to map to five colors, I&#8217;ve(arbitrarily) chosen to make the Cursor and Cursor Text values depend upon the Foreground and Background colors, plus a fixed increment value. Here&#8217;s a picture to help explain.</p>

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/kuler-iterm2-themes-with-groovy-scripting/feelingetsykulertheme_0.png" title="" class="shutterset_singlepic95" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/95_watermark_750x450_feelingetsykulertheme_0.png" alt="feelingetsykulertheme_0" title="feelingetsykulertheme_0" />
</a>

<p>And here is the configuration screen for this new profile in iTerm.</p>

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/kuler-iterm2-themes-with-groovy-scripting/itermprofileconfiguration.png" title="" class="shutterset_singlepic96" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/96_watermark_750x450_itermprofileconfiguration.png" alt="itermprofileconfiguration" title="itermprofileconfiguration" />
</a>

<p>Each of the ANSI colors maps a standard color onto our color scheme and provides &#8216;Normal&#8217; and &#8216;Bright&#8217; variations for each color. I&#8217;ve (again arbitrarily) decided to map each of these by randomly selecting a color from the theme and determining a &#8216;Bright&#8217; version of it. This leads to some themes where colors won&#8217;t show up very well if there is a conflict with the &#8216;Basic&#8217; colors but it&#8217;s sufficient for my use case. In the end we want to write out an xml file for each theme which looks something like this:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;plist version=&quot;1.0&quot;&gt;
  &lt;dict&gt;
    &lt;key&gt;Ansi 0 Color&lt;/key&gt;
    &lt;dict&gt;
      &lt;key&gt;Blue Component&lt;/key&gt;
      &lt;real&gt;0.2705882353&lt;/real&gt;
      &lt;key&gt;Green Component&lt;/key&gt;
      &lt;real&gt;0.2627450980&lt;/real&gt;
      &lt;key&gt;Red Component&lt;/key&gt;
      &lt;real&gt;0.1882352941&lt;/real&gt;
    &lt;/dict&gt;
    &lt;key&gt;Ansi 8 Color&lt;/key&gt;
    &lt;dict&gt;
...
</pre>
<p>This repeating structure is easy to create using Groovy&#8217;s built in xml functionality. Because we want to include the DOCTYPE and xml header, I&#8217;m using StreamingMarkupBuilder and it&#8217;s handy <em>yieldUnescaped</em> function. Full source code is <a href="https://gist.github.com/2945752">available on github</a>, but here&#8217;s the bit which generates the two ANSI color definitions shown in the xml above.</p>
<pre class="brush: groovy; title: ; notranslate">
final Closure buildColors = { builder, Color color -&gt;
    builder.dict {
        key('Blue Component')
        real(normalize(color.blue))
        key('Green Component')
        real(normalize(color.green))
        key('Red Component')
        real(normalize(color.red))
    }
}

final Closure buildComponentColors = { builder, colors, i -&gt;
    final hex = colors

    //Normal
    final Color color = extractColor(hex)
    builder.key(&quot;Ansi $i Color&quot;)
    buildColors(builder, color)

    //Bright
    final Color brighterColor = color.brighter()
    builder.key(&quot;Ansi ${i + 8} Color&quot;)
    buildColors(builder, brighterColor)
}
</pre>
<p>Each theme results in a PLIST xml file ready to import into iTerm. </p>
<h1>Conclusion</h1>
<p>I continue to be impressed with how easy Groovy makes it to solve common programming problems. Within a very small space of time I was able to:</p>
<ul>
<li>parse multiple RSS feeds</li>
<li>create a Swing application to visualize results</li>
<li>transform the previously parsed results into an xml document usable in iTerm</li>
<li>do it all in a couple of hundred lines of code</li>
<li>publish the individual scripts on github</li>
</ul>
<p>Hopefully this gives you some ideas on how to do some Groovy hacking of your own. I know it was a fun afternoon for me <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/' rel='bookmark' title='Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code'>Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/14/groovy-and-bash-can-scripting-get-much-easier/' rel='bookmark' title='Groovy and Bash &#8211; can scripting get much easier?'>Groovy and Bash &#8211; can scripting get much easier?</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/10/more-griffonfest-testing/' rel='bookmark' title='More Groovy/Griffon/FEST Testing'>More Groovy/Griffon/FEST Testing</a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2012/12/08/kuler-iterm2-themes-with-groovy-scripting/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>GitHub Social Graphs with Groovy and GraphViz</title>
		<link>http://www.kellyrob99.com/blog/2012/05/27/github-social-graphs-with-groovy-and-graphviz/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=github-social-graphs-with-groovy-and-graphviz</link>
		<comments>http://www.kellyrob99.com/blog/2012/05/27/github-social-graphs-with-groovy-and-graphviz/#comments</comments>
		<pubDate>Sun, 27 May 2012 19:11:32 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[GAE]]></category>
		<category><![CDATA[Gaelyk]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[GitHub API]]></category>
		<category><![CDATA[Google App Engine]]></category>
		<category><![CDATA[GPars]]></category>
		<category><![CDATA[Gradle]]></category>
		<category><![CDATA[Graphviz]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[HTTPBuilder]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[Open source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1933</guid>
		<description><![CDATA[The Goal Using the GitHub API, Groovy and GraphViz to determine, interpret and render a graph of the relationships between GitHub users based on the watchers of their repositories. The end result can look something like this. The GitHub V3 API You can find the full documentation for the GitHub V3 API here. They do [...]<div class='yarpp-related-rss'>

Related posts:<ol>
<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/2011/03/27/hooking-into-the-jenkinshudson-api/' rel='bookmark' title='Hooking into the Jenkins(Hudson) API'>Hooking into the Jenkins(Hudson) API</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/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>
</ol>
</div>
]]></description>
			<content:encoded><![CDATA[<h2>The Goal</h2>
<p>Using the <a href="http://develop.github.com/">GitHub API</a>, <a href="http://groovy.codehaus.org/">Groovy</a> and <a href="http://www.graphviz.org/">GraphViz</a> to determine, interpret and render a graph of the relationships between GitHub users based on the watchers of their repositories. The end result can look something like this.</p>

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/amandasblueandyellow-dot_-twopi-1024.png" title="Twopi layout with randomly assigned node colors." class="shutterset_singlepic81" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/81_watermark_900x450_amandasblueandyellow-dot_-twopi-1024.png" alt="amandasblueandyellow-dot_-twopi-1024" title="amandasblueandyellow-dot_-twopi-1024" />
</a>

<h2>The GitHub V3 API</h2>
<p>You can find the full documentation for the GitHub V3 API <a href="http://developer.github.com/v3/">here</a>. They do a great job of documenting the various endpoints and their behaviour as well as demonstrating usage of the API extensively with <a href="http://curl.haxx.se/">curl</a>. For the purposes of this post the API calls I&#8217;m making are simple GET requests that do not require authentication. In particular I&#8217;m targeting two specific endpoints: <a href="http://developer.github.com/v3/repos/">repositories for a specific user</a> and <a href="http://developer.github.com/v3/repos/watching/">watchers for a repository</a>. </p>
<h3>Limitations of the API</h3>
<p>Although a huge upgrade from the 50 requests per hour rate limit on the V2 API, I found it fairly easy to exhaust the 5000 requests per hour provided by the V3 API while gathering data. Fortunately, included with every response from GitHub is a convenient <strong><a href="http://developer.github.com/v3/#rate-limiting">X-RateLimit-Remaining</a></strong> header we can use to check our limit. This allows us to stop processing before we run out of requests, after which GitHub will return errors for every request. For each user we examine one url to find their repositories, and for each of those repositories execute a separate request to find all of the watchers. While executing these requests, using my own GitHub account as the centerpoint, I was able to gather repository information about 1143 users and find 31142 total watchers- 18023 of which were unique in the data collected. This is somewhat of a broken figure as consistently, after reaching the rate limit, there were far more nodes left to process in the queue than already encountered. Myself I only have 31 total repository watchers but appearing within the graph we find users like <a href="https://github.com/igrigorik">igrigorik</a>, an employee of Google with 529 repository watchers, and that tends to skew the results somewhat. The end result is that the data provided here is far from complete, I&#8217;m sorry to say, but that doesn&#8217;t mean it&#8217;s not interesting to visualize.</p>
<h2>Groovy and HttpBuilder</h2>
<p>Groovy and the <a href="http://groovy.codehaus.org/HTTP+Builder">HttpBuilder</a> dsl abstract away most of the details of handling the HTTP connections. The graph I&#8217;m building starts with one central GitHub user and links that user to everyone that is presently watching one of their repositories. This requires a single GET request to load all of the repositories for the given user, and a GET request per repository to find the watchers. These two HTTP operations are very easily encapsulated with Closures using the HttpBuilder wrapper around HttpClient. Each call returns both the <strong>X-RateLimit-Remaining</strong> value and the requested data. Here&#8217;s what the configuration of HttpBuilder looks like:</p>
<pre class="brush: groovy; title: ; notranslate">
final String rootUrl = 'https://api.github.com'
final HTTPBuilder builder = new HTTPBuilder(rootUrl)
</pre>
<p>The builder object is created and fixed at the GitHub api url, simplifying the syntax for future calls. Now we define two closures, each of which targets a specific url and extracts the appropriate data from the (already automagically unmarshalled by HttpBuilder) JSON response. The <strong>findWatchers</strong> Closure has a little bit more logic in it to remove duplicate entries, and to exclude the user themselves from the list as by default GitHub records a self-referential link for all users with their own repositories.</p>
<pre class="brush: groovy; title: ; notranslate">
final String RATE_LIMIT_HEADER = 'X-RateLimit-Remaining'
final Closure findReposForUser = { HTTPBuilder http, username -&gt;
    http.get(path: &quot;/users/$username/repos&quot;, contentType: JSON) { resp, json -&gt;
        return [resp.headers[RATE_LIMIT_HEADER].value as int, json.toList()]
    }
}
final Closure findWatchers = { HTTPBuilder http, username, repo -&gt;
    http.get(path: &quot;/repos/$username/$repo/watchers&quot;, contentType: JSON) { resp, json -&gt;
        return [resp.headers[RATE_LIMIT_HEADER].value as int, json.toList()*.login.flatten().unique() - username]
    }
}
</pre>
<p>Out of this data we&#8217;re only interested (for now) in keeping a simple map of Username -> Watchers which we can easily marshal as a JSON object and store in a file. The complete Groovy script code for loading the data can be run from the command line using the following code or executed remotely from a GitHub gist on the command line by calling <em>groovy https://raw.github.com/gist/2468052/5d536c5a35154defb5614bed78b325eeadbdc1a7/repos.groovy {username}</em>. In either case you should pass in the username you would like to center the graph on. The results will be output to a file called &#8216;reposOutput.json&#8217; in the working directory. Please be patient, as this is going to take a little while; progress is output to the console as each user is processed so you can follow along.</p>
<pre class="brush: groovy; title: ; notranslate">
@Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.5.2')
import groovy.json.JsonBuilder
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.ContentType.JSON

final rootUser = args[0]
final String RATE_LIMIT_HEADER = 'X-RateLimit-Remaining'
final String rootUrl = 'https://api.github.com'
final Closure&lt;Boolean&gt; hasWatchers = {it.watchers &gt; 1}
final Closure findReposForUser = { HTTPBuilder http, username -&gt;
    http.get(path: &quot;/users/$username/repos&quot;, contentType: JSON) { resp, json -&gt;
        return [resp.headers[RATE_LIMIT_HEADER].value as int, json.toList()]
    }
}
final Closure findWatchers = { HTTPBuilder http, username, repo -&gt;
    http.get(path: &quot;/repos/$username/$repo/watchers&quot;, contentType: JSON) { resp, json -&gt;
        return [resp.headers[RATE_LIMIT_HEADER].value as int, json.toList()*.login.flatten().unique() - username]
    }
}

LinkedList nodes = [rootUser] as LinkedList
Map&lt;String, List&gt; usersToRepos = [:]
Map&lt;String, List&lt;String&gt;&gt; watcherMap = [:]
boolean hasRemainingCalls = true
final HTTPBuilder builder = new HTTPBuilder(rootUrl)
while(!nodes.isEmpty() &amp;&amp; hasRemainingCalls)
{
    String username = nodes.remove()
    println &quot;processing $username&quot;
    println &quot;remaining nodes = ${nodes.size()}&quot;

    def remainingApiCalls, repos, watchers
    (remainingApiCalls, repos) = findReposForUser(builder, username)
    usersToRepos[username] = repos
    hasRemainingCalls = remainingApiCalls &gt; 300
    repos.findAll(hasWatchers).each{ repo -&gt;
        (remainingApiCalls, watchers) =  findWatchers(builder, username, repo.name)
        def oldValue = watcherMap.get(username, [] as LinkedHashSet)
        oldValue.addAll(watchers)
        watcherMap[username] =  oldValue
        nodes.addAll(watchers)
        nodes.removeAll(watcherMap.keySet())
        hasRemainingCalls = remainingApiCalls &gt; 300
    }
    if(!hasRemainingCalls)
    {
        println &quot;Stopped with $remainingApiCalls api calls left.&quot;
        println &quot;Still have not processed ${nodes.size()} users.&quot;
    }
}

new File('reposOutput.json').withWriter {writer -&gt;
    writer &lt;&lt; new JsonBuilder(watcherMap).toPrettyString()
}
</pre>
<p>The JSON file contains very simple data that looks like this:</p>
<blockquote>
<pre>
    "bmuschko": [
        "claymccoy",
        "AskDrCatcher",
        "roycef",
        "btilford",
        "madsloen",
        "phaggood",
        "jpelgrim",
        "mrdanparker",
        "rahimhirani",
        "seymores",
        "AlBaker",
        "david-resnick", ...
</pre>
</blockquote>
<p>Now we need to take this data and turn it into a representation that GraphViz can understand. We're also going to add information about the number of watchers for each user and a link back to their GitHub page.</p>
<h2>Generating a GraphViz file in dot format</h2>
<p><a href="http://www.graphviz.org/">GraphViz</a> is a popular framework for generating graphs. The cornerstone of this is a simple format for describing a directed graph in a simple text file(commonly referred to as a 'dot' file) combined with a variety of different layouts for displaying the graph. For the purposes of this post, I'm after describing the following for inclusion in the graph:</p>
<ul>
<li>An edge from each watcher to the user whose repository they are watching.</li>
<li>A label on each node which includes the user's name and the count of watchers for all of their repositories.</li>
<li>An embedded HTML link to the user's GitHub page on each node.</li>
<li>Highlighting the starting user in the graph by coloring that node red.</li>
<li>Assigning a 'rank' attribute to nodes that links all users with the same number of watchers.</li>
</ul>
<p>The script I'm using to create the 'dot' file is pretty much just brute force string processing and the full source code is <a href="https://gist.github.com/2475460">available as a gist</a>, but here are the interesting parts. First, loading in the JSON file that was output in the last step; converting it to a map structure is very simple:</p>
<pre class="brush: groovy; title: ; notranslate">
def data
new File(filename).withReader {reader -&gt;
   data = new JsonSlurper().parse(reader)
}
</pre>
<p>From this data structure we can extract particular details and group everything by the number of watchers per user.</p>
<pre class="brush: groovy; title: ; notranslate">
println &quot;Number of mapped users = ${data.size()}&quot;
println &quot;Number of watchers = ${data.values().flatten().size()}&quot;
println &quot;Number of unique watchers = ${data.values().flatten().unique().size()}&quot;

//group the data by the number of watchers
final Map groupedData = data.groupBy {it.value.size()}.sort {-it.key}
final Set allWatchers = data.collect {it.value}.flatten()
final Set allUsernames = data.keySet()
final Set leafNodes = allWatchers - allUsernames
</pre>
<p>Given this data, we create individual nodes with styling details like so:</p>
<pre class="brush: groovy; title: ; notranslate">
    StringWriter writer = new StringWriter()
    groupedUsers.each {count, users -&gt;
        users.each { username, watchers -&gt;
            def user = &quot;\t\&quot;$username\&quot;&quot;
            def attrs = generateNodeAttrsMemoized(username, count)
            def rootAttrs = &quot;fillcolor=red style=filled $attrs&quot;
            if (username == rootUser) {
                writer &lt;&lt; &quot;$user [$rootAttrs];\n&quot;
            } else {
                writer &lt;&lt; &quot;$user [$attrs ${extraAttrsMemoized(count, username)}];\n&quot;
            }
        }
    }
</pre>
<p>And this generates node and edge descriptions that look like this:</p>
<blockquote>
<pre>
     ...
     	"gyurisc" [label="gyurisc = 31" URL="https://github.com/gyurisc" ];
	"kellyrob99" [fillcolor=red style=filled label="kellyrob99 = 31" 
                      URL="https://github.com/kellyrob99"];
     ...
	"JulianDevilleSmith" -> "cfxram";
	"rhyolight" -> "aalmiray";
	"kellyrob99" -> "aalmiray";
     ...
</pre>
</blockquote>
<p>If you created the JSON data already, you can run this command in the same directory in order to generate the GraphViz dot file: <em>groovy https://raw.github.com/gist/2475460/78642d81dd9bc95f099e0f96c3d87389a1ef6967/githubWatcherDigraphGenerator.groovy {username} reposOutput.json</em>. This will create a file named &#8216;reposDigraph.dot&#8217; in that directory. From there the last step is to interpret the graph definition into an image.</p>
<h2>Turning a &#8216;dot&#8217; file into an image</h2>
<p>I was looking for a quick and easy way to generate multiple visualizations from the same model quickly for comparison and settled on using GPars to generate them concurrently. We have to be a little careful here as some of the layout/format combinations can require a fair bit of memory and CPU &#8211; in the worst cases as much as 2GB of memory and processing times in the range of an hour. My recommendation is to stick with the sfdp and twopi(see the <a href="http://www.graphviz.org/Documentation.php">online documentation here</a>) layouts for graphs of similar size to the one described here. If you&#8217;re after a huge, stunning graphic with complete detail, expect a png image to weigh in somewhere north of 150MB whereas the corresponding svg file will be less than 10MB. This Groovy script depends on having the GraphViz command line &#8216;dot&#8217; executable already installed, exercises six of the available layout algorithms and generates png and svn files using four concurrently.</p>
<pre class="brush: groovy; title: ; notranslate">
import groovyx.gpars.GParsPool

def inputfile = args[0]
def layouts = [ 'dot', 'neato', 'twopi', 'sfdp', 'osage', 'circo' ] //NOTE some of these will fail to process large graphs
def formats = [ 'png', 'svg']
def combinations = [layouts, formats].combinations()

GParsPool.withPool(4) {
    combinations.eachParallel { combination -&gt;
        String layout = combination[0]
        String format = combination[1]
        List args = [ '/usr/local/bin/dot', &quot;-K$layout&quot;, '-Goverlap=prism', '-Goverlap_scaling=-10', &quot;-T$format&quot;,
                '-o', &quot;${inputfile}.${layout}.$format&quot;, inputfile ]
        println args
        final Process execute = args.execute()
        execute.waitFor()
        println execute.exitValue()
    }
}

</pre>
<p>Here&#8217;s a gallery with some examples of the images created and scaled down to be web friendly. The full size graphs I generated using this data weighed in as large as 300MB for a single PNG file. The SVG format takes up significantly less space but still more than 10MB. I also had trouble finding a viewer for the SVG format that was a) capable of showing the large graph in a navigable way and b) didn&#8217;t crash my browser due to memory usage.<br />

<div class="ngg-galleryoverview" id="ngg-gallery-16-1933">

	<!-- Slideshow link -->
	<div class="slideshowlink">
		<a class="slideshowlink" href="http://www.kellyrob99.com/blog/2012/05/27/github-social-graphs-with-groovy-and-graphviz/?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=16&amp;mode=gallery'});">
			[View with PicLens]		</a>
	</div>
	
	<!-- Thumbnails -->
		
	<div id="ngg-image-81" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/amandasblueandyellow-dot_-twopi-1024.png" title="Twopi layout with randomly assigned node colors." class="shutterset_set_16" >
								<img title="amandasblueandyellow-dot_-twopi-1024" alt="amandasblueandyellow-dot_-twopi-1024" src="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/thumbs/thumbs_amandasblueandyellow-dot_-twopi-1024.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-82" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/circo-1024.png" title="Circo layout" class="shutterset_set_16" >
								<img title="circo-1024" alt="circo-1024" src="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/thumbs/thumbs_circo-1024.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-83" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/neato-1024.png" title="Neato layout" class="shutterset_set_16" >
								<img title="neato-1024" alt="neato-1024" src="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/thumbs/thumbs_neato-1024.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-84" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/reposdigraph-dot_-neato-1024.png" title="Neato layout on larger graph" class="shutterset_set_16" >
								<img title="reposdigraph-dot_-neato-1024" alt="reposdigraph-dot_-neato-1024" src="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/thumbs/thumbs_reposdigraph-dot_-neato-1024.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-85" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/reposdigraph-dot_-osage-1024.png" title="Osage layout, poor for a graph this size" class="shutterset_set_16" >
								<img title="reposdigraph-dot_-osage-1024" alt="reposdigraph-dot_-osage-1024" src="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/thumbs/thumbs_reposdigraph-dot_-osage-1024.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-86" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/reposdigraph-dot_-sfdp-1024.png" title="Sfdp layout on larger graph, which it is specialized for." class="shutterset_set_16" >
								<img title="reposdigraph-dot_-sfdp-1024" alt="reposdigraph-dot_-sfdp-1024" src="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/thumbs/thumbs_reposdigraph-dot_-sfdp-1024.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-87" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/reposdigraph-dot_-twopi-1024.png" title="Twopi layout on larger graph." class="shutterset_set_16" >
								<img title="reposdigraph-dot_-twopi-1024" alt="reposdigraph-dot_-twopi-1024" src="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/thumbs/thumbs_reposdigraph-dot_-twopi-1024.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-88" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/sfdp-1024.png" title="Sfdp layout" class="shutterset_set_16" >
								<img title="sfdp-1024" alt="sfdp-1024" src="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/thumbs/thumbs_sfdp-1024.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-89" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/stabledot-1024.png" title="Dot layout" class="shutterset_set_16" >
								<img title="stabledot-1024" alt="stabledot-1024" src="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/thumbs/thumbs_stabledot-1024.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-90" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/stablesfdp-1024.png" title="Sfdp layout" class="shutterset_set_16" >
								<img title="stablesfdp-1024" alt="stablesfdp-1024" src="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/thumbs/thumbs_stablesfdp-1024.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-91" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/stabletwopi-1024.png" title="Twopi layout" class="shutterset_set_16" >
								<img title="stabletwopi-1024" alt="stabletwopi-1024" src="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/thumbs/thumbs_stabletwopi-1024.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-92" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/twopi-1024.png" title="Twopi layout" class="shutterset_set_16" >
								<img title="twopi-1024" alt="twopi-1024" src="http://www.kellyrob99.com/blog/wp-content/gallery/githubsocialgraphs/thumbs/thumbs_twopi-1024.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 	 	
	<!-- Pagination -->
 	<div class='ngg-clear'></div>
 	
</div>

</p>
<h2>And just for fun <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </h2>
<p>Originally I had intended to publish this functionality as an application on the <a href="https://developers.google.com/appengine/">Google App Engine</a> using <a href="http://gaelyk.appspot.com/">Gaelyk</a>, but since the API limit would make it suitable for pretty much one request per hour, and likely get me in trouble with GitHub, I ended up foregoing that bit. But along the way I developed a very simple page that will load all of the publicly available <a href="https://gist.github.com/">Gists</a> for a particular user and display them in a table. This is a pretty clean example of how you can whip up a quick and dirty application and make it publicly available using GAE + Gaelyk. This involved setting up the infrastructure using the <a href="https://github.com/bmuschko/gradle-gaelyk-plugin">gradle-gaelyk-plugin</a> combined with the <a href="https://github.com/bmuschko/gradle-gae-plugin">gradle-gae-plugin</a>, and using Gradle to build, test and deploy the app to the web- all told about an hour&#8217;s worth of effort. Try this link to load up all of my publicly available Gists- replace the username parameter if you&#8217;d like to check out somebody else. Please give it a second as GAE will undeploy the application if it hasn&#8217;t been requested in awhile, so the first call can take a few seconds.<br />
<a href="http://publicgists.appspot.com/gist?username=kellyrob99" title="display public gists for a specific user using the V3 API" target="_blank">http://publicgists.appspot.com/gist?username=kellyrob99</a></p>
<p>Here&#8217;s the <a href="http://groovy.codehaus.org/Groovlets">Groovlet</a> implementation that loads the data and then forwards to the template page. </p>
<pre class="brush: groovy; title: ; notranslate">
def username =  request.getParameter('username') ?: 'kellyrob99'
def text = &quot;https://gist.github.com/api/v1/json/gists/$username&quot;.toURL().text
log.info text
request.setAttribute('rawJSON', text)
request.setAttribute('username', username)

forward '/WEB-INF/pages/gist.gtpl'
</pre>
<p>And the accompanying template page which renders a simple tabular view of the API request.</p>
<pre class="brush: groovy; title: ; notranslate">
&lt;% include '/WEB-INF/includes/header.gtpl' %&gt;
&lt;% import groovy.json.JsonSlurper %&gt;
&lt;%
   def gistMap = new JsonSlurper().parseText(request['rawJSON'])
%&gt;
&lt;h1&gt;Public Gists for username : ${request['username']} &lt;/h1&gt;

&lt;p&gt;
    &lt;table class = &quot;gridtable&quot;&gt;
        &lt;th&gt;Description&lt;/th&gt;
        &lt;th&gt;Web page&lt;/th&gt;
        &lt;th&gt;Repo&lt;/th&gt;
        &lt;th&gt;Owner&lt;/th&gt;
        &lt;th&gt;Files&lt;/th&gt;
        &lt;th&gt;Created at&lt;/th&gt;
        &lt;%
        gistMap.gists.each { data -&gt;
            def repo = data.repo
        %&gt;
            &lt;tr&gt;
                &lt;td&gt;${data.description ?: ''}&lt;/td&gt;
                &lt;td&gt;
                    &lt;a href=&quot;https://gist.github.com/${repo}&quot;&gt;${repo}&lt;/a&gt;
                &lt;/td&gt;
                &lt;td&gt;
                    &lt;a href= &quot;git://gist.github.com/${repo}.git&quot;&gt;${repo}&lt;/a&gt;
                &lt;/td&gt;
                &lt;td&gt;${data.owner}&lt;/td&gt;
                &lt;td&gt;${data.files}&lt;/td&gt;
                &lt;td&gt;${data.created_at}&lt;/td&gt;
            &lt;/tr&gt;
        &lt;% } %&gt;
    &lt;/table&gt;
&lt;/p&gt;
&lt;% include '/WEB-INF/includes/footer.gtpl' %&gt;
</pre>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<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/2011/03/27/hooking-into-the-jenkinshudson-api/' rel='bookmark' title='Hooking into the Jenkins(Hudson) API'>Hooking into the Jenkins(Hudson) API</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/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>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2012/05/27/github-social-graphs-with-groovy-and-graphviz/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JFreeChart with Groovy and Apache POI</title>
		<link>http://www.kellyrob99.com/blog/2012/03/18/jfreechart-with-groovy-and-apache-poi/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=jfreechart-with-groovy-and-apache-poi</link>
		<comments>http://www.kellyrob99.com/blog/2012/03/18/jfreechart-with-groovy-and-apache-poi/#comments</comments>
		<pubDate>Mon, 19 Mar 2012 01:50:09 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[builders]]></category>
		<category><![CDATA[ChartBuilder]]></category>
		<category><![CDATA[DSL]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[ExcelBuilder]]></category>
		<category><![CDATA[Gradle]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[JFreeChart]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[MarkupBuilder]]></category>
		<category><![CDATA[Office]]></category>
		<category><![CDATA[theKaptain]]></category>
		<category><![CDATA[visualization]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1845</guid>
		<description><![CDATA[The point of this article is to show you how to parse data from an Excel spreadsheet that looks like this: and turn it into a series of graphs that look like this: Recently I was looking for an opportunity to get some practice with JFreeChart and ended up looking at a dataset released by [...]<div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2012/05/27/github-social-graphs-with-groovy-and-graphviz/' rel='bookmark' title='GitHub Social Graphs with Groovy and GraphViz'>GitHub Social Graphs with Groovy and GraphViz</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>
<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>
</ol>
</div>
]]></description>
			<content:encoded><![CDATA[<p>The point of this article is to show you how to parse data from an Excel spreadsheet that looks like this:</p>

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/apache-poi-with-groovy-and-jfreechart/excelheaders.png" title="" class="shutterset_singlepic78" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/78_watermark_700x400_excelheaders.png" alt="excelheaders" title="excelheaders" />
</a>

<p>and turn it into a series of graphs that look like this:</p>

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/apache-poi-with-groovy-and-jfreechart/naturalresourcescanadanewseedlings-total-ca.png" title="" class="shutterset_singlepic79" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/79_watermark_700x400_naturalresourcescanadanewseedlings-total-ca.png" alt="naturalresourcescanadanewseedlings-total-ca" title="naturalresourcescanadanewseedlings-total-ca" />
</a>

<p>Recently I was looking for an opportunity to get some practice with JFreeChart and ended up looking at a dataset released by the Canadian government as part of their <a href="http://www.data.gc.ca">&#8216;Open Data&#8217; initiative</a>.</p>
<p>The particular set of data is entitled <a href="http://www.data.gc.ca/default.asp?lang=En&#038;n=5175A6F0-1&#038;xsl=datacataloguerecord&#038;xml=5175A6F0-61E1-49FC-8E5D-0BBCDAF5969D&#038;formid=F2E3F796-9AF1-4237-8C5B-10456B12ACF3&#038;showfromadmin=1&#038;readonly=true">&#8216;Number of Seedlings Planted by Ownership, Species&#8217;</a> and is delivered as an Excel spreadsheet, hence the need for the <a href="http://poi.apache.org/">Apache POI</a> library in order to read the data in. As is fairly usual, at least in my experience, the Excel spreadsheet is designed primarily for human consumption which adds a degree of complexity to the parsing. Fortunately the spreadsheet does follow a repetitive pattern that can be accounted for fairly easily, so this is not insurmountable. Still, we want to get the data out of Excel to make it more approachable for machine consumption so the first step is to convert it to a JSON representation. Once it is in this much more transportable form we can readily convert the data into graph visualizations using JFreeChart.</p>
<h2>The spreadsheet format</h2>
<p>Excel as a workplace tool is very well established, can increase individual productivity and is definitely a boon to your average office worker. The problem is that once the data is there it&#8217;s often trapped there. Data tends to be laid out based on human aesthetics and not on parsability, meaning that unless you want to use Excel itself to do further analysis, there&#8217;s not a lot of options. Exports to more neutral formats like csv suffer from the same problems- namely that there&#8217;s no way to read in the data coherently without designing a custom parser. In this particular case, parsing the spreadsheet has to take into account the following:</p>
<ul>
<li>Merged cells where one column is meant to represent a fixed value for a number of sequential rows.</li>
<li>Column headers that do not represent all of the actual columns. Here we have a &#8216;notes&#8217; column for each province that immediately follows its&#8217; data column. As the header cells are merged across both of these columns, they cannot be used directly to parse the data.</li>
<li>Data is broken down into several domains that lead to repetitions in the format.</li>
<li>The data contains a mix of numbers where results are available and text where they are not. The meanings of the text entries are described in a table at the end of the spreadsheet.</li>
<li>Section titles and headers are repeated throughout the document, apparently trying to match some print layout, or perhaps just trying to provide some assistance to those scrolling through the long document.</li>
</ul>
<p>Data in the spreadsheet is first divided into reporting by Provincial crown land, private land, Federal land, and finally a total for all of them.</p>
<p>Within each of these sections, data is reported for each tree species on a yearly basis across all Provinces and Territories along with aggregate totals of these figures across Canada.</p>
<p>Each of these species data-tables has an identical row/column structure which allows us to create a single parsing structure sufficient for reading in data from each of them separately.</p>
<h2>Converting the spreadsheet to JSON</h2>
<p>For parsing the Excel document, I&#8217;m using the Apache POI library and a Groovy wrapper class to assist in processing. The wrapper class is very simple but allows us to abstract most of the mechanics of dealing with the Excel document away. The full source is available on <a href="http://www.technipelago.se/content/technipelago/blog/44">this blog post from author Goran Ehrsson</a>. The key benefit is the ability to specify a window of the file to process based on &#8216;offset&#8217; and &#8216;max&#8217; parameters provided in a simple map. Here&#8217;s an example for reading data for the text symbols table at the end of the spreadsheet.</p>
<p>We define a Map which states which sheet to read from, which line to start on(offset) and how many lines to process. The ExcelBuilder class(which isn&#8217;t really a builder at all) takes in the path to a File object and under the hood reads that into a <a href="http://poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/HSSFWorkbook.html">POI HSSFWorkbook</a> which is then referenced by the call to the <em>eachLine</em> method.</p>
<pre class="brush: groovy; title: ; notranslate">
public static final Map SYMBOLS = [sheet: SHEET1, offset: 910, max: 8]
...
    final ExcelBuilder excelReader = new ExcelBuilder(data.absolutePath)
    Map&lt;String, String&gt; symbolTable = [:]
    excelReader.eachLine(SYMBOLS) { HSSFRow row -&gt;
        symbolTable[row.getCell(0).stringCellValue] = row.getCell(1).stringCellValue
    }

</pre>
<p>Eventually when we turn this into JSON, it will look like this:</p>
<pre class="brush: plain; title: ; notranslate">
    &quot;Symbols&quot;: {
        &quot;...&quot;: &quot;Figures not appropriate or not applicable&quot;,
        &quot;..&quot;: &quot;Figures not available&quot;,
        &quot;--&quot;: &quot;Amount too small to be expressed&quot;,
        &quot;-&quot;: &quot;Nil or zero&quot;,
        &quot;p&quot;: &quot;Preliminary figures&quot;,
        &quot;r&quot;: &quot;Revised figures&quot;,
        &quot;e&quot;: &quot;Estimated by provincial or territorial forestry agency&quot;,
        &quot;E&quot;: &quot;Estimated by the Canadian Forest Service or by Statistics Canada&quot;
    }
</pre>
<p>Now processing the other data blocks gets a little bit trickier. The first column consists of 2 merged cells, and all but one of the other headers actually represents two columns of information: a count and an optional notation. The merged column is handled by a simple <em>EMPTY</em> placeholder and the extra columns by processing the list of headers;.</p>
<pre class="brush: groovy; title: ; notranslate">
public static final List&lt;String&gt; HEADERS = ['Species', 'EMPTY', 'Year', 'NL', 'PE', 'NS', 'NB', 'QC', 'ON', 'MB', 'SK', 'AB',
    'BC', 'YT', 'NT *a', 'NU', 'CA']
/**
* For each header add a second following header for a 'notes' column
* @param strings
* @return expanded list of headers
*/
private List&lt;String&gt; expandHeaders(List&lt;String&gt; strings)
{
    strings.collect {[it, &quot;${it}_notes&quot;]}.flatten()
}
</pre>
<p>Each data block corresponds to a particular species of tree, broken down by year and Province or Territory. Each species is represented by a map which defines where in the document that information is contained so we can iterate over a collection of these maps and aggregate data quite easily. This set of constants and code is sufficient for parsing all of the data in the document.</p>
<pre class="brush: groovy; title: ; notranslate">
        public static final int HEADER_OFFSET = 3
        public static final int YEARS = 21
        public static final Map PINE = [sheet: SHEET1, offset: 6, max: YEARS, species: 'Pine']
        public static final Map SPRUCE = [sheet: SHEET1, offset: 29, max: YEARS, species: 'Spruce']
        public static final Map FIR = [sheet: SHEET1, offset: 61, max: YEARS, species: 'Fir']
        public static final Map DOUGLAS_FIR = [sheet: SHEET1, offset: 84, max: YEARS, species: 'Douglas-fir']
        public static final Map MISCELLANEOUS_SOFTWOODS = [sheet: SHEET1, offset: 116, max: YEARS, species: 'Miscellaneous softwoods']
        public static final Map MISCELLANEOUS_HARDWOODS = [sheet: SHEET1, offset: 139, max: YEARS, species: 'Miscellaneous hardwoods']
        public static final Map UNSPECIFIED = [sheet: SHEET1, offset: 171, max: YEARS, species: 'Unspecified']
        public static final Map TOTAL_PLANTING = [sheet: SHEET1, offset: 194, max: YEARS, species: 'Total planting']
        public static final List&lt;Map&gt; PROVINCIAL = [PINE, SPRUCE, FIR, DOUGLAS_FIR, MISCELLANEOUS_SOFTWOODS, MISCELLANEOUS_HARDWOODS, UNSPECIFIED, TOTAL_PLANTING]
        public static final List&lt;String&gt; AREAS = HEADERS[HEADER_OFFSET..-1]

        ...

        final Closure collector = { Map species -&gt;
            Map speciesMap = [name: species.species]
            excelReader.eachLine(species) {HSSFRow row -&gt;
                //ensure that we are reading from the correct place in the file
                if (row.rowNum == species.offset)
                {
                    assert row.getCell(0).stringCellValue == species.species
                }
                //process rows
                if (row.rowNum &gt; species.offset)
                {
                    final int year = row.getCell(HEADERS.indexOf('Year')).stringCellValue as int
                    Map yearMap = [:]
                    expandHeaders(AREAS).eachWithIndex {String header, int index -&gt;
                        final HSSFCell cell = row.getCell(index + HEADER_OFFSET)
                        yearMap[header] = cell.cellType == HSSFCell.CELL_TYPE_STRING ? cell.stringCellValue : cell.numericCellValue
                    }
                    speciesMap[year] = yearMap.asImmutable()
                }
            }
            speciesMap.asImmutable()
        }
</pre>
<p>The defined <em>collector</em> Closure returns a map of all species data for one of the four groupings(Provincial, private land, Federal and totals). The only thing that differentiates these groups is their offset in the file so we can define maps for the structure of each simply by updating the offsets of the first.</p>
<pre class="brush: groovy; title: ; notranslate">
    public static final List&lt;Map&gt; PROVINCIAL = [PINE, SPRUCE, FIR, DOUGLAS_FIR, MISCELLANEOUS_SOFTWOODS, MISCELLANEOUS_HARDWOODS, UNSPECIFIED, TOTAL_PLANTING]
    public static final List&lt;Map&gt; PRIVATE_LAND = offset(PROVINCIAL, 220)
    public static final List&lt;Map&gt; FEDERAL = offset(PROVINCIAL, 441)
    public static final List&lt;Map&gt; TOTAL = offset(PROVINCIAL, 662)

    private static List&lt;Map&gt; offset(List&lt;Map&gt; maps, int offset)
    {
        maps.collect { Map map -&gt;
            Map offsetMap = new LinkedHashMap(map)
            offsetMap.offset = offsetMap.offset + offset
            offsetMap
        }
    }
</pre>
<p>Finally, we can iterate over these simple map structures applying the <em>collector</em> Closure and we end up with a single map representing all of the data.</p>
<pre class="brush: groovy; title: ; notranslate">
        def parsedSpreadsheet = [PROVINCIAL, PRIVATE_LAND, FEDERAL, TOTAL].collect {
            it.collect(collector)
        }
        Map resultsMap = [:]
        GROUPINGS.eachWithIndex {String groupName, int index -&gt;
            resultsMap[groupName] = parsedSpreadsheet[index]
        }
        resultsMap['Symbols'] = symbolTable
</pre>
<p>And the JsonBuilder class provides an easy way to convert any map to a JSON document ready to write out the results.</p>
<pre class="brush: groovy; title: ; notranslate">
        Map map = new NaturalResourcesCanadaExcelParser().convertToMap(data)
        new File('src/test/resources/NaturalResourcesCanadaNewSeedlings.json').withWriter {Writer writer -&gt;
            writer &lt;&lt; new JsonBuilder(map).toPrettyString()
        }
</pre>
<h2>Parsing JSON into JFreeChart line charts</h2>
<p>All right, so now that we&#8217;ve turned the data into a slightly more consumable format, it&#8217;s time to visualize it. For this case I&#8217;m using a combination of the JFreeChart library and the <a href="http://java.net/projects/groovychart">GroovyChart project</a> which provides a nice DSL syntax for working with the JFreeChart API. It doesn&#8217;t look to be under development presently, but aside from the fact that the jar isn&#8217;t published to an available repository it was totally up to this task.</p>
<p>We&#8217;re going to create four charts for each of the fourteen areas represented for a total of 56 graphs overall. All of these graphs contain plotlines for each of the eight tree species tracked. This means that overall we need to create 448 distinct time series. I didn&#8217;t do any formal timings of how long this takes, but in general it came in somewhere under ten seconds to generate all of these. Just for fun, I added GPars to the mix to parallelize creation of the charts, but since writing the images to disk is going to be the most expensive part of this process, I don&#8217;t imagine it&#8217;s speeding things up terribly much.</p>
<p>First, reading in the JSON data from a file is simple with JsonSlurper.</p>
<pre class="brush: groovy; title: ; notranslate">
        def data
        new File(jsonFilename).withReader {Reader reader -&gt;
            data = new JsonSlurper().parse(reader)
        }
        assert data
</pre>
<p>Here&#8217;s a sample of what the JSON data looks like for one species over a single year, broken down first by one of the four major groups, then by tree species, then by year and finally by Province or Territory.</p>
<pre class="brush: plain; title: ; notranslate">
{
    &quot;Provincial&quot;: [
        {
            &quot;name&quot;: &quot;Pine&quot;,
            &quot;1990&quot;: {
                &quot;NL&quot;: 583.0,
                &quot;NL_notes&quot;: &quot;&quot;,
                &quot;PE&quot;: 52.0,
                &quot;PE_notes&quot;: &quot;&quot;,
                &quot;NS&quot;: 4.0,
                &quot;NS_notes&quot;: &quot;&quot;,
                &quot;NB&quot;: 4715.0,
                &quot;NB_notes&quot;: &quot;&quot;,
                &quot;QC&quot;: 33422.0,
                &quot;QC_notes&quot;: &quot;&quot;,
                &quot;ON&quot;: 51062.0,
                &quot;ON_notes&quot;: &quot;&quot;,
                &quot;MB&quot;: 2985.0,
                &quot;MB_notes&quot;: &quot;&quot;,
                &quot;SK&quot;: 4671.0,
                &quot;SK_notes&quot;: &quot;&quot;,
                &quot;AB&quot;: 8130.0,
                &quot;AB_notes&quot;: &quot;&quot;,
                &quot;BC&quot;: 89167.0,
                &quot;BC_notes&quot;: &quot;e&quot;,
                &quot;YT&quot;: &quot;-&quot;,
                &quot;YT_notes&quot;: &quot;&quot;,
                &quot;NT *a&quot;: 15.0,
                &quot;NT *a_notes&quot;: &quot;&quot;,
                &quot;NU&quot;: &quot;..&quot;,
                &quot;NU_notes&quot;: &quot;&quot;,
                &quot;CA&quot;: 194806.0,
                &quot;CA_notes&quot;: &quot;e&quot;
            },
    ...
</pre>
<p>Building the charts is a simple matter of iterating over the resulting map of parsed data. In this case we're ignoring the 'notes' data but have included it in the dataset in case we want to use it later. We're also just ignoring any non-numeric values.</p>
<pre class="brush: groovy; title: ; notranslate">
GROUPINGS.each { group -&gt;
            withPool {
                AREAS.eachParallel { area -&gt;
                    ChartBuilder builder = new ChartBuilder();
                    String title = sanitizeName(&quot;$group-$area&quot;)
                    TimeseriesChart chart = builder.timeserieschart(title: group,
                            timeAxisLabel: 'Year',
                            valueAxisLabel: 'Number of Seedlings(1000s)',
                            legend: true,
                            tooltips: false,
                            urls: false
                    ) {
                        timeSeriesCollection {
                            data.&quot;$group&quot;.each { species -&gt;
                                Set years = (species.keySet() - 'name').collect {it as int}
                                timeSeries(name: species.name, timePeriodClass: 'org.jfree.data.time.Year') {
                                    years.sort().each { year -&gt;
                                        final value = species.&quot;$year&quot;.&quot;$area&quot;
                                        //check that it's a numeric value
                                        if (!(value instanceof String))
                                        {
                                            add(period: new Year(year), value: value)
                                        }
                                    }
                                }
                            }
                        }
                    }
...
}
</pre>
<p>Then we apply some additional formatting to the JFreeChart to enhance the output styling, insert an image into the background, and fix the plot color schemes.</p>
<pre class="brush: groovy; title: ; notranslate">
                    JFreeChart innerChart = chart.chart
                    String longName = PROVINCE_SHORT_FORM_MAPPINGS.find {it.value == area}.key
                    innerChart.addSubtitle(new TextTitle(longName))
                    innerChart.setBackgroundPaint(Color.white)
                    innerChart.plot.setBackgroundPaint(Color.lightGray.brighter())
                    innerChart.plot.setBackgroundImageAlignment(Align.TOP_RIGHT)
                    innerChart.plot.setBackgroundImage(logo)
                    [Color.BLUE, Color.GREEN, Color.ORANGE, Color.CYAN, Color.MAGENTA, Color.BLACK, Color.PINK, Color.RED].eachWithIndex { color, int index -&gt;
                        innerChart.XYPlot.renderer.setSeriesPaint(index, color)
                    }
</pre>
<p>And we write out each of the charts to a formulaically named png file.</p>
<pre class="brush: groovy; title: ; notranslate">
                    def fileTitle = &quot;$FILE_PREFIX-${title}.png&quot;
                    File outputDir = new File(outputDirectory)
                    if (!outputDir.exists())
                    {
                        outputDir.mkdirs()
                    }
                    File file = new File(outputDir, fileTitle)
                    if (file.exists())
                    {
                        file.delete()
                    }
                    ChartUtilities.saveChartAsPNG(file, innerChart, 550, 300)
</pre>
<p>To tie it all together, an html page is created using <a href="http://groovy.codehaus.org/api/groovy/xml/MarkupBuilder.html">MarkupBuilder</a> to showcase all of the results, organized by Province or Territory.</p>
<pre class="brush: groovy; title: ; notranslate">
    def buildHtml(inputDirectory)
    {
        File inputDir = new File(inputDirectory)
        assert inputDir.exists()
        Writer writer = new StringWriter()
        MarkupBuilder builder = new MarkupBuilder(writer)
        builder.html {
            head {
                title('Number of Seedlings Planted by Ownership, Species')
                style(type: &quot;text/css&quot;) {
                    mkp.yield(CSS)
                }
            }
            body {
                ul {
                    AREAS.each { area -&gt;
                        String areaName = sanitizeName(area)
                        div(class: 'area rounded-corners', id: areaName) {
                            h2(PROVINCE_SHORT_FORM_MAPPINGS.find {it.value == area}.key)
                            inputDir.eachFileMatch(~/.*$areaName\.png/) {
                                img(src: it.name)
                            }
                        }
                    }
                }
                script(type: 'text/javascript', src: 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js', '')
                script(type: 'text/javascript') {
                    mkp.yield(JQUERY_FUNCTION)
                }
            }
        }
        writer.toString()
    }
</pre>
<p>The generated html page assumes that all images are co-located in the same folder, presents four images per Province/Territory and, just for fun, uses JQuery to attach a click handler to each of the headers. Click on a header and the images in that div will animate into the background. I&#8217;m sure the actual JQuery being used could be improved upon, but it serves its purpose. Here&#8217;s a sample of the html output:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;ul&gt;
      &lt;div class='area rounded-corners' id='NL'&gt;
        &lt;h2&gt;Newfoundland and Labrador&lt;/h2&gt;
        &lt;img src='naturalResourcesCanadaNewSeedlings-Federal-NL.png' /&gt;
        &lt;img src='naturalResourcesCanadaNewSeedlings-PrivateLand-NL.png' /&gt;
        &lt;img src='naturalResourcesCanadaNewSeedlings-Provincial-NL.png' /&gt;
        &lt;img src='naturalResourcesCanadaNewSeedlings-Total-NL.png' /&gt;
      &lt;/div&gt;
    ...
</pre>
<p>The resulting page looks like this in Firefox.</p>

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/apache-poi-with-groovy-and-jfreechart/htmlpagescreenshot.png" title="" class="shutterset_singlepic80" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/80_watermark_700x400_htmlpagescreenshot.png" alt="htmlpagescreenshot" title="htmlpagescreenshot" />
</a>

<h2>Source code and Links</h2>
<p>The source code is <a href="https://github.com/kellyrob99/JFreeChart-POI-Groovy">available on GitHub</a>. So is the <a href="http://kellyrob99.github.com/JFreeChart-POI-Groovy/site/naturalResourcesCanadaSeedlingsCharts.html">final resulting html page</a>. The entire source required to go from Excel to charts embedded in an html page comes in at slightly under 300 lines of code and I don&#8217;t think the results are too bad for the couple of hours effort involved. Finally, the JSON results are also <a href="http://kellyrob99.github.com/JFreeChart-POI-Groovy/site/NaturalResourcesCanadaNewSeedlings.json">hosted on the GitHub pages</a> for the project for anyone else who might want to delve into the data.</p>
<p>Some reading related to this topic:</p>
<ul>
<li><a href="http://www.technipelago.se/content/technipelago/blog/44">Groovy loves POI and POI loves Groovy</a></li>
<li><a href="http://fbflex.wordpress.com/2010/06/11/writing-batch-import-scripts-with-grails-gsql-and-gpars/">Writing batch import scripts with Grails, GSQL and GPars</a></li>
<li><a href="http://blog.andresteingress.com/2012/01/13/gsheets-a-groovy-builder-based-on-apache-poi/">GSheets – A Groovy Builder based on Apache POI</a></li>
<li><a href="http://groovy.codehaus.org/Groovy+for+the+Office">Groovy for the Office</a></li>
</ul>

<div class="ngg-galleryoverview" id="ngg-gallery-15-1845">

	<!-- Slideshow link -->
	<div class="slideshowlink">
		<a class="slideshowlink" href="http://www.kellyrob99.com/blog/2012/03/18/jfreechart-with-groovy-and-apache-poi/?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=15&amp;mode=gallery'});">
			[View with PicLens]		</a>
	</div>
	
	<!-- Thumbnails -->
		
	<div id="ngg-image-79" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/apache-poi-with-groovy-and-jfreechart/naturalresourcescanadanewseedlings-total-ca.png" title=" " class="shutterset_set_15" >
								<img title="naturalresourcescanadanewseedlings-total-ca" alt="naturalresourcescanadanewseedlings-total-ca" src="http://www.kellyrob99.com/blog/wp-content/gallery/apache-poi-with-groovy-and-jfreechart/thumbs/thumbs_naturalresourcescanadanewseedlings-total-ca.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-78" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/apache-poi-with-groovy-and-jfreechart/excelheaders.png" title=" " class="shutterset_set_15" >
								<img title="excelheaders" alt="excelheaders" src="http://www.kellyrob99.com/blog/wp-content/gallery/apache-poi-with-groovy-and-jfreechart/thumbs/thumbs_excelheaders.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-80" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/apache-poi-with-groovy-and-jfreechart/htmlpagescreenshot.png" title=" " class="shutterset_set_15" >
								<img title="htmlpagescreenshot" alt="htmlpagescreenshot" src="http://www.kellyrob99.com/blog/wp-content/gallery/apache-poi-with-groovy-and-jfreechart/thumbs/thumbs_htmlpagescreenshot.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 	 	
	<!-- Pagination -->
 	<div class='ngg-clear'></div>
 	
</div>


<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2012/05/27/github-social-graphs-with-groovy-and-graphviz/' rel='bookmark' title='GitHub Social Graphs with Groovy and GraphViz'>GitHub Social Graphs with Groovy and GraphViz</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>
<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>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2012/03/18/jfreechart-with-groovy-and-apache-poi/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hooking into the Jenkins(Hudson) API, Part 2</title>
		<link>http://www.kellyrob99.com/blog/2012/02/26/hooking-into-the-jenkinshudson-api-part-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=hooking-into-the-jenkinshudson-api-part-2</link>
		<comments>http://www.kellyrob99.com/blog/2012/02/26/hooking-into-the-jenkinshudson-api-part-2/#comments</comments>
		<pubDate>Sun, 26 Feb 2012 23:42:57 +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[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=1793</guid>
		<description><![CDATA[It&#8217;s been almost a year, but I finally had some time to revisit some code I wrote for interacting with the Jenkins api. I&#8217;ve used parts of this work to help manage a number of Jenkins build servers, mostly in terms of keeping plugins in sync and moving jobs from one machine to another. For [...]<div class='yarpp-related-rss'>

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/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/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>
</ol>
</div>
]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been almost a year, but I finally had some time to revisit some code I wrote for <a href="http://www.kellyrob99.com/blog/2011/03/27/hooking-into-the-jenkinshudson-api/" title="Hooking into the Jenkins(Hudson) API">interacting with the Jenkins api</a>. I&#8217;ve used parts of this work to help manage a number of <a href="http://jenkins-ci.org/" target="_blank">Jenkins</a> build servers, mostly in terms of keeping plugins in sync and moving jobs from one machine to another. For this article I&#8217;m going to be primarily focusing on the <a href="https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+CLI" target="_blank">CLI jar functionality</a> and some of the things you can do with it. This has mostly been developed against Jenkins but I did some light testing with <a href="http://hudson-ci.org/" target="_blank">Hudson</a> and it worked there for everything I tried, so the code remains mostly agnostic as to your choice of build server.</p>
<p></p>
<h1>The project structure</h1>
<p></p>
<p>The <a href="https://github.com/kellyrob99/Jenkins-api-tour" target="_blank">code is hosted on Github</a>, and provides a <a href="http://gradle.org/" target="_blank">Gradle</a> build which downloads and launches a Jenkins(or Hudson) server locally to execute tests. The server is set to use the Gradle build directory as its working directory, so it can be deleted simply by executing <strong><em>gradle clean</em></strong>. I tried it using both the Jenkins and the Hudson versions of the required libraries and, aside from some quirks between the two CLI implementations, they continue to function very much the same. If you want to try it with Hudson instead of Jenkins, pass in the command flag <strong><em>-Pswitch</em></strong> and the appropriate war and libraries will be used. The project is meant to be run with Gradle 1.0-milestone-8, and comes with a <a href="http://gradle.org/docs/current/userguide/gradle_wrapper.html">Gradle wrapper</a> for that version. Most of the code remains the same since the original article, but there are some enhancements and changes to deal with the newer versions of Jenkins and Hudson.<br />
The library produced by this project is published as a Maven artifact, and later on I&#8217;ll describe exactly how to get at it. There are also some samples included that demonstrate using that library in Gradle or Maven projects, and in Groovy scripts with Grapes. We&#8217;re using Groovy 1.8.6, Gradle 1.0-milestone-8 and Maven 3.0.3 to build everything.</p>
<p></p>
<h1>Getting more out of the CLI</h1>
<p>
As an alternative to the api, the CLI jar is a very capable way of interacting with the build server. In addition to a variety of built-in commands, Groovy scripts can be executed remotely, and with a little effort we can easily serialize responses in order to work with data extracted on the server. As an execution environment, the server provides a <a href="http://groovy.codehaus.org/Groovy+Shell" target="_blank">Groovysh</a> shell and stocks it with imports for the <a href="http://javadoc.jenkins-ci.org/hudson/model/package-summary.html" target="_blank">hudson.model package</a>. Also passed into the <a href="http://groovy.codehaus.org/api/groovy/lang/Binding.html" target="_blank">Binding</a> is the instance of the <a href="http://javadoc.jenkins-ci.org/hudson/model/Hudson.html" target="_blank">Jenkins/Hudson singleton object</a> in that package. In these examples I&#8217;m using the backwards-compatible Hudson version, since the code is intended to be runnable on either flavor of the server.</p>
<p></p>
<h2>The available commands</h2>
<p></p>
<p>There&#8217;s a rich variety of built-in commands, all of which are implemented in the <a href="http://javadoc.jenkins-ci.org/hudson/cli/package-summary.html">hudson.cli</a> package. Here are the ones that are listed on the CLI page of the running application:</p>
<ul>
<li>build: Builds a job, and optionally waits until its completion.</li>
<li>cancel-quiet-down: Cancel the effect of the &#8220;quiet-down&#8221; command.</li>
<li>clear-queue: Clears the build queue</li>
<li>connect-node: Reconnect to a node</li>
<li>copy-job: Copies a job.</li>
<li>create-job: Creates a new job by reading stdin as a configuration XML file.</li>
<li>delete-builds: Deletes build record(s).</li>
<li>delete-job: Deletes a job</li>
<li>delete-node: Deletes a node</li>
<li>disable-job: Disables a job</li>
<li>disconnect-node: Disconnects from a node</li>
<li>enable-job: Enables a job</li>
<li>get-job: Dumps the job definition XML to stdout</li>
<li>groovy: Executes the specified Groovy script.</li>
<li>groovysh: Runs an interactive groovy shell.</li>
<li>help: Lists all the available commands.</li>
<li>install-plugin: Installs a plugin either from a file, an URL, or from update center.</li>
<li>install-tool: Performs automatic tool installation, and print its location to stdout. Can be only called from<br />
        inside a build.
    </li>
<li>keep-build: Mark the build to keep the build forever.</li>
<li>list-changes: Dumps the changelog for the specified build(s).</li>
<li>login: Saves the current credential to allow future commands to run without explicit credential information.
    </li>
<li>logout: Deletes the credential stored with the login command.</li>
<li>mail: Reads stdin and sends that out as an e-mail.</li>
<li>offline-node: Stop using a node for performing builds temporarily, until the next &#8220;online-node&#8221; command.</li>
<li>online-node: Resume using a node for performing builds, to cancel out the earlier &#8220;offline-node&#8221; command.</li>
<li>quiet-down: Quiet down Jenkins, in preparation for a restart. Don&#8217;t start any builds.</li>
<li>reload-configuration: Discard all the loaded data in memory and reload everything from file system. Useful when<br />
        you modified config files directly on disk.
    </li>
<li>restart: Restart Jenkins</li>
<li>safe-restart: Safely restart Jenkins</li>
<li>safe-shutdown: Puts Jenkins into the quiet mode, wait for existing builds to be completed, and then shut down<br />
        Jenkins.
    </li>
<li>set-build-description: Sets the description of a build.</li>
<li>set-build-display-name: Sets the displayName of a build</li>
<li>set-build-result: Sets the result of the current build. Works only if invoked from within a build.</li>
<li>shutdown: Immediately shuts down Jenkins server</li>
<li>update-job: Updates the job definition XML from stdin. The opposite of the get-job command</li>
<li>version: Outputs the current version.</li>
<li>wait-node-offline: Wait for a node to become offline</li>
<li>wait-node-online: Wait for a node to become online</li>
<li>who-am-i: Reports your credential and permissions</li>
</ul>
<p>It&#8217;s not immediately apparent what arguments are required for each, but they almost universally follow a CLI pattern of printing usage details when called with no arguments. For instance, when you call the <em>build</em> command with no arguments, here&#8217;s what you get back in the error stream:</p>
<blockquote><p>
    Argument &#8220;JOB&#8221; is required<br />
    java -jar jenkins-cli.jar build args&#8230;<br />
    Starts a build, and optionally waits for a completion.<br />
    Aside from general scripting use, this command can be<br />
    used to invoke another job from within a build of one job.<br />
    With the -s option, this command changes the exit code based on<br />
    the outcome of the build (exit code 0 indicates a success.)<br />
    With the -c option, a build will only run if there has been<br />
    an SCM change<br />
    JOB : Name of the job to build<br />
    -c  : Check for SCM changes before starting the build, and if there&#8217;s no<br />
    change, exit without doing a build<br />
    -p  : Specify the build parameters in the key=value format.<br />
    -s  : Wait until the completion/abortion of the command
</p></blockquote>
<p></p>
<h2>Getting data out of the system</h2>
<p>
All of the interaction with the remote system is handled by streams and it&#8217;s pretty easy to craft scripts that will return data in an easily parseable String format using built-in Groovy facilities. In theory, you should be able to marshal more complex objects as well, but let&#8217;s keep it simple for now. Here&#8217;s a Groovy script that just extracts all of the job names into a List, calling the Groovy inspect method to quote all values.<br />
<script src="https://gist.github.com/1910293.js?file=nameAllJobs.groovy"></script><noscript><pre><code class="language-groovy groovy">@GrabResolver(name = 'glassfish', root = 'http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name = &quot;github&quot;, root = &quot;http://kellyrob99.github.com/Jenkins-api-tour/repository&quot;)
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import org.kar.hudson.api.cli.HudsonCliApi

String rootUrl = 'http://localhost:8080'
HudsonCliApi cliApi = new HudsonCliApi()
OutputStream out = new ByteArrayOutputStream()
cliApi.runCliCommand(rootUrl, ['groovysh', 'hudson.jobNames.inspect()'], System.in, out, System.err)
List allJobs = Eval.me(cliApi.parseResponse(out.toString()))
println allJobs

</code></pre></noscript><br />
Once we get the response back, we do a little housekeeping to remove some extraneous characters at the beginning of the String, and use Eval.me to transform the String into a List. Groovy provides a variety of ways of turning text into code, so if your usage scenario gets more complicated than this simple case you can use a GroovyShell with a Binding or other alternative to parse the results into something useful. This easy technique extends to Maps and other types as well, making it simple to work with data sent back from the server.</p>
<p></p>
<h1>Some useful examples</h1>
<p></p>
<h2>Finding plugins with updates and and updating all of them</h2>
<p>Here&#8217;s an example of using a Groovy script to find all of the plugins that have updates available, returning that result to the caller, and then calling the CLI &#8216;install-plugin&#8217; command on all of them. Conveniently, this command will either install a plugin if it&#8217;s not already there or update it to the latest version if already installed.<br />
<script src="https://gist.github.com/1907114.js?file=updateAllPlugins.groovy"></script><noscript><pre><code class="language-groovy groovy">def findPluginsWithUpdates = '''
Hudson.instance.pluginManager.plugins.inject([]) { List toUpdate, plugin -&gt;
    if(plugin.hasUpdate())
    {
        toUpdate &lt;&lt; plugin.shortName
    }
    toUpdate
}.inspect()
'''
OutputStream updateablePlugins = new ByteArrayOutputStream()
cliApi.runCliCommand(rootUrl, ['groovysh', findPluginsWithUpdates], System.in, updateablePlugins, System.err)

def listOfPlugins = Eval.me(parseOutput(updateablePlugins.toString()))
listOfPlugins.each{ plugin -&gt;
    cliApi.runCliCommand(rootUrl, ['install-plugin', plugin])
}</code></pre></noscript></p>
<p></p>
<h2>Install or upgrade a suite of Plugins all at once</h2>
<p>This definitely beats using the &#8216;Manage Plugins&#8217; UI and is idempotent so running it more than once can only result in possibly upgrading already installed Plugins. This set of plugins might be overkill, but these are some plugins I recently surveyed for possible use.<br />
<script src="https://gist.github.com/1907283.js?file=setupNewServer.groovy"></script><noscript><pre><code class="language-groovy groovy">@GrabResolver(name='glassfish', root='http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name=&quot;github&quot;, root=&quot;http://kellyrob99.github.com/Jenkins-api-tour/repository&quot;)
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import static java.net.HttpURLConnection.*
import org.kar.hudson.api.*
import org.kar.hudson.api.cli.HudsonCliApi

String rootUrl = 'http://localhost:8080'
HudsonCliApi cliApi = new HudsonCliApi()

['groovy', 'gradle', 'chucknorris', 'greenballs', 'github', 'analysis-core', 'analysis-collector', 'cobertura',
        'project-stats-plugin','audit-trail', 'view-job-filters', 'disk-usage', 'global-build-stats',
        'radiatorviewplugin', 'violations', 'build-pipeline-plugin', 'monitoring', 'dashboard-view',
        'iphoneview', 'jenkinswalldisplay'].each{ plugin -&gt;
    cliApi.runCliCommand(rootUrl, ['install-plugin', plugin])
}

//  Restart a node, required for newly installed plugins to be made available.
cliApi.runCliCommand(rootUrl, 'safe-restart')
</code></pre></noscript></p>
<p></p>
<h2>Finding all failed builds and triggering them</h2>
<p>It&#8217;s not all that uncommon that a network problem or infrastructure event can cause a host of builds to fail all at once. Once the problem is solved this script can be useful for verifying that the builds are all in working order.<br />
<script src="https://gist.github.com/1911932.js?file=findAndTriggerFailedBuilds.groovy"></script><noscript><pre><code class="language-groovy groovy">@GrabResolver(name = 'glassfish', root = 'http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name = &quot;github&quot;, root = &quot;http://kellyrob99.github.com/Jenkins-api-tour/repository&quot;)
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import org.kar.hudson.api.cli.HudsonCliApi

String rootUrl = 'http://localhost:8080'
HudsonCliApi cliApi = new HudsonCliApi()
OutputStream out = new ByteArrayOutputStream()
def script = '''hudson.items.findAll{ job -&gt;
    job.isBuildable() &amp;&amp; job.lastBuild &amp;&amp; job.lastBuild.result == Result.FAILURE
}.collect{it.name}.inspect()
'''
cliApi.runCliCommand(rootUrl, ['groovysh', script], System.in, out, System.err)
List failedJobs = Eval.me(cliApi.parseResponse(out.toString()))
failedJobs.each{ job -&gt;
    cliApi.runCliCommand(rootUrl, ['build', job])
}

</code></pre></noscript></p>
<p></p>
<h2>Open an interactive Groovy shell</h2>
<p>If you really want to poke at the server you can launch an interactive shell to inspect state and execute commands. The System.in stream is bound and responses from the server are immediately echoed back.<br />
<script src="https://gist.github.com/1912014.js?file=jenkinsGroovyShell.groovy"></script><noscript><pre><code class="language-groovy groovy">@GrabResolver(name = 'glassfish', root = 'http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name = &quot;github&quot;, root = &quot;http://kellyrob99.github.com/Jenkins-api-tour/repository&quot;)
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import org.kar.hudson.api.cli.HudsonCliApi
/**
 * Open an interactive Groovy shell that imports the hudson.model.* classes and exposes
 * a 'hudson' and/or 'jenkins' object in the Binding which is an instance of hudson.model.Hudson
 */
HudsonCliApi cliApi = new HudsonCliApi()
String rootUrl = args ? args[0] :'http://localhost:8080'
cliApi.runCliCommand(rootUrl, 'groovysh')

</code></pre></noscript></p>
<p></p>
<h1>Updates to the project</h1>
<p>A lot has happened in the last year and all of the project dependencies needed an update. In particular, there have been some very nice improvements to Groovy, Gradle and Spock. Most notably, Gradle has come a VERY long way since version 0.9.2. The JSON support added in Groovy 1.8 comes in handy as well. Spock required a small tweak for rendering dynamic content in test reports when using <a href="http://java.dzone.com/articles/unrolling-spock-advanced" target="_blank">@Unroll</a>, but that&#8217;s a small price to pay for features like <a href="http://blog.freeside.co/blog/2012/02/15/spock-killer-features-the-old-method/">the &#8216;old&#8217; method</a> and <a href="http://meetspock.appspot.com/script/45001">Chained Stubbing</a>. Essentially, in response to changes in Groovy 1.8+, a Spock @Unroll annotation needs to change from:</p>
<pre class="brush: groovy; title: ; notranslate">
@Unroll(&quot;querying of #rootUrl should match #xmlResponse&quot;)
</pre>
<p>to a Closure encapsulated GString expression:</p>
<pre class="brush: groovy; title: ; notranslate">
@Unroll({&quot;querying of $rootUrl should match $xmlResponse&quot;})
</pre>
<p>It sounds like the syntax is still in flux and I&#8217;m glad I found this <a href="http://spock-framework.3207229.n2.nabble.com/Problem-with-Unroll-with-groovy-1-8-td6317496.html" target="_blank">discussion of the problem online</a>.</p>
<p></p>
<h1>Hosting a Maven repository on Github</h1>
<p>Perhaps you noticed from the previous script examples, we&#8217;re referencing a published library to get at the HudsonCliApi class. I read an <a href="http://chkal.blogspot.com/2010/09/maven-repositories-on-github.html" target="_blank">interesting article last week</a> which describes how to use the built-in <a href="http://pages.github.com/">Github Pages</a> for publishing a Maven repository. While this isn&#8217;t nearly as capable as a repository like Nexus or Artifactory, it&#8217;s totally sufficient for making some binaries available to most common build tools in a standard fashion. Simply publish the binaries along with associated poms in the standard Maven repo layout and you&#8217;re off to the races! Each dependency management system has its quirks(I&#8217;m looking at you Ivy!) but they&#8217;re pretty easy to work around, so here&#8217;s examples for Gradle, Maven and Groovy Grapes to use the library produced by this project code. Note that some of the required dependencies for Jenkins/Hudson aren&#8217;t available in the Maven central repository, so we&#8217;re getting them from the Glassfish repo.</p>
<p></p>
<h2>Gradle</h2>
<p>Pretty straight forward, this works with the latest version of Gradle and assumes that you are using the Groovy plugin.</p>
<pre class="brush: groovy; title: ; notranslate">
repositories {
    mavenCentral()
    maven {
        url 'http://maven.glassfish.org/content/groups/public/'
    }
    maven {
        url 'http://kellyrob99.github.com/Jenkins-api-tour/repository'
    }
}
dependencies {
    groovy &quot;org.codehaus.groovy:groovy-all:${versions.groovy}&quot;
    compile 'org.kar:hudson-api:0.2-SNAPSHOT'
}
</pre>
<p></p>
<h2>Maven</h2>
<p>Essentially the same content in xml and in this case it&#8217;s assumed that you&#8217;re using the GMaven plugin</p>
<pre class="brush: xml; title: ; notranslate">
&lt;repositories&gt;
    &lt;repository&gt;
        &lt;id&gt;glassfish&lt;/id&gt;
        &lt;name&gt;glassfish&lt;/name&gt;
        &lt;url&gt;http://maven.glassfish.org/content/groups/public/&lt;/url&gt;
    &lt;/repository&gt;
    &lt;repository&gt;
        &lt;id&gt;github&lt;/id&gt;
        &lt;name&gt;Jenkins-api-tour maven repo on github&lt;/name&gt;
        &lt;url&gt;http://kellyrob99.github.com/Jenkins-api-tour/repository&lt;/url&gt;
    &lt;/repository&gt;
&lt;/repositories&gt;

&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.codehaus.groovy&lt;/groupId&gt;
        &lt;artifactId&gt;groovy-all&lt;/artifactId&gt;
        &lt;version&gt;${groovy.version}&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.kar&lt;/groupId&gt;
        &lt;artifactId&gt;hudson-api&lt;/artifactId&gt;
        &lt;version&gt;0.2-SNAPSHOT&lt;/version&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;

</pre>
<p></p>
<h2>Grapes</h2>
<p>In this case there seems to be a problem resolving some transitive dependency for an older version of Groovy which is why there&#8217;s an explicit exclude for it.</p>
<pre class="brush: groovy; title: ; notranslate">
@GrabResolver(name='glassfish', root='http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name=&quot;github&quot;, root=&quot;http://kellyrob99.github.com/Jenkins-api-tour/repository&quot;)
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
</pre>
<p></p>
<h1>Links</h1>
<p><a href="https://github.com/kellyrob99/Jenkins-api-tour/">The Github Jenkins-api-tour project page</a><br />
<a href="http://chkal.blogspot.com/2010/09/maven-repositories-on-github.html" title="Maven repositories on Github" target="_blank">Maven repositories on Github</a><br />
<a href="http://scriptlerweb.appspot.com" title="Scriptler" target="_blank">Scriptler example Groovy scripts</a><br />
<a href="https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+CLI">Jenkins CLI documentation</a></p>
<div class='yarpp-related-rss'>
<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/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/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>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2012/02/26/hooking-into-the-jenkinshudson-api-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Five Cool Things You Can Do With Groovy Scripts</title>
		<link>http://www.kellyrob99.com/blog/2011/12/04/five-cool-things-you-can-do-with-groovy-scripts/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=five-cool-things-you-can-do-with-groovy-scripts</link>
		<comments>http://www.kellyrob99.com/blog/2011/12/04/five-cool-things-you-can-do-with-groovy-scripts/#comments</comments>
		<pubDate>Sun, 04 Dec 2011 21:51:34 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[gist]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Gradle]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Hudson]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[jenkins]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[JsonSlurper]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1761</guid>
		<description><![CDATA[1. Ensure all of your Jenkins builds are building the correct branch from source control I manage a large number of builds at work, spread across several build servers. When we release a new version all of the builds need to be updated to point to new working branches. This script takes advantage of the [...]<div class='yarpp-related-rss'>

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

assert args &amp;&amp; args.size() == 2
def urls = args[0].split(',')
def expectedVersion = args[1]
urls.each { url -&gt;
    println &quot;examining url $url&quot;
    def json = new JsonSlurper().parseText(url.toURL().text)

    json.jobs.each {
        try
        {
            def job = new JsonSlurper().parseText(&quot;${it.url}/api/json?depth=1&quot;.toURL().text)
            if (!job.builds[0].changeSet.revisions[0].module.endsWith(expectedVersion))
            {
                println &quot;$it.url fails!&quot;
            }
            else
            {
                println &quot;$it.url passes!&quot;
            }
        }
        catch (e)
        {
            println &quot;Exception thrown processing $it.url : $e&quot;
        }
    }
}

</code></pre></noscript></p>
<h2>2. Look up the artifacts from the last successful Jenkins build</h2>
<p>This is very handy if you want to automate deployment of software from your build system and can replace a lot of error prone manual updating of scripts. In this particular example you can link up quickly with the latest, greatest build of JRuby from <a href="http://ci.jruby.org/">their public CI server</a>.<br />
<script src="https://gist.github.com/1430856.js?file=jenkinsBuildArtifacts.groovy"></script><noscript><pre><code class="language-groovy groovy">import groovy.json.*
def HOSTNAME = 'http://ci.jruby.org'
def JOBNAME = 'jruby-dist'
def JOB_URL = &quot;$HOSTNAME/job/$JOBNAME/lastSuccessfulBuild&quot;
def text = &quot;$JOB_URL/api/json&quot;.toURL().text
println JsonOutput.prettyPrint(text)
def json = new JsonSlurper().parseText(text)
json.artifacts.each{
    println it
}</code></pre></noscript><br />
Here&#8217;s the sample output at time of writing:</p>
<blockquote><p>[relativePath:dist/jruby-bin-1.7.0.dev.tar.gz, fileName:jruby-bin-1.7.0.dev.tar.gz, displayPath:null]<br />
[relativePath:dist/jruby-bin-1.7.0.dev.tar.gz.md5, fileName:jruby-bin-1.7.0.dev.tar.gz.md5, displayPath:null]<br />
[relativePath:dist/jruby-bin-1.7.0.dev.tar.gz.sha1, fileName:jruby-bin-1.7.0.dev.tar.gz.sha1, displayPath:null]<br />
[relativePath:dist/jruby-bin-1.7.0.dev.zip, fileName:jruby-bin-1.7.0.dev.zip, displayPath:null]<br />
[relativePath:dist/jruby-bin-1.7.0.dev.zip.md5, fileName:jruby-bin-1.7.0.dev.zip.md5, displayPath:null]<br />
[relativePath:dist/jruby-bin-1.7.0.dev.zip.sha1, fileName:jruby-bin-1.7.0.dev.zip.sha1, displayPath:null]<br />
[relativePath:dist/jruby-complete-1.7.0.dev.jar, fileName:jruby-complete-1.7.0.dev.jar, displayPath:null]<br />
[relativePath:dist/jruby-complete-1.7.0.dev.jar.md5, fileName:jruby-complete-1.7.0.dev.jar.md5, displayPath:null]<br />
[relativePath:dist/jruby-complete-1.7.0.dev.jar.sha1, fileName:jruby-complete-1.7.0.dev.jar.sha1, displayPath:null]<br />
[relativePath:dist/jruby-jars-1.7.0.dev.gem, fileName:jruby-jars-1.7.0.dev.gem, displayPath:null]<br />
[relativePath:dist/jruby-jars-1.7.0.dev.gem.md5, fileName:jruby-jars-1.7.0.dev.gem.md5, displayPath:null]<br />
[relativePath:dist/jruby-jars-1.7.0.dev.gem.sha1, fileName:jruby-jars-1.7.0.dev.gem.sha1, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.tar.gz, fileName:jruby-src-1.7.0.dev.tar.gz, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.tar.gz.md5, fileName:jruby-src-1.7.0.dev.tar.gz.md5, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.tar.gz.sha1, fileName:jruby-src-1.7.0.dev.tar.gz.sha1, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.zip, fileName:jruby-src-1.7.0.dev.zip, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.zip.md5, fileName:jruby-src-1.7.0.dev.zip.md5, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.zip.sha1, fileName:jruby-src-1.7.0.dev.zip.sha1, displayPath:null]</p></blockquote>
<h2>3. Read in a CSV file, filter it, and write out the result</h2>
<p>Groovy Grapes and one of my favorite libraries, <a href="http://opencsv.sourceforge.net/">OpenCSV</a>, make it trivial to script &#8216;one off&#8217; solutions for removing work that would normally take place manually in Excel. For me it comes up most often with data import/export from systems I&#8217;m working on and the need to create particular test environments using those import/export mechanisms. For example, using a scripted solution like this you can quickly:</p>
<ul>
<li>Export users from one test system into a CSV file, along with local phone number contact data</li>
<li>Replace the existing phone numbers with a mix of local and international numbers</li>
<li>Import the new data into a different test system</li>
<li>Verify that the system properly deals with international calling concerns</li>
</ul>
<p>This example simply trims out all of the rows where the second column of input contains values less than 100. It&#8217;s also nice to note that OpenCSV is smart enough to let you ignore one or more &#8216;header rows&#8217;, a common attribute of CSV files.<br />
<script src="https://gist.github.com/1430935.js?file=openCsv.groovy"></script><noscript><pre><code class="language-groovy groovy">@Grab(group = 'net.sf.opencsv', module = 'opencsv', version = '2.3')
import au.com.bytecode.opencsv.CSVReader
import au.com.bytecode.opencsv.CSVParser
import au.com.bytecode.opencsv.CSVWriter

def TEST_FILE_NAME = 'test.csv'
def TEST_OUTPUT_FILE_NAME = 'testOut.csv'

List&lt;String[]&gt; rows = new CSVReader(new FileReader(new File(TEST_FILE_NAME)), CSVParser.DEFAULT_SEPARATOR, CSVParser.DEFAULT_ESCAPE_CHARACTER, CSVParser.DEFAULT_QUOTE_CHARACTER, 1).readAll()
def rowsOver100 = rows.findAll {it[1].toInteger() &gt; 100}

File output = new File(TEST_OUTPUT_FILE_NAME)
if (output.exists())
{
    output.delete()
}
output.createNewFile()
output.withWriter { writer -&gt;
    new CSVWriter(writer).writeAll(rowsOver100)

}

//println rows</code></pre></noscript></p>
<h2>4. Download, install and run a stand-alone webserver</h2>
<p>This example comes courtesy of a <a href="http://www.ibm.com/developerworks/java/library/j-javadev2-20/index.html">recent article by Andrew Glover</a> about <a href="https://github.com/groovypp/gretty/wiki">Gretty</a>, a lightweight http server. I don&#8217;t have a concrete use-case for this right now, but it&#8217;s easy to note that in this case you can code a large part of the server behaviour directly in the script, unlike, for instance, if you were to use a script to stand up a Jetty server. This should let you publish a script once in a central location and stand up as many Gretty servers providing the declared services as you like. This particular example simply echos back &#8216;Hello&#8217; plus whatever path you append to localhost:8080.<br />
<script src="https://gist.github.com/1431012.js?file=grettyExample.groovy"></script><noscript><pre><code class="language-groovy groovy">import org.mbte.gretty.httpserver.* 

@GrabResolver(name='gretty', 
  root='http://groovypp.artifactoryonline.com/groovypp/libs-releases-local')
@Grab('org.mbte.groovypp:gretty:0.4.279') 

GrettyServer server = [] 
server.groovy = [ 
    localAddress: new InetSocketAddress(&quot;localhost&quot;, 8080), 
    defaultHandler: { 
        response.redirect &quot;/&quot; 
    }, 
    &quot;/:name&quot;: {
        get {
            response.text = &quot;Hello ${request.parameters['name']}&quot;
        } 
    } 
] 
server.start()</code></pre></noscript></p>
<h2>5. Remotely execute any of these scripts by url</h2>
<p>As of <a title="Groovy 1.8.3/1.9-beta-4" href="http://glaforge.appspot.com/article/groovy-1-8-3-and-1-9-beta-4-released" target="_blank">Groovy 1.8.3/1.9-beta-4</a> you can refer to a Groovy script hosted at a remote url and execute it locally. If you work on different machines a lot(as I do) this can really help keep your toolbox of scripts handy, regardless of where you are. Since these scripts are publicly hosted on GitHub(thanks guys!), you can simply copy the url from the &#8216;view raw&#8217; link at the bottom and go to your console to execute them like this:</p>
<pre class="brush: groovy; title: ; notranslate">
$ groovy https://gist.github.com/raw/1430856/cea0186a862217015fb4fc2b63eb0ad3575c06fc/jenkinsBuildArtifacts.groovy
{
    &quot;actions&quot;: [
        {
            &quot;causes&quot;: [
                {
                    &quot;shortDescription&quot;: &quot;Started by timer&quot;
                }
            ]
        },
        {
            &quot;buildsByBranchName&quot;: {
                &quot;origin/master&quot;: {
                    &quot;buildNumber&quot;: 684,
                    &quot;buildResult&quot;: null,
                    &quot;revision&quot;: {
                        &quot;SHA1&quot;: &quot;3419fee4bb9436d3222ff3df8dd7fcf2308a6919&quot;,
                        &quot;branch&quot;: [
                            {
                                &quot;SHA1&quot;: &quot;3419fee4bb9436d3222ff3df8dd7fcf2308a6919&quot;,
                                &quot;name&quot;: &quot;origin/master&quot;
                            }
                        ]
                    }
                }
            },
... and so on
</pre>
<h2>Final note</h2>
<p>Being able to share scripts across a variety of machines has definitely made my professional life a lot easier and I&#8217;m very glad to see the ability to execute code from a URL in Groovy. But what really turned me onto the idea was its usage in Gradle, which supports loading remote Groovy/Gradle scripts using the &#8220;apply from: {url or file}&#8221; syntax. I find that more and more I reference particular tasks remotely in a build, especially for static analysis tools that don&#8217;t necessarily need to be run on a regular basis.<br />
A great example of this is the recently released <a href="http://tellurianring.com/wiki/gradle/templates">Gradle Templates Plugin</a>, which is basically the Gradle answer to the <a href="http://maven.apache.org/archetype/maven-archetype-plugin/">Maven Archetype plugin</a>. Create a build.gradle with the following content:</p>
<pre class="brush: groovy; title: ; notranslate">
apply from: 'http://launchpad.net/gradle-templates/trunk/1.2/+download/apply.groovy'
</pre>
<p>And we have the following tasks available to create new Gradle projects and objects with conventional structure:</p>
<pre class="brush: groovy; title: ; notranslate">
Template tasks
--------------
createGradlePlugin - Creates a new Gradle Plugin project in a new directory named after your project.
createGroovyClass - Creates a new Groovy class in the current project.
createGroovyProject - Creates a new Gradle Groovy project in a new directory named after your project.
createJavaClass - Creates a new Java class in the current project.
createJavaProject - Creates a new Gradle Java project in a new directory named after your project.
createScalaClass - Creates a new Scala class in the current project.
createScalaObject - Creates a new Scala object in the current project.
createScalaProject - Creates a new Gradle Scala project in a new directory named after your project.
createWebappProject - Creates a new Gradle Webapp project in a new directory named after your project.
exportAllTemplates - Exports all the default template files into the current directory.
exportGroovyTemplates - Exports the default groovy template files into the current directory.
exportJavaTemplates - Exports the default java template files into the current directory.
exportPluginTemplates - Exports the default plugin template files into the current directory.
exportScalaTemplates - Exports the default scala template files into the current directory.
exportWebappTemplates - Exports the default webapp template files into the current directory.
initGradlePlugin - Initializes a new Gradle Plugin project in the current directory.
initGroovyProject - Initializes a new Gradle Groovy project in the current directory.
initJavaProject - Initializes a new Gradle Java project in the current directory.
initScalaProject - Initializes a new Gradle Scala project in the current directory.
initWebappProject - Initializes a new Gradle Webapp project in the current directory.
</pre>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2011/09/18/using-gradle-to-bootstrap-your-legacy-ant-builds/' rel='bookmark' title='Using Gradle to Bootstrap your Legacy Ant Builds'>Using Gradle to Bootstrap your Legacy Ant Builds</a></li>
<li><a href='http://www.kellyrob99.com/blog/2012/02/26/hooking-into-the-jenkinshudson-api-part-2/' rel='bookmark' title='Hooking into the Jenkins(Hudson) API, Part 2'>Hooking into the Jenkins(Hudson) API, Part 2</a></li>
<li><a href='http://www.kellyrob99.com/blog/2012/05/27/github-social-graphs-with-groovy-and-graphviz/' rel='bookmark' title='GitHub Social Graphs with Groovy and GraphViz'>GitHub Social Graphs with Groovy and GraphViz</a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2011/12/04/five-cool-things-you-can-do-with-groovy-scripts/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Using Gradle to Bootstrap your Legacy Ant Builds</title>
		<link>http://www.kellyrob99.com/blog/2011/09/18/using-gradle-to-bootstrap-your-legacy-ant-builds/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-gradle-to-bootstrap-your-legacy-ant-builds</link>
		<comments>http://www.kellyrob99.com/blog/2011/09/18/using-gradle-to-bootstrap-your-legacy-ant-builds/#comments</comments>
		<pubDate>Sun, 18 Sep 2011 20:44:11 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ant]]></category>
		<category><![CDATA[AntBuilder]]></category>
		<category><![CDATA[Gradle]]></category>
		<category><![CDATA[GradleBuild]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1422</guid>
		<description><![CDATA[Gradle provides several different ways to leverage your existing investment in Ant, both in terms of accumulated knowledge and the time you&#8217;ve already put into build files. This can greatly facilitate the process of porting Ant built projects over to Gradle, and can give you a path for incrementally doing so. The Gradle documentation does [...]<div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/11/13/why-do-i-like-gradle/' rel='bookmark' title='Why do I Like Gradle?'>Why do I Like Gradle?</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/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>
</ol>
</div>
]]></description>
			<content:encoded><![CDATA[<p>Gradle provides several different ways to leverage your existing investment in Ant, both in terms of accumulated knowledge and the time you&#8217;ve already put into build files. This can greatly facilitate the process of porting Ant built projects over to Gradle, and can give you a path for incrementally doing so. The <a href="http://gradle.org/current/docs/userguide/userguide_single.html#ant">Gradle documentation</a> does a good job of describing how you can use Ant in your Gradle build script, but here&#8217;s a quick overview and some particulars I&#8217;ve run into myself.</p>
<p></p>
<h2>Gradle AntBuilder</h2>
<p>Every Gradle Project includes an AntBuilder instance, making any and all of the facilities of Ant available within your build files. Gradle provides a simple extension to the existing Groovy AntBuilder which adds a simple yet powerful way to interface with existing Ant build files: the <em>importBuild(Object antBuildFile)</em> method. Internally this method utilizes an Ant ProjectHelper to parse the specified Ant build file and then wraps all of the targets in Gradle tasks making them available in the Gradle build. The following is a simple Ant build file used for illustration which contains some properties and a couple of dependent targets.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;project name=&quot;build&quot; default=&quot;all&quot;&gt;
    &lt;echo&gt;Building ${ant.file}&lt;/echo&gt;

    &lt;property file=&quot;build.properties&quot;/&gt;
    &lt;property name=&quot;root.dir&quot; location=&quot;.&quot;/&gt;

    &lt;target name=&quot;dist&quot; description=&quot;Build the distribution&quot;&gt;
        &lt;property name=&quot;dist.dir&quot; location=&quot;dist&quot;/&gt;
        &lt;echo&gt;dist.dir=${dist.dir}, foo=${foo}&lt;/echo&gt;
    &lt;/target&gt;

    &lt;target name=&quot;all&quot; description=&quot;Build everything&quot; depends=&quot;dist&quot;/&gt;
&lt;/project&gt;

</pre>
<p>
Importing this build file using Gradle is a one-liner.<br />
</p>
<pre class="brush: groovy; title: ; notranslate">
ant.importBuild('src/main/resources/build.xml')
</pre>
<p>
And the output of gradle tasks &#8211;all on the command line shows that the targets have been added to the build tasks.<br />
</p>
<pre class="brush: groovy; title: ; notranslate">
$ gradle tasks --all
...
Other tasks
-----------
all - Build everything
    dist - Build the distribution
...
</pre>
<p>
Properties used in the Ant build file can be specified in the Gradle build or on the command line and, unlike the usual Ant property behaviour, properties set by Ant or on the command line may be overwritten by Gradle. Given a simple build.properties file with <em>foo=bar</em> as the single entry, here&#8217;s a few combinations to demonstrate the override behaviour.<br />

<table id="wp-table-reloaded-id-6-no-1" class="wp-table-reloaded wp-table-reloaded-id-6">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Command line invocation</th><th class="column-2">Gradle Build Config</th><th class="column-3">Effect</th><th class="column-4">Result</th>
	</tr>
</thead>
<tbody>
	<tr class="row-2 even">
		<td class="column-1">gradle dist</td><td class="column-2">ant.importBuild('src/main/resources/build.xml')</td><td class="column-3">build.properties value loaded from ant build is used</td><td class="column-4">foo=bar</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">gradle dist -Dfoo=NotBar</td><td class="column-2">ant.importBuild('src/main/resources/build.xml')</td><td class="column-3">command line property is used</td><td class="column-4">foo=NotBar</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">gradle dist -Dfoo=NotBar</td><td class="column-2">ant.foo='NotBarFromGradle' <br />
ant.importBuild('src/main/resources/build.xml')</td><td class="column-3">Gradle build property is used</td><td class="column-4">foo=NotBarFromGradle</td>
	</tr>
	<tr class="row-5 odd">
		<td class="column-1">gradle dist -Dfoo=NotBar</td><td class="column-2">ant.foo='NotBarFromGradle'<br />
ant.importBuild('src/main/resources/build.xml')<br />
ant.foo='NotBarFromGradleAgain'</td><td class="column-3">Gradle build property override is used</td><td class="column-4">foo=NotBarFromGradleAgain</td>
	</tr>
</tbody>
</table>
</p>
<h2>How to deal with task name clashes</h2>
<p>Since Gradle insists on uniqueness of task names attempting to import an Ant build that contains a target with the same name as an existing Gradle task will fail. The most common clash I&#8217;ve encountered is with the <em>clean</em> task provided by the Gradle BasePlugin. With the help of a little bit of indirection we can still import and use any clashing targets by utilizing the GradleBuild task to bootstrap an Ant build import in an isolated Gradle project. Let&#8217;s add a new task to the mix in the Ant build imported and another dependency on the ant <em>clean</em> target to the <em>all</em> task. </p>
<pre class="brush: xml; title: ; notranslate">
&lt;!-- excerpt from buildWithClean.xml Ant build file --&gt;
    &lt;target name=&quot;clean&quot; description=&quot;clean up&quot;&gt;
        &lt;echo&gt;Called clean task in ant build with foo = ${foo}&lt;/echo&gt;
    &lt;/target&gt;
    &lt;target name=&quot;all&quot; description=&quot;Build everything&quot; depends=&quot;dist,clean&quot;/&gt;
</pre>
<p>And a simple Gradle build file which will handle the import.</p>
<pre class="brush: groovy; title: ; notranslate">
ant.importBuild('src/main/resources/buildWithClean.xml')
</pre>
<p>Finally, in our main gradle build file we add a task to run the targets we want.</p>
<pre class="brush: groovy; title: ; notranslate">
task importTaskWithExistingName(type: GradleBuild) { GradleBuild antBuild -&gt;
    antBuild.buildFile ='buildWithClean.gradle'
    antBuild.tasks = ['all']
}
</pre>
<p>This works, but unfortunately suffers from <a href="http://issues.gradle.org/browse/GRADLE-427">one small problem</a>. When Gradle is importing these tasks it doesn&#8217;t properly respect the declared order of the dependencies. Instead it executes the dependent ant targets in alphabetical order. In this particular case Ant expects to execute the <em>dist</em> target before <em>clean</em> and Gradle executes them in the reverse order. This can be worked around by explicitly stating the task order, definitely not ideal, but workable. This Gradle task will execute the  underlying Ant targets in the way we need.</p>
<pre class="brush: groovy; title: ; notranslate">
task importTasksRunInOrder(type: GradleBuild) { GradleBuild antBuild -&gt;
    antBuild.buildFile ='buildWithClean.gradle'
    antBuild.tasks = ['dist', 'clean']
}
</pre>
<h2>Gradle Rules for the rest</h2>
<p>Finally, you can use a Gradle Rule to allow for calling any arbitrary target in a GradleBuild bootstrapped import.</p>
<pre class="brush: groovy; title: ; notranslate">
tasks.addRule(&quot;Pattern: a-&lt;target&gt; will execute a single &lt;target&gt; in the ant build&quot;) { String taskName -&gt;
    if (taskName.startsWith(&quot;a-&quot;)) {
        task(taskName, type: GradleBuild) {
            buildFile = 'buildWithClean.gradle'
            tasks = [taskName - 'a-']
        }
    }
}
</pre>
<p>In this particular example, this can allow you to string together calls as well, but be warned that they execute in completely segregated environments.</p>
<pre class="brush: groovy; title: ; notranslate">
$ gradle a-dist a-clean
</pre>
<h2>Source code</h2>
<p>All of code referenced in this article is <a href="https://github.com/kellyrob99/gradleAntImport">available on github</a> if you&#8217;d like to take a closer look.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/11/13/why-do-i-like-gradle/' rel='bookmark' title='Why do I Like Gradle?'>Why do I Like Gradle?</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/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>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2011/09/18/using-gradle-to-bootstrap-your-legacy-ant-builds/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Groovy/Gradle JSLint Plugin</title>
		<link>http://www.kellyrob99.com/blog/2011/04/03/a-groovygradle-jslint-plugin/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-groovygradle-jslint-plugin</link>
		<comments>http://www.kellyrob99.com/blog/2011/04/03/a-groovygradle-jslint-plugin/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 01:07:31 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ant]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[Gradle]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[GroovyMag]]></category>
		<category><![CDATA[JSLint]]></category>
		<category><![CDATA[kellyrob]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1552</guid>
		<description><![CDATA[This article originally appeared in the January 2011 issue of GroovyMag. Gradle is a build system in which builds are described using a declarative and concise DSL written in the Groovy language. This article describes how you can wrap proven Apache Ant Tasks in a Gradle Plugin to make using them as effortless as possible. [...]<div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2011/09/18/using-gradle-to-bootstrap-your-legacy-ant-builds/' rel='bookmark' title='Using Gradle to Bootstrap your Legacy Ant Builds'>Using Gradle to Bootstrap your Legacy Ant Builds</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/11/13/why-do-i-like-gradle/' rel='bookmark' title='Why do I Like Gradle?'>Why do I Like Gradle?</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>
</div>
]]></description>
			<content:encoded><![CDATA[<p><em>This article originally appeared in the January 2011 issue of <a href="http://www.groovymag.com/">GroovyMag</a>.</em></p>
<blockquote><p>Gradle is a build system in which builds are described using a declarative and concise DSL written in the Groovy language. This article describes how you can wrap proven Apache Ant Tasks in a Gradle Plugin to make using them as effortless as possible. We&#8217;ll also go over some of the tools Gradle provides for building and testing robust Plugin functionality following some easy patterns.</p></blockquote>
<p>Creating new custom Plugins for Gradle is a relatively straightforward and easy process. Within a Plugin it&#8217;s possible to configure a Gradle Project with new properties, dependencies, Tasks &#8211; pretty much anything that you can configure in a build.gradle file can be encapsulated into a Plugin for abstraction, portability and reuse. One of the easier ways to add functionality through a Plugin is to encapsulate an existing Ant Task and enhance it by providing the ease-of-use and configuration that Gradle users have come to expect. Recently, I&#8217;ve been writing a lot more JavaScript and was looking for static analysis tools to help guide me away from &#8216;bad habits&#8217;. The popular choice for static analysis of  JavaScript code seems to be <a href="http://www.jslint.com">JSLint</a>, so here&#8217;s an example of providing that functionality for a Gradle build by wrapping an existing <a href="http://jslint4java.googlecode.com/svn/docs/1.4/ant.html">JSLint task</a> and making it easier to work with.</p>
<p></p>
<h2>Anatomy of a Gradle Plugin</h2>
<p>Gradle plugins can most easily be built using Gradle itself. There is a conveniently available <strong>gradleApi()</strong> method you can call to include the required framework classes, demonstrated in the dependencies section of a build.gradle file shown in Listing 1. For this example we&#8217;re also using the <a href="http://gradle.org/latest/docs/userguide/groovy_plugin.html">Groovy Plugin</a> and <a href="http://www.junit.org/">JUnit</a> for testing, so we will include those dependencies as well.</p>
<pre class="brush: groovy; title: ; notranslate">
dependencies {
    compile gradleApi()
    groovy group: 'org.codehaus.groovy', name: 'groovy', version: '1.7.6'
    testCompile group: 'junit', name: 'junit', version: '4.8.2
}

</pre>
<p><em>Listing 1: The dependencies portion of a build.gradle file for building our Plugin </em></p>
<p>Creating a new Gradle <a href="http://www.gradle.org/latest/docs/javadoc/org/gradle/api/Plugin.html">Plugin</a> is a simple matter of implementing the Gradle interface and its single required method, the skeleton of which is shown in Listing 2. Within the apply method, the Plugin can configure the Project to add Tasks or properties as needed.</p>
<pre class="brush: groovy; title: ; notranslate">
class JSLintPlugin implements Plugin&lt;Project&gt;
{
	void apply(Project project)
	{
		//configure the Project here
	}
}
</pre>
<p><em>Listing 2: Skeleton of the Plugin implementation</em></p>
<p></p>
<h2>Integrating with Ant</h2>
<p>I&#8217;ve never been overly fond of <a href="http://ant.apache.org/">Ant</a>, mostly due to the extremely verbose and repetitive nature of the xml declaration. But the fact remains that Ant has been a primary and well-used build tool for years, and the Tasks written for it have been tried and tested by many developers. The Groovy <a href="http://groovy.codehaus.org/api/groovy/util/AntBuilder.html">AntBuilder</a>, in combination with the facilities Gradle provides for dependency resolution and classpath management, makes it very easy to incorporate existing Ant functionality into a build and abstract most of the details away from the end user. For this plugin, we add the library containing the Ant Task to a custom configuration so that we can have it automatically downloaded and easily resolve the classpath.<br />
Listing 3 shows how the configuration for the JSLint4Java Task could appear in an Ant build.xml file. Note that you&#8217;re on your own here to provide the required library for the classpath.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;taskdef name=&quot;jslint&quot;
         classname=&quot;com.googlecode.jslint4java.ant.JSLintTask&quot;
         classpath=&quot;/path/to/jslint4java-1.4.jar&quot;/&gt;
&lt;target name=&quot;jslint&quot;&gt;
    &lt;jslint options=&quot;undef,white&quot; haltOnFailure=&quot;false&quot;&gt;
        &lt;formatter type=&quot;xml&quot; destfile=&quot;${build.dir}/reports&quot;/&gt;
        &lt;fileset dir=&quot;.&quot; includes=&quot;**/*.js&quot; excludes=&quot;**/server/&quot;/&gt;
    &lt;/jslint&gt;
&lt;/target&gt;
</pre>
<p><em>Listing 3: Configuring the Ant target in a build.xml file</em></p>
<p>Gradle makes it easy to separate the configuration and execution phases of the build, allowing for a Plugin to add an Ant Task to the Gradle Project and expose the (optional) configuration in a build script. In addition, Gradle encourages a pattern of providing a &#8216;convention&#8217; object alongside of a Plugin to clearly separate the concerns.<br />
Listing 4 demonstrates some code from the Plugin implementation that adds a &#8216;jslint&#8217; Task to a Gradle Project, setting the specific options based on a convention object. Note how we extract the classpath using the notation  <strong>project.configurations.jslint.asPath</strong>.</p>
<pre class="brush: groovy; title: ; notranslate">
private static final String TASK_NAME = 'jslint'
private Project project
private JSLintPluginConvention jsLintpluginConvention
...
// some of the code in the apply method
this.jsLintpluginConvention = new JSLintPluginConvention(project)
project.convention.plugins.jslint = jsLintpluginConvention
project.task(TASK_NAME) &lt;&lt; {
    project.file(project.reportsDir).mkdirs()
    logger.info(&quot;Running jslint on project ${project.name}&quot;)
    ant.taskdef(name: TASK_NAME, classname: jsLintpluginConvention.taskName,
        classpath: project.configurations.jslint.asPath)
    ant.&quot;$TASK_NAME&quot;(jsLintpluginConvention.mapTaskProperties()) {
        formatter(type: jsLintpluginConvention.decideFormat(),
                destfile:  jsLintpluginConvention.createOutputFileName())
        jsLintpluginConvention.inputDirs.each { dirName -&gt;
            fileset(dir: dirName,
			 includes: jsLintpluginConvention.includes,
			 excludes: jsLintpluginConvention.excludes)
        }
    }
}
</pre>
<p><em>Listing 4: Adding a jslint Task to a Gradle Project </em></p>
<p>If you&#8217;re not already familiar with the Gradle syntax for creating new Tasks inline, the <strong>project.task(String taskName)</strong> method is called to instantiate a new <a href="http://www.gradle.org/latest/docs/javadoc/org/gradle/api/Task.html">Task</a>, and the &#8216;< <' syntax is used to to push the Task activities into the 'doLast' Task lifecycle phase.<br />
Allowing for configuration of the Task in a build script is as simple as exposing a method named the same as the Task that takes in a Closure parameter and applies that Closure to set properties on the convention object, as shown in Listing 5.</p>
<pre class="brush: groovy; title: ; notranslate">
/**
 * Perform custom configuration of the plugin using the provided closure.
 * @param closure
 */
def jslint(Closure closure)
{
    closure.delegate = this
    closure()
}
</pre>
<p>Listing 5: A method to allow for configuration of the jslint Task from a build script </p>
<p></p>
<h2>The simple use-case</h2>
<p>As per usual when working with Gradle, using this plugin in the most basic case requires only these things:</p>
<ul>
<li>Declare a dependency on the Plugin source.  This can be either a released jar to be downloaded from a repository by Gradle or you can download a jar manually from pretty much anywhere and add it to the classpath directly.</li>
<li>Apply the Plugin to a Gradle build.</li>
<li>Call the jslint Task as part of the build.</li>
</ul>
<p>The entire configuration and usage looks something like Listing 6, assuming that the gradle-jslint-plugin jar is found in /usr/home/gradlelibs.</p>
<pre class="brush: groovy; title: ; notranslate">
/* In a build.gradle file */
buildscript {
	dependencies {
		classpath fileTree(dir: '/usr/home/gradlelibs', include: '*.jar')
	}
}
apply plugin: org.kar.jslint.gradle.plugin.JSLintPlugin

/* and on the command line... */
gradle jslint
</pre>
<p><em>Listing 6: Configuring the jslint Plugin in a build script and calling it from the command line</em></p>
<p>By default, this is enough to scan for all .js files under the directory where the build script is located and create a JSLint text report using the basic settings.</p>
<p></p>
<h2>The not-so-simple case</h2>
<p>Of course in the real world the defaults aren't always what we need, so being able to easily configure the Task is essential. Fortunately, Gradle makes extending a custom Plugin to allow for configuration by a simple Closure, so we can exercise the code from Listing 5 in a build script with the Closure  definition in Listing 7.</p>
<pre class="brush: groovy; title: ; notranslate">
jslint {
	haltOnFailure = false
	excludes = '**/metadata/'
	options = 'rhino'
	formatterType = 'html'
}
</pre>
<p><em>Listing 7: Departing from the default jslint Task configuration </em></p>
<p></p>
<h2>Extending Ant Task capabilities</h2>
<p>The Ant Task as is can produce either a plain text document or an xml report, but transforming the results into a more consumable html format is easy to do using an Ant xslt Task. Having Gradle wrap the Task definition allows for simply adding a new formatter type to the configuration and abstracting away the details from the end user. A copy of <a href="http://code.google.com/p/memwords/source/browse/trunk/jslint/jslint.xsl?r=109">an xsl file available online</a> is easy to incorporate with the plugin and can be used to transform the xml output into a nicely formatted web page.  Being able to program around Ant Tasks like this is a great way to enhance their value in your build. An example of simple output from the test cases included in the Plugin is shown in Figure 1.<br />

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/jslint/figure1.png" title="" class="shutterset_singlepic76" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/76__x_figure1.png" alt="figure1" title="figure1" />
</a>
<br />
<em>Figure 1: Example html formatted output from jslint </em></p>
<p></p>
<h2>Testing using ProjectBuilder</h2>
<p>In order to facilitate testing custom Tasks and Plugins, the Gradle framework provides the <a href="http://www.gradle.org/latest/docs/javadoc/org/gradle/testfixtures/ProjectBuilder.html">ProjectBuilder</a> implementation to handle most of the heavy lifting. This gives you a mocked out instance of a Gradle Project that builds into a temporary directory; very handy for testing how Tasks behave under real working conditions.  Having tools like this available directly from the framework removes a lot of potential barriers that might otherwise discourage testing of custom components. The source code that accompanies this article uses the ProjectBuilder to achieve 100% code coverage of the project and is available on github at <a href="https://github.com/kellyrob99/gradle-jslint-plugin">https://github.com/kellyrob99/gradle-jslint-plugin</a> if you'd like to look closer for some ideas on how to test your own Gradle Plugins. An already built version of the jar is also available if you'd like to try without having to build it yourself: <a href="https://github.com/kellyrob99/gradle-jslint-plugin/blob/master/releases/gradle-jslint-plugin-0.1-SNAPSHOT.jar">https://github.com/kellyrob99/gradle-jslint-plugin/blob/master/releases/gradle-jslint-plugin-0.1-SNAPSHOT.jar</a>.</p>
<p></p>
<h2>How could we improve this Plugin?</h2>
<p>This implementation represents the 'brute-force' method of wrapping an Ant Task, and there are several ways to enhance its function, if we wanted to spend some additional time and effort on the Plugin. It would actually be far more flexible if we extended the Gradle <a href="http://gradle.org/latest/docs/groovydoc/org/gradle/api/DefaultTask.html">DefaultTask</a> to provide the actual functionality; this would allow for the possibility of executing the Task separately against different sets of JavaScript in the same project with different configurations of JSLint. In the case of an application with both client and server-side JavaScript, for instance, you might want to apply different rules. In that event you'd probably also want to have the capability to aggregate multiple result sets, which would be a relatively easy feature to add.<br />
Having a separate Task implementation defined would also make it easier to clearly define the inputs and outputs of the process using one of the <a href="http://gradle.org/latest/docs/javadoc/org/gradle/api/tasks/Input.html">@Input</a> or <a href="http://gradle.org/latest/docs/javadoc/org/gradle/api/tasks/Output.html">@Output</a> Gradle annotations, allowing for incremental builds including JSLint execution. The full set of annotations available from the <a href="http://gradle.org/latest/docs/javadoc/org/gradle/api/tasks/package-summary.html">org.gradle.api.tasks package</a> allow for combining File and/or simple property types to make your Tasks smarter regarding whether or not running again would produce a different result than the last execution.<br />
This article was created using the recently released 0.9 version of Gradle and version 1.4.4 of jslint4java.</p>
<p></p>
<h2>Learn more</h2>
<p>If you'd like to find out some background or more about Gradle and how to create your own custom Plugins and Tasks, you can find some good information on these sites:</p>
<ul>
<li>The Gradle documentation at <a href="http://gradle.org/documentation.html">http://gradle.org/documentation.html</a></li>
<li>In particular, the Project API is a great starting point for getting to know Gradle: <a href="http://gradle.org/latest/docs/javadoc/org/gradle/api/Project.html">http://gradle.org/latest/docs/javadoc/org/gradle/api/Project.html</a></li>
<li>The excellent examples of Mr. Haki at <a href="http://mrhaki.blogspot.com/search/label/Gradle%3AGoodness">http://mrhaki.blogspot.com/search/label/Gradle%3AGoodness</a></li>
<li>Published plugins on github can be found with this search: <a href="https://github.com/search?type=Repositories&amp;language=&amp;q=gradle+plugin">https://github.com/search?type=Repositories&amp;language=&amp;q=gradle+plugin</a> </li>
</ul>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2011/09/18/using-gradle-to-bootstrap-your-legacy-ant-builds/' rel='bookmark' title='Using Gradle to Bootstrap your Legacy Ant Builds'>Using Gradle to Bootstrap your Legacy Ant Builds</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/11/13/why-do-i-like-gradle/' rel='bookmark' title='Why do I Like Gradle?'>Why do I Like Gradle?</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>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2011/04/03/a-groovygradle-jslint-plugin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<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 [...]<div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2012/02/26/hooking-into-the-jenkinshudson-api-part-2/' rel='bookmark' title='Hooking into the Jenkins(Hudson) API, Part 2'>Hooking into the Jenkins(Hudson) API, Part 2</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/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>
</ol>
</div>
]]></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>


<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2012/02/26/hooking-into-the-jenkinshudson-api-part-2/' rel='bookmark' title='Hooking into the Jenkins(Hudson) API, Part 2'>Hooking into the Jenkins(Hudson) API, Part 2</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/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>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2011/03/27/hooking-into-the-jenkinshudson-api/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Why do I Like Gradle?</title>
		<link>http://www.kellyrob99.com/blog/2010/11/13/why-do-i-like-gradle/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=why-do-i-like-gradle</link>
		<comments>http://www.kellyrob99.com/blog/2010/11/13/why-do-i-like-gradle/#comments</comments>
		<pubDate>Sat, 13 Nov 2010 23:53:47 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ant]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[Gradle]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1526</guid>
		<description><![CDATA[Gradle, if you don&#8217;t already know it, is rapidly gaining traction as a strong leader in the next generation of build systems. It builds heavily upon excellent aspects of the Maven and Ant frameworks, yet is pitched as not suffering from the same &#8220;Frameworkitis&#8220;. And I&#8217;ve gotta say &#8211; the results are pretty spectacular. Among [...]<div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2011/09/18/using-gradle-to-bootstrap-your-legacy-ant-builds/' rel='bookmark' title='Using Gradle to Bootstrap your Legacy Ant Builds'>Using Gradle to Bootstrap your Legacy Ant Builds</a></li>
<li><a href='http://www.kellyrob99.com/blog/2011/04/03/a-groovygradle-jslint-plugin/' rel='bookmark' title='A Groovy/Gradle JSLint Plugin'>A Groovy/Gradle JSLint Plugin</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/09/26/groovy-inspecteval-for-externalizing-data/' rel='bookmark' title='Groovy inspect()/Eval for Externalizing Data'>Groovy inspect()/Eval for Externalizing Data</a></li>
</ol>
</div>
]]></description>
			<content:encoded><![CDATA[<p><a href="http://gradle.org/">Gradle</a>, if you don&#8217;t already know it, is rapidly gaining traction as a strong leader in the next generation of build systems. It builds heavily upon excellent aspects of the <a href="http://maven.apache.org/">Maven</a> and <a href="http://ant.apache.org/">Ant</a> frameworks, yet is pitched as not suffering from the same &#8220;<a href="http://www.codinghorror.com/blog/2005/11/conversations-with-erich-gamma.html">Frameworkitis</a>&#8220;. And I&#8217;ve gotta say &#8211; the results are pretty spectacular. Among the major selling features, at least as I see it, are:</p>
<ul>
<li>Groovy syntax and a very terse and descriptive dsl that makes build scripts easily comprehensible</li>
<li>flexibility of layout, configuration, organizing build logic &#8211; pretty much everything</li>
<li>incremental builds, based on an easily implementable pattern</li>
<li>convention over configuration paradigm, thank you very much Maven</li>
<li>clear separation of build configuration from execution</li>
<li>extensibility at every level</li>
</ul>
<h2>The most basic Java build</h2>
<pre class="brush: groovy; title: ; notranslate">
apply plugin: 'java'
</pre>
<p>That&#8217;s it. One line of Groovy in a file called &#8216;build.gradle&#8217; and you can build a Java project with a Maven-standardized project layout.</p>
<pre>
├── build.gradle
└── src
    ├── main
    │   ├── java
    │   └── resources
    └── test
        ├── java
        └── resources
</pre>
<p>Included with the Java plugin are tasks to compile, package, test and javadoc your code. You also get <a href="http://gradle.org/latest/docs/userguide/artifact_dependencies_tutorial.html#sec:artifact_configurations">configuration</a> objects to describe the artifacts that your build depends on and those  that it produces. Of course, with this most basic setup these configurations don&#8217;t yet have anything in them, but in a complex build they&#8217;re very handy for isolating the responsibilities of each task. Because you can both configure the existing configurations and add custom ones yourself, it&#8217;s very easy to accommodate a project that follows a different structure, whether that is just differently named source directories or multiple directories that need specific processing. This is VERY handy for legacy builds.</p>
<h2>Incremental builds</h2>
<p>Gradle provides a very easy way to create tasks that are able to execute only if their declared input and/or output artifacts have changed. This makes it trivial to incorporate your custom build behaviour into an incremental build. As an example I&#8217;d like to expand upon something I read by <a href="http://twitter.com/etiennestuder">Etienne Studer</a> in this month&#8217;s <a href="http://jaxenter.com/jaxmag">JAXmag</a>. It&#8217;s a great example of developing an incremental task. First here&#8217;s the task implementation almost verbatim from the article. I&#8217;ve updated it slightly to make the output more readable using FileUtils, and you can examine the file it spits out from the build/reports/size directory that will be automatically created when it executes.</p>
<pre class="brush: groovy; title: ; notranslate">
class Size extends DefaultTask
{
    @InputFiles FileTree inputDir
    @OutputFile File outputFile

    @TaskAction
    void generate()
    {
        def totalSize = inputDir.files.inject(0) { def size, File file -&gt; size + file.size()
        }
        outputFile.text = FileUtils.byteCountToDisplaySize(totalSize)
    }
}
</pre>
<p>If you simply include this class definition in a build file, it will be automatically compiled and available for use elsewhere in the script. It could just as easily be defined in a separate file(local or remote), in a jar on the classpath or in the buildSrc directory of your Gradle project. This flexibility enables developing and evolving tasks in a very agile fashion, encouraging you to publish the results for reuse instead of re-implementing the logic in other projects.<br />
In order to execute this task as part of a build, we first need to configure it. In this case, I&#8217;m configuring it to work on all declared configurations and all source, both code and associated resources. In order to do so, I&#8217;m using a couple of Gradle internal classes, <a href="http://www.gradle.org/latest/docs/javadoc/org/gradle/api/file/FileTree.html">FileTree</a> and <a href="http://www.gradle.org/latest/docs/javadoc/org/gradle/api/tasks/SourceSet.html">SourceSet</a>, which actually sound pretty self-explanatory to me. The key part is the assignment of the &#8216;inputDir&#8217; and &#8216;outputFile&#8217; properties on the task.</p>
<pre class="brush: groovy; title: ; notranslate">
task size(type:Size){
    def filetree = sourceSets.inject(new UnionFileTree()) { FileTree total, SourceSet sourceSet -&gt;
        total += sourceSet.allSource
        total
    }
    inputDir = filetree
    outputFile = file(&quot;$reportsDir/size/size.txt&quot;)
}
</pre>
<p>Just to prove that it&#8217;s working incrementally, here&#8217;s the output from successive invocations. Note that &#8216;UP-TO-DATE&#8217; in the output that indicates the task was skipped the second time around, because none of the inputs changed and the output file hasn&#8217;t been deleted.</p>
<pre class="brush: groovy; title: ; notranslate">
gradle-intro$ gradle size
:size

BUILD SUCCESSFUL

Total time: 2.963 secs

gradle-intro$ gradle size
:size UP-TO-DATE

BUILD SUCCESSFUL

Total time: 2.912 secs
</pre>
<p>This task does actually have a concrete dependency on the Java plugin, since without that convention applied neither the &#8216;sourceSets&#8217; or &#8216;reportsDir&#8217; objects would be present. Here&#8217;s the complete version of the build file that&#8217;s been built so far, 28 lines including imports and spacing.</p>
<pre class="brush: groovy; title: ; notranslate">
import org.apache.commons.io.FileUtils
import org.gradle.api.internal.file.UnionFileTree
import org.gradle.api.tasks.SourceSet

apply plugin: 'java'           

task size(type:Size){
    def filetree = sourceSets.inject(new UnionFileTree()) { FileTree total, SourceSet sourceSet -&gt;
        total += sourceSet.allSource
        total
    }
    inputDir = filetree
    outputFile = file(&quot;$reportsDir/size/size.txt&quot;)
}

class Size extends DefaultTask
{
    @InputFiles FileTree inputDir
    @OutputFile File outputFile

    @TaskAction
    void generate()
    {
        def totalSize = inputDir.files.inject(0) { def size, File file -&gt; size + file.size()
        }
        outputFile.text = FileUtils.byteCountToDisplaySize(totalSize)
    }
}
</pre>
<h2>Sharing your new Task</h2>
<p>The simplest way to share build logic is to &#8216;apply&#8217; it. This simple shorthand covers everything from plugins to local files to remotely hosted resources. Here&#8217;s how easy it is to incorporate this particular task implementation and configuration into a build using a relative file path.</p>
<pre class="brush: groovy; title: ; notranslate">
apply from : '../gradle-intro/build.gradle'
</pre>
<p>And because only a simple http connection is required to share it to a broader base, here&#8217;s how you can reference a copy on this site. Sorry about the .txt extension, but I didn&#8217;t feel like editing php to allow a new filetype today <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<pre class="brush: groovy; title: ; notranslate">
apply from : 'http://www.kellyrob99.com/blog/wp-content/uploads/downloads/2010/11/gradleSizeTask.txt'
</pre>
<h2>Some other reading</h2>
<p>If you&#8217;re still not sold on Gradle, here&#8217;s some articles I&#8217;ve seen recently that at the very least will give you a better perspective.<br />
<a href="http://community.jboss.org/wiki/Gradlewhy">Hibernate &#8211; Gradle why?</a><br />
<a href="http://jaxenter.com/maven-vs-gradle-vs-ant.1-30682.html">Maven VS Gradle VS Ant</a><br />
Maven to Gradle: <a href="http://www.beeworks.be/maven-to-gradle-part-1/">Part 1</a>, <a href="http://www.beeworks.be/maven-to-gradle-part-2/">Part 2</a>,  <a href="http://www.beeworks.be/maven-to-gradle-part-3/">Part 3</a><br />
<a href="http://kaczanowscy.pl/tomek/2010-11/build-script-length-maven3-polyglot-maven-gradle-ant">A comparison of build script length</a><br />
<a href="http://kaczanowscy.pl/tomek/2009-11/ant-gradle-and-maven-comparison-install-script">Ant/Gradle/Maven comparison</a><br />
<a href="http://java.dzone.com/hibernate-users-learn-gradle">DZone article</a><br />
<a href="http://openmrs-mailing-list-archives.1560443.n2.nabble.com/Maven-vs-Gradle-td4511793.html">OpenMRS Mailing list on Maven VS Gradle</a></p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2011/09/18/using-gradle-to-bootstrap-your-legacy-ant-builds/' rel='bookmark' title='Using Gradle to Bootstrap your Legacy Ant Builds'>Using Gradle to Bootstrap your Legacy Ant Builds</a></li>
<li><a href='http://www.kellyrob99.com/blog/2011/04/03/a-groovygradle-jslint-plugin/' rel='bookmark' title='A Groovy/Gradle JSLint Plugin'>A Groovy/Gradle JSLint Plugin</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/09/26/groovy-inspecteval-for-externalizing-data/' rel='bookmark' title='Groovy inspect()/Eval for Externalizing Data'>Groovy inspect()/Eval for Externalizing Data</a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/11/13/why-do-i-like-gradle/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Groovy inspect()/Eval for Externalizing Data</title>
		<link>http://www.kellyrob99.com/blog/2010/09/26/groovy-inspecteval-for-externalizing-data/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy-inspecteval-for-externalizing-data</link>
		<comments>http://www.kellyrob99.com/blog/2010/09/26/groovy-inspecteval-for-externalizing-data/#comments</comments>
		<pubDate>Sun, 26 Sep 2010 20:32:13 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Bamboo]]></category>
		<category><![CDATA[Eval]]></category>
		<category><![CDATA[Gradle]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Hudson]]></category>
		<category><![CDATA[inspect()]]></category>
		<category><![CDATA[Junit]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1502</guid>
		<description><![CDATA[One of the things I love about Groovy is how easy it makes reading and writing text files. I&#8217;ve written Groovy scripts for everything from parsing log files for extracting timing information to finding (and replacing with selectors) in-line css blocks. Often there&#8217;s a piece of information extracted from a file that I want to [...]<div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2011/09/18/using-gradle-to-bootstrap-your-legacy-ant-builds/' rel='bookmark' title='Using Gradle to Bootstrap your Legacy Ant Builds'>Using Gradle to Bootstrap your Legacy Ant Builds</a></li>
<li><a href='http://www.kellyrob99.com/blog/2011/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/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>
</ol>
</div>
]]></description>
			<content:encoded><![CDATA[<p>One of the things I love about Groovy is how easy it makes reading and writing text files. I&#8217;ve written Groovy scripts for everything from parsing log files for extracting timing information to finding (and replacing with selectors) in-line css blocks. Often there&#8217;s a piece of information extracted from a file that I want to keep for further examination, or just for future reference. The Groovy <a href="http://groovy.codehaus.org/api/org/codehaus/groovy/runtime/DefaultGroovyMethods.html#inspect%28java.lang.Object%29">inspect()</a> method provides a nice easy way to take simple results that are stored in variables and write them to a file. Then the Groovy <a href="http://groovy.codehaus.org/api/groovy/util/Eval.html">Eval</a> class provides convenience methods to parse that information back from the file in a single line. Here&#8217;s examples of test code that creates Lists and Maps, writes them out to a file and then asserts that evaluating the stored Groovy code results in the same data structures.</p>
<pre class="brush: groovy; title: ; notranslate">
    private static final Closure RANDOM_STRING = RandomStringUtils.&amp;randomAlphanumeric
    private static final String TMP_DIR = System.getProperty('java.io.tmpdir')

    @Test
    public void testSerializeListToFile()
    {
        List&lt;String&gt; accumulator = []
        100.times { int i -&gt;
            accumulator &lt;&lt; RANDOM_STRING(i + 1)
        }
        File file = new File(&quot;$TMP_DIR/inspectListTest.groovy&quot;)
        file.deleteOnExit()
        file &lt;&lt; accumulator.inspect()
        assertThat(accumulator, equalTo(Eval.me(file.text)))
    }

    @Test
    public void testSerializeMapToFile()
    {
        Map&lt;String, String&gt; accumulator = [:]
        100.times { int i -&gt;
            accumulator[RANDOM_STRING(i + 1)] = RANDOM_STRING(i + 1)
        }
        File file = new File(&quot;$TMP_DIR/inspectMapTest.groovy&quot;)
        file.deleteOnExit()
        file &lt;&lt; accumulator.inspect()
        assertThat(accumulator, equalTo(Eval.me(file.text)))
    }
</pre>
<p>Two little tidbits of goodness embedded in this example are the ability to capture a method as a closure, in this case RandomStringUtils.randomAlphanumeric(), and the <a href="http://download-llnw.oracle.com/javase/6/docs/api/java/io/File.html#deleteOnExit%28%29">File.deleteOnExit()</a> method &#8211; which is only cool because I never noticed it in the API before and it turns out to be a great way to clean up after tests.<br />
 <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>A particular usage of this technique I&#8217;ve been using lately has been sparked by a shift of tools at work. I&#8217;ve worked with the Atlassian stack of web applications for years now, and have always enjoyed the rich feedback Bamboo gives for build history. But now I&#8217;m using Hudson as the primary continuous integration tool and one of the things I&#8217;ve been sorely missing is the &#8216;Top 10 Longest Running Tests&#8217;.  If you&#8217;re not familiar with this view in Bamboo, stroll on over to <a href="http://bamboo.ci.codehaus.org/browse/GROOVY-DEF17J6EX/test">the Groovy build results page</a> and click on the tab.<br />
One of my present priorities at work is to speed up build times and rooting out slow or inefficient tests is one way to do this. It&#8217;s possible to elicit this information from JUnit test reports using xsl(<a href="http://stackoverflow.com/questions/277923/longest-running-unit-tests">see this link for an example</a>)  but I came up with a nice way to incorporate similar functionality into a Gradle build. Following the <a href="http://gradle.org/">Gradle</a> project-report conventions, this task simply uses the inspect() method to write out a results file in the &#8216;reportsDir&#8217;. I&#8217;ve captured this output(manually) over time to track the progress of speeding up test times, and the format makes it easy to read back in results and do deeper analysis and aggregation &#8211; such as the creation of csv reports and simple graphs for instance.</p>
<pre class="brush: groovy; title: ; notranslate">
tolerance = 2.0
task findLongRunningTests &lt;&lt; {
    description= &quot;find all tests that take over $tolerance seconds to run&quot;
    String testDir = &quot;${project.reportsDir}/tests&quot;.toString()
    file(testDir).mkdirs()
    File file = file(&quot;$testDir/longRunningTests.txt&quot;)
    file.createNewFile()
    BufferedWriter writer = file.newWriter()
    writer &lt;&lt; parseTestResults('**/TESTS-TestSuites.xml', tolerance)
    writer.close()
}

/**
 * Read in xml files in the junit format and extract test names and times
 * @includePattern ant pattern describing junit xml reports to inspect, recursively gathered from the rootDir
 * @tolerance the number of seconds over which tests should be included in the report
 */
private String parseTestResults(includePattern, float tolerance)
{
    def resultMap = [:]
    fileTree(dir: rootDir, include: includePattern).files.each {
        def testResult = new XmlSlurper().parse(it)
        testResult.depthFirst().findAll {it.name() == 'testcase'}.each { testcase -&gt;
            def key = [testcase.@classname.text(), testcase.@name.text()].join(':')
            def value = testcase.@time.text() as float
            resultMap[(key)] = value
        }
    }
    return resultMap.findAll {it.value &gt; tolerance}.sort {-it.value}.inspect()
}
</pre>
<p>Note that this works recursively from the &#8216;rootDir&#8217; of a <a href="http://www.gradle.org/latest/docs/javadoc/org/gradle/api/Project.html">Project</a>, so it is effective for multi-project Gradle builds. Source code for this simple example <a href="http://github.com/kellyrob99/groovy-inspect-eval">is available on github</a> if you want to check it out yourself.</p>
<p>Here&#8217;s a sample result drawn from examining some test output in the Gradle build itself. Only one of the tests executed in WrapperTest takes more than 2 seconds to execute.</p>
<pre class="brush: groovy; title: ; notranslate">
[&quot;org.gradle.api.tasks.wrapper.WrapperTest:testWrapper&quot;:2.37]
</pre>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2011/09/18/using-gradle-to-bootstrap-your-legacy-ant-builds/' rel='bookmark' title='Using Gradle to Bootstrap your Legacy Ant Builds'>Using Gradle to Bootstrap your Legacy Ant Builds</a></li>
<li><a href='http://www.kellyrob99.com/blog/2011/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/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>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/09/26/groovy-inspecteval-for-externalizing-data/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Groovy and CSV: How to Get Your Data Out?</title>
		<link>http://www.kellyrob99.com/blog/2010/07/01/groovy-and-csv-how-to-get-your-data-out/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy-and-csv-how-to-get-your-data-out</link>
		<comments>http://www.kellyrob99.com/blog/2010/07/01/groovy-and-csv-how-to-get-your-data-out/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 21:07:35 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Comma-separated values]]></category>
		<category><![CDATA[csv]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[hsqldb]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[OpenCSV]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Spreadsheet]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1420</guid>
		<description><![CDATA[I don&#8217;t know exactly how many CSV files I&#8217;ve read/written to date, but I&#8217;m willing to bet it&#8217;s a lot. These kind of files are a simple and common way to exchange data and are interoperable with spreadsheet programs as well, making them more easily accessible to non-programmer types. There is some excellent support out [...]<div class='yarpp-related-rss'>

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

<table id="wp-table-reloaded-id-4-no-1" class="wp-table-reloaded wp-table-reloaded-id-4">
<tbody>
	<tr class="row-1 odd">
		<td class="column-1">Atomic Number</td><td class="column-2">Atomic Mass</td><td class="column-3">Name</td><td class="column-4">Symbol</td>
	</tr>
	<tr class="row-2 even">
		<td class="column-1">1</td><td class="column-2">1.00794</td><td class="column-3">Hydrogen</td><td class="column-4">H</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">2</td><td class="column-2">4.002602</td><td class="column-3">Helium</td><td class="column-4">He</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">3</td><td class="column-2">6.941</td><td class="column-3">Lithium</td><td class="column-4">Li</td>
	</tr>
	<tr class="row-5 odd">
		<td class="column-1">4</td><td class="column-2">9.012182</td><td class="column-3">Beryllium</td><td class="column-4">Be</td>
	</tr>
	<tr class="row-6 even">
		<td class="column-1">5</td><td class="column-2">10.811</td><td class="column-3">Boron</td><td class="column-4">B</td>
	</tr>
</tbody>
</table>
<span class="wp-table-reloaded-table-description-id-4 wp-table-reloaded-table-description">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The simple format of the example CSV file.</span>
</p>
<p></p>
<h2>Groovy All by Itself</h2>
<p><a href="http://groovy.codehaus.org/">Groovy</a> makes dealing with String objects pretty painless.  By adding facilities like easy casting and find()/findAll() for quickly turning raw Strings into real data, you can program some fairly complex questions. In this simple example I&#8217;m depending on all values being quoted and I am not protecting against casting problems. I&#8217;m running this through Maven which really helps to keep test data organized; all you have to do is drop your test file in /src/test/resources and it&#8217;s automagically available on the test classpath.<br />
No specific handling is done for different types here; everything is read in as a String and cast to a more specific type as needed. In a &#8216;real&#8217; application you&#8217;re very likely going to encounter mixed alphanumeric data in any given column of data &#8211; &#8216;UNKNOWN&#8217; instead of a number in a column labeled &#8216;Quantity&#8217; for instance &#8211; and be more careful about casting.</p>
<pre class="brush: groovy; title: ; notranslate">
//load and split the file
InputStream inputFile = getClass().classLoader.getResourceAsStream(TEST_FILE_NAME)
String[] lines = inputFile.text.split('\n')
List&lt;String[]&gt; rows = lines.collect {it.split(',')}

/**
 * A little helper method to get rid of the quotes in the input
 * and cast values so they can be compared properly.
 */
private double castToDouble(string)
{
    return string.replaceAll('&quot;', '').toDouble()
}

//OK, it's parsed - let's ask some questions
private static final int ATOMIC_MASS = 1;

def elementsOver200Mass = rows.findAll {castToDouble(it[ATOMIC_MASS]) &gt; 200}
def elementsBetween10And20 = rows.findAll { row -&gt;
            double mass = castToDouble(row[ATOMIC_MASS])
            mass &lt;= 20 &amp;&amp; mass &gt;= 10
}
</pre>
<p>So this approach works fine for well formed input, but falls apart quickly in other cases. For instance, if any columns in the file are missing values the split() function treats them as nulls, leading to different size arrays being stored in the list. Similarly you need to deal with quoted VS non-quoted content, embedded line breaks and other issues individually. Fortunately, some nice guys have done that for us.</p>
<p></p>
<h2>OpenCSV</h2>
<p><a href="http://blogs.bytecode.com.au/glen/">Glen Smith&#8217;s</a> <a href="http://opencsv.sourceforge.net/">OpenCSV</a> library nicely abstracts away a lot of the minutiae of dealing with CSV. It properly deals with escaped characters, multiline input and a host of other issues for you. Give it pretty much anything that satisfies the Reader interface as an input and it&#8217;s good to go. The return type of the CSVReader.readAll() method also satisfies the same contract as the plain Groovy version shown above, so we can interact with the parsed results in exactly the same way as in the previous example.<br />
All values are still typed as Strings, so we need to cast in order to compare numeric values.</p>
<pre class="brush: groovy; title: ; notranslate">
import au.com.bytecode.opencsv.CSVReader

List&lt;String[]&gt; rows = new CSVReader(
        new InputStreamReader(getClass().classLoader.getResourceAsStream(TEST_FILE_NAME)))
            .readAll()

//same finders as in the Groovy version
def elementsOver200Mass = rows.findAll {it[ATOMIC_MASS].toDouble() &gt; 200}
def elementsBetween10And20 = rows.findAll { row -&gt;
    double mass = castToDouble(row[ATOMIC_MASS])
    mass &lt;= 20 &amp;&amp; mass &gt;= 10
}
</pre>
<p></p>
<h2>HsqlDB</h2>
<p>HsqlDB allows for using flat files as <a href="http://hsqldb.org/doc/2.0/guide/texttables-chapt.html">Text Tables</a>, effectively turning a CSV file into a database table. Data values are cast to the types specified in your table definition, so any potential type cast failures happen right up front when loading the data. The benefit is that once the data is read in no further manual processing is necessary. Note: by default the csv file and the database file must be located in the same directory, as a security precaution (can be overridden through configuration).</p>
<p>In addition, leveraging sql makes querying the data extremely easy. Groovy brings in the <a href="http://groovy.codehaus.org/api/groovy/sql/Sql.html">Sql class</a> to abstract away a lot of the normal <a class="zem_slink" title="Java (programming language)" rel="homepage" href="http://java.sun.com">Java</a> boilerplate you encounter when working with a <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/sql/ResultSet.html">ResultSet</a>. I didn&#8217;t do any in-depth testing to prove it out, but this is also the only one of the strategies described here that doesn&#8217;t require holding the entire data in memory in order to do arbitrary queries. That can be mitigated in the previously shown methods by processing files line by line rather than in bulk if memory usage is a concern.</p>
<pre class="brush: groovy; title: ; notranslate">
//create the table definition to insert
String tableName = 'elements'
String tableDefinition = &quot;&quot;&quot;CREATE TEXT TABLE $tableName (
    atomic_number INTEGER PRIMARY KEY,
    atomic_mass NUMERIC,
    name VARCHAR(255),
    symbol VARCHAR(3)
);&quot;&quot;&quot;

//create a new file database and a table corresponding to the csv file
Sql sql = Sql.newInstance(&quot;jdbc:hsqldb:file:${testdbDir.absolutePath}/testdb&quot;, 'sa', ''
    ,'org.hsqldb.jdbcDriver')
sql.execute(tableDefinition)

//set the source to the csv file
sql.execute(&quot;SET TABLE elements SOURCE '${TEST_FILE_NAME};all_quoted=true'&quot;.toString())

//querying the database that's wrapping our CSV file
def elementsOver200Mass = sql.rows(&quot;SELECT * FROM $tableName WHERE atomic_mass &gt; ?&quot;, [200])
def elementsBetween10And20 = sql.rows(
    &quot;SELECT * FROM $tableName WHERE atomic_mass &lt;= ? AND atomic_mass &gt;= ?&quot;, [20, 10])

//simple db aggregates
def count = 0
sql.eachRow(&quot;SELECT count(1) FROM $tableName WHERE atomic_mass &lt;= ?&quot;, [20]){row-&gt;
    count = row[0]
}
def avg = 0
sql.eachRow(&quot;SELECT avg(atomic_mass) FROM $tableName&quot;.toString()){row-&gt;
    avg = row[0]
}
</pre>
<p></p>
<h2>Which One do I Use???</h2>
<p>Pick the one that fits best for your use case is the real answer. I didn&#8217;t know about the HsqlDB option until recently, but OpenCSV has been a personal standby for years. Then again, if you&#8217;re writing something quick and dirty at the script level, the simplicity of just applying a couple of split() operations is pretty appealing. Here&#8217;s how I generally decide.</p>

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

<div class="zemanta-pixie"><a class="zemanta-pixie-a" title="Enhanced by Zemanta" href="http://www.zemanta.com/"><img class="zemanta-pixie-img" src="http://img.zemanta.com/zemified_a.png?x-id=104c23a4-eae4-4092-87ab-7680f9df82e2" alt="Enhanced by Zemanta" /></a><span class="zem-script more-related pretty-attribution"><script src="http://static.zemanta.com/readside/loader.js" type="text/javascript"></script></span></div>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/09/26/groovy-inspecteval-for-externalizing-data/' rel='bookmark' title='Groovy inspect()/Eval for Externalizing Data'>Groovy inspect()/Eval for Externalizing Data</a></li>
<li><a href='http://www.kellyrob99.com/blog/2011/12/04/five-cool-things-you-can-do-with-groovy-scripts/' rel='bookmark' title='Five Cool Things You Can Do With Groovy Scripts'>Five Cool Things You Can Do With Groovy Scripts</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/07/01/groovy-and-csv-how-to-get-your-data-out/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>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 [...]<div class='yarpp-related-rss'>

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/2012/02/26/hooking-into-the-jenkinshudson-api-part-2/' rel='bookmark' title='Hooking into the Jenkins(Hudson) API, Part 2'>Hooking into the Jenkins(Hudson) API, Part 2</a></li>
</ol>
</div>
]]></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>
<div class='yarpp-related-rss'>
<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/2012/02/26/hooking-into-the-jenkinshudson-api-part-2/' rel='bookmark' title='Hooking into the Jenkins(Hudson) API, Part 2'>Hooking into the Jenkins(Hudson) API, Part 2</a></li>
</ol></p>
</div>
]]></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>Achieving Groovy-like Fluency in Java with Google Collections</title>
		<link>http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=achieving-groovy-like-fluency-in-java-with-google-collections</link>
		<comments>http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/#comments</comments>
		<pubDate>Sun, 16 May 2010 05:33:19 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Collections]]></category>
		<category><![CDATA[DataProvider]]></category>
		<category><![CDATA[fluent syntax]]></category>
		<category><![CDATA[GMaven]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[google-collections]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[guava]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[MultiMap]]></category>
		<category><![CDATA[mvn]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[TestNG]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1261</guid>
		<description><![CDATA[One of the most compelling things about using Groovy is the fluent and concise syntax, as well as the productivity and readability gains that come out of it. But there&#8217;s no reason not to take advantage of some of the same techniques and some library support, in this case google-collections, to make Java code easy [...]<div class='yarpp-related-rss'>

Related posts:<ol>
<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>
<li><a href='http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/' rel='bookmark' title='Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;'>Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/19/groovy-and-glazed-lists-with-grape/' rel='bookmark' title='Groovy and Glazed Lists with Grape'>Groovy and Glazed Lists with Grape</a></li>
</ol>
</div>
]]></description>
			<content:encoded><![CDATA[<p>One of the most compelling things about using Groovy is the fluent and concise syntax, as well as the productivity and readability gains that come out of it. But there&#8217;s no reason not to take advantage of some of the same techniques and some library support, in this case <a href="http://code.google.com/p/google-collections/">google-collections</a>, to make Java code easy to write AND to read.</p>
<h2>Creating Collections</h2>
<p>Groovy really shines for this one, making the creation of Lists and Maps, empty or populated, an absolute breeze. Java has some help for creating basic Lists but begins to struggle when creating maps. This is an area that google-collections can help in, especially in regards to creating immutable Maps.</p>
<pre class="brush: groovy; title: ; notranslate">
//Empty Lists
        List&lt;String&gt; groovyList = []
        List&lt;String&gt; javaList = new ArrayList&lt;String&gt;()
        List&lt;String&gt; googleList = Lists.newArrayList()  //can omit generics

//Populated Lists
        List&lt;String&gt; groovyList = [&quot;1&quot;, &quot;2&quot;]
        List&lt;String&gt; javaList = Arrays.asList(&quot;1&quot;, &quot;2&quot;)
        List&lt;String&gt; googleList = Lists.newArrayList(&quot;1&quot;, &quot;2&quot;)

//Immutable Lists
        List&lt;String&gt; groovyList = [&quot;1&quot;, &quot;2&quot;].asImmutable()
        List&lt;String&gt; javaList = Collections.unmodifiableList(Arrays.asList(&quot;1&quot;, &quot;2&quot;))
        List&lt;String&gt; googleList = ImmutableList.of(&quot;1&quot;, &quot;2&quot;)

//Empty Maps
        Map&lt;String, String&gt; groovyMap = [:]
        Map&lt;String, String&gt; javaMap = new LinkedHashMap&lt;String,String&gt;()
        Map&lt;String, String&gt; googleMap = Maps.newLinkedHashMap()

//Immutable Maps
        Map&lt;String, String&gt; groovyMap = [&quot;a&quot;:&quot;1&quot;, &quot;b&quot;:&quot;2&quot;].asImmutable()

        Map&lt;String, String&gt; javaMap = new LinkedHashMap&lt;String,String&gt;()
        javaMap.put(&quot;a&quot;, &quot;1&quot;)
        javaMap.put(&quot;b&quot;, &quot;2&quot;)
        javaMap = Collections.unmodifiableMap(javaMap)

        //OR(works only in Java, will not compile in Groovy)
        Map&lt;String, String&gt; javaMap = new LinkedHashMap&lt;String, String&gt;()
        {
            {
                put(&quot;a&quot;, &quot;1&quot;);
                put(&quot;b&quot;, &quot;2&quot;);
            }
        };

        Map&lt;String, String&gt; googleMap = ImmutableMap.of(&quot;a&quot;, &quot;1&quot;, &quot;b&quot;, &quot;2&quot;)  //clunky syntax but it works
</pre>
<h2>Filtering Collections</h2>
<p>Groovy provides the very handy &#8216;findAll&#8217; method that allows you to filter a Collection by applying a Closure. Google-collections provides similar facilities using the Predicate interface and two filter methods available statically on Collections2 and Iterables. This would also be a lot more readable if the Predicate definition were extracted but I wanted to show that it&#8217;s still possible to create them in-line quickly.</p>
<pre class="brush: groovy; title: ; notranslate">
import static com.google.common.collect.Collections2.*

List&lt;Integer&gt; toFilter = [1, 2, 3, 4, 5]
List&lt;Integer&gt; groovyVersion = toFilter.findAll{ it &lt; 3}
List&lt;Integer&gt; googleVersion = filter(toFilter, new Predicate&lt;Integer&gt;()
    {
        public boolean apply(Integer input)
        {
            return input &lt; 3;
        }
    };)
</pre>
<h2>Joining Collections into a String Representation</h2>
<p>This one has come up pretty often over the years, and it&#8217;s not surprising that where the JDK hasn&#8217;t provided, enterprising developers have added support through libraries. The problem is: given a Collection of objects, create a String representation of that Collection suitable for view from a consumer of the system. And admit it &#8211; the first time you hand-coded the algorithm you left a trailing comma, didn&#8217;t you? I know I did.<br />
Groovy has fantastic support for this use-case by simply including the &#8216;join&#8217; method on Lists. Google-collections utilizes static calls on the Joiner class along with a simple DSL-like syntax to achieve the same effect. Throw in a static import to make it even more concise and it does a fine job. These two examples yield the same result.</p>
<pre class="brush: groovy; title: ; notranslate">
import static com.google.common.base.Joiner.*
def toJoin = ['a', 'b', 'c']
def separator = ', '

//groovy version
def groovyJoin = toJoin.join(separator)

//google-collections version
def googleJoin = on(separator).join(toJoin)

</pre>
<p>And google-collections also supports join for Maps, something missing from Groovy(although not very hard to implement).</p>
<pre class="brush: groovy; title: ; notranslate">
import static com.google.common.base.Joiner.*
def toJoin = [1: 'a', 2: 'b', 3: 'c']
def separator = ', '
def keyValueSeparator = ':'

//results in '1:a, 2:b, 3:c' which is essentially what is returned from Groovy map.toMapString()
def googleVersion = on(separator).withKeyValueSeparator(keyValueSeparator).join(map)

//results in '1 is a and 2 is b and 3 is c'
googleVersion = on(&quot; and &quot;).withKeyValueSeparator(&quot; is &quot;).join(map)

//doing the same in Groovy is slightly more involved, but really not that bad
def groovyVersion = toJoin.inject([]) {builder, entry -&gt;
            builder &lt;&lt; &quot;${entry.key} is ${entry.value}&quot;
            builder
        }.join(' and ')
</pre>
<h2>Multimaps</h2>
<p>Multimaps are one of the more interesting parts of google-collections, at least to me. Have you ever found yourself writing code to create a Map of keys to Lists? Well the various <a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Multimap.html">Multimap</a> implementations in google-collections mean you never have to write that boilerplate kind of code again. Here&#8217;s a &#8220;first-stab&#8221; effort to simulate a fairly generic Multimap with pure Java code.</p>
<pre class="brush: groovy; title: ; notranslate">
public class JavaMultimap
{
    private Map&lt;Object, List&lt;Object&gt;&gt; multimap = new LinkedHashMap&lt;Object, List&lt;Object&gt;&gt;();

    public boolean put(Object key, Object value)
    {
        List&lt;object&gt; objects = multimap.get(key);
        objects = objects != null ? objects : new ArrayList&lt;object&gt;();
        objects.add(value);
        multimap.put(key, objects);
        return true;
    }
}
</pre>
<p>
And the same thing in Groovy, achieving a slightly smaller version.</p>
<pre class="brush: groovy; title: ; notranslate">
class GroovyMultimap
{
    Map map = [:]

    public boolean put(Object key, Object value)
    {
        List list = map.get(key, [])
        list.add(value)
        map.&quot;$key&quot; = list
    }
}
</pre>
<p>I did some primitive timings comparing Java, Groovy and google-collections Multimaps implementations and, as you&#8217;d pretty much expect, google clearly takes the lead.  Where things really start to get interesting though is when you start using the Multimap in Groovy code. Imagine if you will that you want to iterate over a collection of Objects and map some of the properties to a List. Here&#8217;s a contrived example of what I&#8217;m talking about, but applying this same pattern to domain objects in your application or even a directory full of xml files is pretty much the same. If you look closely you&#8217;ll notice that Groovy actually makes this a one liner to extract all values for a property across a List of Objects(used in the assertion), but I imagine that Multimap is probably a better alternative for large data sets.</p>
<pre class="brush: groovy; title: ; notranslate">
class GoogleCollectionsMultiMapTest
{
    private Random random = new Random()

    @Test
    public void testMultimap()
    {
        def list = []
        10.times {
            list &lt;&lt; createObject()
        }
        List properties = ['value1', 'value2', 'value3']
        Multimap multimap = list.inject(LinkedListMultimap.create()) {Multimap map, object -&gt;
            properties.each {
                map.put(it, object.&quot;$it&quot;)
            }
            map
        }
        properties.each {
            assertEquals (multimap.get(it), list.&quot;$it&quot;)
        }
    }

    Object createObject()
    {
        Expando expando = new Expando()
        expando.value1 =  random.nextInt(10) + 1
        expando.value2 =  random.nextInt(100) + 100
        expando.value3 =  random.nextInt(50) + 50
        return expando
    }
}
</pre>
<h2>So Where Does This Get Us?</h2>
<p>Between google-collections and <a href="http://code.google.com/p/guava-libraries/">the newer guava-libraries</a> that contain it, there&#8217;s lots of help available for simplifying programming problems and making your code more readable. I haven&#8217;t even touched on the newly available support for primitives, Files, Streams and more, but if you&#8217;re interested in reducing the amount of code you write AND simultaneously making it more readable you should probably take a look. There&#8217;s a very nice overview available in <a href="http://codemunchies.com/2009/10/beautiful-code-with-google-collections-guava-and-static-imports-part-1/">part one</a> and <a href="http://codemunchies.com/2009/10/diving-into-the-google-guava-library-part-2/">part two</a> by <a href="http://twitter.com/astensby">Aleksander Stensby</a>.  And here&#8217;s a <a href="http://bwinterberg.blogspot.com/2009/09/introduction-to-google-collections.html">closer look at what google-collections can do for you</a>.</p>
<h2>Source Code</h2>
<p>As per usual, source code is <a href="http://github.com/kellyrob99/groovy-google-collections">available at github as a maven project</a>. Big thanks to the Spock team for sharing <a href="http://old.nabble.com/GMaven-and-Groovy-1.7-td27378212.html">how they configure GMaven to properly utilize Groovy 1.7</a>.  Please feel free to take a look and comment here. Thanks!</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<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>
<li><a href='http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/' rel='bookmark' title='Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;'>Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/19/groovy-and-glazed-lists-with-grape/' rel='bookmark' title='Groovy and Glazed Lists with Grape'>Groovy and Glazed Lists with Grape</a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 19.485 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2013-05-21 11:31:29 -->
