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

<channel>
	<title>The Kaptain on ... stuff &#187; maven</title>
	<atom:link href="http://www.kellyrob99.com/blog/tag/maven/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kellyrob99.com/blog</link>
	<description>Tales of development, life and the folly that goes along with both</description>
	<lastBuildDate>Sun, 04 Dec 2011 21:51:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>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 [...]
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>]]></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>
<!-- AdSense Now! V1.95 -->
<!-- Post[count: 2] -->
<div class="adsense adsense-leadout" style="float:right;margin: 12px;"><script type="text/javascript"><!--
google_ad_client = "pub-6955914197200080";
/* 728x90, created 8/3/09 */
google_ad_slot = "4051815125";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/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>]]></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>0</slash:comments>
		</item>
		<item>
		<title>Why do I Like Gradle?</title>
		<link>http://www.kellyrob99.com/blog/2010/11/13/why-do-i-like-gradle/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=why-do-i-like-gradle</link>
		<comments>http://www.kellyrob99.com/blog/2010/11/13/why-do-i-like-gradle/#comments</comments>
		<pubDate>Sat, 13 Nov 2010 23:53:47 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ant]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[Gradle]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[theKaptain]]></category>

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

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

BUILD SUCCESSFUL

Total time: 2.963 secs

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

BUILD SUCCESSFUL

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

apply plugin: 'java'           

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

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

    @TaskAction
    void generate()
    {
        def totalSize = inputDir.files.inject(0) { def size, File file -&gt; size + file.size()
        }
        outputFile.text = FileUtils.byteCountToDisplaySize(totalSize)
    }
}
</pre>
<h2>Sharing your new Task</h2>
<p>The simplest way to share build logic is to &#8216;apply&#8217; it. This simple shorthand covers everything from plugins to local files to remotely hosted resources. Here&#8217;s how easy it is to incorporate this particular task implementation and configuration into a build using a relative file path.</p>
<pre class="brush: groovy; title: ; notranslate">
apply from : '../gradle-intro/build.gradle'
</pre>
<p>And because only a simple http connection is required to share it to a broader base, here&#8217;s how you can reference a copy on this site. Sorry about the .txt extension, but I didn&#8217;t feel like editing php to allow a new filetype today <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<pre class="brush: groovy; title: ; notranslate">
apply from : 'http://www.kellyrob99.com/blog/wp-content/uploads/downloads/2010/11/gradleSizeTask.txt'
</pre>
<h2>Some other reading</h2>
<p>If you&#8217;re still not sold on Gradle, here&#8217;s some articles I&#8217;ve seen recently that at the very least will give you a better perspective.<br />
<a href="http://community.jboss.org/wiki/Gradlewhy">Hibernate &#8211; Gradle why?</a><br />
<a href="http://jaxenter.com/maven-vs-gradle-vs-ant.1-30682.html">Maven VS Gradle VS Ant</a><br />
Maven to Gradle: <a href="http://www.beeworks.be/maven-to-gradle-part-1/">Part 1</a>, <a href="http://www.beeworks.be/maven-to-gradle-part-2/">Part 2</a>,  <a href="http://www.beeworks.be/maven-to-gradle-part-3/">Part 3</a><br />
<a href="http://kaczanowscy.pl/tomek/2010-11/build-script-length-maven3-polyglot-maven-gradle-ant">A comparison of build script length</a><br />
<a href="http://kaczanowscy.pl/tomek/2009-11/ant-gradle-and-maven-comparison-install-script">Ant/Gradle/Maven comparison</a><br />
<a href="http://java.dzone.com/hibernate-users-learn-gradle">DZone article</a><br />
<a href="http://openmrs-mailing-list-archives.1560443.n2.nabble.com/Maven-vs-Gradle-td4511793.html">OpenMRS Mailing list on Maven VS Gradle</a></p>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2011/09/18/using-gradle-to-bootstrap-your-legacy-ant-builds/' rel='bookmark' title='Using Gradle to Bootstrap your Legacy Ant Builds'>Using Gradle to Bootstrap your Legacy Ant Builds</a></li>
<li><a href='http://www.kellyrob99.com/blog/2011/04/03/a-groovygradle-jslint-plugin/' rel='bookmark' title='A Groovy/Gradle JSLint Plugin'>A Groovy/Gradle JSLint Plugin</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/09/26/groovy-inspecteval-for-externalizing-data/' rel='bookmark' title='Groovy inspect()/Eval for Externalizing Data'>Groovy inspect()/Eval for Externalizing Data</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/11/13/why-do-i-like-gradle/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Achieving Groovy-like Fluency in Java with Google Collections</title>
		<link>http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=achieving-groovy-like-fluency-in-java-with-google-collections</link>
		<comments>http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/#comments</comments>
		<pubDate>Sun, 16 May 2010 05:33:19 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Collections]]></category>
		<category><![CDATA[DataProvider]]></category>
		<category><![CDATA[fluent syntax]]></category>
		<category><![CDATA[GMaven]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[google-collections]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[guava]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[MultiMap]]></category>
		<category><![CDATA[mvn]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[TestNG]]></category>
		<category><![CDATA[theKaptain]]></category>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=496</guid>
		<description><![CDATA[I&#8217;ve been asked by my friend and co-worker Manfred Moser to give a presentation at next month&#8217;s Vancouver Island Java user&#8217;s group meeting, and silly me I said yes before remembering that speaking in front of people always makes me feel quesy and light-headed. Thanks Manfred for the kind invitation; I&#8217;ll do my best to [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/08/27/vijug-griffongroovy-presentation/' rel='bookmark' title='VIJUG Griffon/Groovy Presentation'>VIJUG Griffon/Groovy Presentation</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/02/11/a-one-day-griffon-applicationpresentation/' rel='bookmark' title='A One Day Griffon Application/Presentation'>A One Day Griffon Application/Presentation</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been asked by my friend and co-worker <a href="http://www.mosabuam.com/">Manfred Moser</a> to give a presentation at next month&#8217;s <a href="http://www.mosabuam.com/vijug/blog/2009/07/26/august-2009-vijug-meeting-griffon/">Vancouver Island Java user&#8217;s group meeting</a>, and silly me I said yes before remembering that speaking in front of people always makes me feel quesy and light-headed. Thanks Manfred for the kind invitation; I&#8217;ll do my best to make it a good show.</p>
<p>No sooner had Manfred let loose a message on the Tweetosphere than <a href="http://www.jroller.com/aalmiray/">Andres Almiray</a> very graciously offered up some free copies of the upcoming book <a href="http://www.manning.com/almiray/">Griffon in Action</a> to give away at the meeting. Thanks for that Andres!</p>
<p>The company I work for, <a href="http://genologics.com/">Genologics</a>, also gave me permission to publish a presentation that I gave recently at work as a Groovy primer for other members of the development staff. Thanks for that Cliff!</p>
<p>I demonstrated some code in SwingPad and created an application using a <a href="http://groovy.codehaus.org/GMaven">GMaven</a> archetype to show off some of the sweetness that Groovy adds to the Java toolbox. It&#8217;s worth noting that even though that page doesn&#8217;t say it, GMaven recently released a 1.0 final verison(NICE!)</p>
<p>I&#8217;ve attached the presentation and some of the source code examples for anyone who might be interested, including the maven project that contains a variety of MOP, builder and GDK extension samples.</p>
<p><a rel="attachment wp-att-522" href="http://www.kellyrob99.com/blog/2009/07/16/presenting-a-groovygriffon-talk/groovytalk-3/">GroovyTalk</a></p>
<p><a rel="attachment wp-att-499" href="http://www.kellyrob99.com/blog/2009/07/16/presenting-a-groovygriffon-talk/groovydemo/">groovyDemo</a></p>
<p><a rel="attachment wp-att-501" href="http://www.kellyrob99.com/blog/2009/07/16/presenting-a-groovygriffon-talk/swingpad1/">SwingPad1</a></p>
<p><a rel="attachment wp-att-502" href="http://www.kellyrob99.com/blog/2009/07/16/presenting-a-groovygriffon-talk/groovymailroute/">GroovyMailRoute</a></p>
<p><a rel="attachment wp-att-503" href="http://www.kellyrob99.com/blog/2009/07/16/presenting-a-groovygriffon-talk/prefusebuilder/">Prefusebuilder</a></p>
<p><a rel="attachment wp-att-504" href="http://www.kellyrob99.com/blog/2009/07/16/presenting-a-groovygriffon-talk/swingthreadingexample/">SwingThreadingExample</a></p>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" title="Reblog this post [with Zemanta]" href="http://reblog.zemanta.com/zemified/0148208a-a39e-4433-b233-3dc914a7f1ab/"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=0148208a-a39e-4433-b233-3dc914a7f1ab" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script src="http://static.zemanta.com/readside/loader.js" type="text/javascript"></script></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/08/27/vijug-griffongroovy-presentation/' rel='bookmark' title='VIJUG Griffon/Groovy Presentation'>VIJUG Griffon/Groovy Presentation</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/02/11/a-one-day-griffon-applicationpresentation/' rel='bookmark' title='A One Day Griffon Application/Presentation'>A One Day Griffon Application/Presentation</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/07/16/presenting-a-groovygriffon-talk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gracelets and Seam &#8211; a DSL for Facelets and Groovy with easy integration</title>
		<link>http://www.kellyrob99.com/blog/2009/05/10/gracelets-and-seam-a-dsl-for-facelets-with-easy-integration/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=gracelets-and-seam-a-dsl-for-facelets-with-easy-integration</link>
		<comments>http://www.kellyrob99.com/blog/2009/05/10/gracelets-and-seam-a-dsl-for-facelets-with-easy-integration/#comments</comments>
		<pubDate>Mon, 11 May 2009 04:16:38 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Facelets]]></category>
		<category><![CDATA[Gracelets]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JBoss Seam]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[XML]]></category>

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

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

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

<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/4fdd0aeb-98bb-4937-b9ad-e5a5d2f4eb93/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=4fdd0aeb-98bb-4937-b9ad-e5a5d2f4eb93" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/07/26/streamingmarkupbuilder-for-groovy-er-xml/' rel='bookmark' title='StreamingMarkupBuilder for Groovy-er xml'>StreamingMarkupBuilder for Groovy-er xml</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/' rel='bookmark' title='Groovy and Hibernate Validator for Dynamic Constraints'>Groovy and Hibernate Validator for Dynamic Constraints</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/01/07/bamboo-grails-and-git-for-continuous-integration/' rel='bookmark' title='Bamboo, Grails and Git for Continuous Integration'>Bamboo, Grails and Git for Continuous Integration</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/05/10/gracelets-and-seam-a-dsl-for-facelets-with-easy-integration/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Groovy and Bash &#8211; can scripting get much easier?</title>
		<link>http://www.kellyrob99.com/blog/2009/04/14/groovy-and-bash-can-scripting-get-much-easier/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy-and-bash-can-scripting-get-much-easier</link>
		<comments>http://www.kellyrob99.com/blog/2009/04/14/groovy-and-bash-can-scripting-get-much-easier/#comments</comments>
		<pubDate>Wed, 15 Apr 2009 03:25:02 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Apache Camel]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[dependency management]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Ivy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Scripting language]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=292</guid>
		<description><![CDATA[The ability to execute pretty much any bash statement embedded in a Groovy script is great, don&#8217;t get me wrong, but with the advent of Grape &#8211; and provided that you&#8217;re an Ivy/Maven user &#8211; adding the abilities of just about any Java library to your scripting language is easy. So what does Groovy add [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/04/03/griffon-bash-completion/' rel='bookmark' title='Griffon bash completion&#8230;'>Griffon bash completion&#8230;</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/08/09/using-the-testng-dataprovider-with-groovy/' rel='bookmark' title='Using the TestNG DataProvider with Groovy'>Using the TestNG DataProvider with Groovy</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/' rel='bookmark' title='Groovy and Hibernate Validator for Dynamic Constraints'>Groovy and Hibernate Validator for Dynamic Constraints</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>The ability to execute pretty much any bash statement embedded in a Groovy script is great, don&#8217;t get me wrong, but with the advent of <a href="http://groovy.codehaus.org/Grape">Grape</a> &#8211; and provided that you&#8217;re an <a href="http://ant.apache.org/ivy/">Ivy</a>/Maven user &#8211; adding the abilities of just about any Java library to your scripting language is easy.</p>
<p>So what does <a href="http://groovy.codehaus.org">Groovy</a> add to the mix to make it an attractive option on top of(or instead of) bash on its own? Dependency management, lean distribution and testability all jump to mind.</p>
<h3 style="text-align: center;">Dependency Management</h3>
<p>Grape gives you the same stability that Maven provides. Any script can load any Java library is wants to utilize into the classpath at runtime using your existing repository or an available internet connection.</p>
<h3 style="text-align: center;">Lean Distribution</h3>
<p>Because Grape utilizes a central repository, all dependencies are shared across the entire system. Scripts with extremely small footprints can do some pretty big things. Recently I&#8217;ve seen examples of <a href="http://www.infoq.com/articles/groovy-1-6">parsing html using TagSoup</a>(I swear I originally saw that example somewhere else but for the life of me can&#8217;t find it now), <a href="http://mrhaki.blogspot.com/2009/04/poll-for-e-mail-with-groovy-and-apache.html">Apache Camel integration</a>(<a href="http://java.dzone.com/news/groovy-example-activemq-broker?mz=7893-progress">and again</a>) and even spawning a local HSQL database, <a href="http://groovy.codehaus.org/Using+Hibernate+with+Groovy">complete with Hibernate</a>. Within a very sparse number of lines, you can do more than you could ever imagine with plain Java, and I&#8217;m more than willing to admit that I wouldn&#8217;t know where to start with bash to do any of the stuff I just mentioned.</p>
<h3 style="text-align: center;">Testability</h3>
<p>The only thing that separates a stand-alone Groovy script from a Groovy class on the command line is the #!. If you&#8217;re willing to launch the script on the command line explicitly using the &#8216;groovy&#8217; executable you can abandon that. So now the difference becomes &#8216;./groovyScript&#8217; versus &#8216;groovy groovyScript&#8217;. But&#8230;. that same script is now ripe and ready to be included in the test framework you use everyday for regular project development. You can easily compose it into unit-testable methods and treat it like any other part of a large and rapidly evolving software project &#8211; things that I&#8217;ve always found inherently difficult with a command line script. Mostly I find that the truly useful scripts and snippets &#8211; the ones that are used regularly by developers on a day to day basis &#8211; are the ones that also never end up under source control, and don&#8217;t get the benefit of evolutionary change that most code gets.</p>
<p>Building upon the example included in the <a href="http://www.infoq.com/articles/groovy-1-6">InfoQ Groovy 1.6 launch notice</a>, here&#8217;s the quick and dirty addition of a JXTable component for showing the results of parsing all links from an html page with TagSoup. A text field is used to bind the url and a click of the button starts it off.  It&#8217;s not pretty, but it did take less than 10 minutes to do so judge for yourself. Run this script from the command line using the groovy command (V1.6+).</p>
<pre class="brush: groovy; smart-tabs: true; title: ; notranslate">
import org.jdesktop.swingx.JXTable
import javax.swing.*

@Grab(group='org.swinglabs', module='swingx', version='0.9.3')
@Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7')
def getHtml(url) {
       def parser = new XmlParser(new org.ccil.cowan.tagsoup.Parser())
       parser.parse(url)
}
def data = [ ]

def my = groovy.swing.SwingBuilder.build {
       frame = frame(title:'Groovy Grab Test', size:[800,500], show:true, pack:true, defaultCloseOperation: WindowConstants.DISPOSE_ON_CLOSE) {
       actions(){
             action(name:'Fetch', id:'fetchAction')
             {
                   data.clear
                   getHtml(urlField.text).body.'**'.a.@href.each{ data &lt;&lt; [url:it] }
                   frame.repaint()
             }
       }
       boxLayout(axis: BoxLayout.Y_AXIS)
       scrollPane() {
             myTable = table(new JXTable(columnControlVisible:true)){
                   tableModel(list:data){
                   propertyColumn(header: 'URL', propertyName: 'url')
             }
       }
 }
       textField(id:'urlField')
       button(fetchAction)
 }
}
</pre>
<p>Since I work for an organization that uses maven extensively for dependency management, most of the libraries that come to mind as handy bash replacements are already available in my local repository. Apache commons, Google collections, and most importantly &#8211; any libraries that are specifically dealing with your own products &#8211; all are at your fingertips! Even better, since most of the tasks that commonly fall to scripting are pretty low level (moving files around, etc), there are easy alternatives.</p>
<p>AntBuilder, for instance, is baked into Groovy, and provides a great abstraction around most of the desired functionality you want in a scripting environment. Moving files, doing text replacement,tarring files, sending mail &#8211; anything that Apache Ant can do, AntBuilder can do. But without all of that infuriating and frustating xml. An example(complete with exception handling!) courtesy of <a href="http://thediscoblog.com/">Andrew Glover</a>, <a href="http://www.ibm.com/developerworks/library/j-pg12144.html">in this article</a>.</p>
<pre class="brush: groovy; title: ; notranslate">
ant = new AntBuilder()
ant.mkdir(dir:&quot;/dev/projects/ighr/binaries/&quot;)

try{
       ant.javac(srcdir:&quot;/dev/projects/ighr/src&quot;,
       destdir:&quot;/dev/projects/ighr/binaries/&quot; )

}catch(Throwable thr){
       ant.mail(mailhost:&quot;mail.anywhere.com&quot;, subject:&quot;build failure&quot;){
             from(address:&quot;buildmaster@anywhere.com&quot;, name:&quot;buildmaster&quot;)
             to(address:&quot;dev-team@anywhere.com&quot;, name:&quot;Development Team&quot;)
             message(&quot;Unable to compile ighr's source.&quot;)
       }
}
</pre>
<p>Where you REALLY need it, you of course are still able to call on any and all of the *nix powertools you might like in a Groovy script. Personally, more and more I find that building and testing the script in my chosen IDE, and using the libraries I&#8217;m most comfortable with to do it, is a much more productive and enjoyable experience.</p>
<p>P.S. Gotta apologize about the code formatting &#8211; if anyone knows a wordpress syntax highlighting plugin that DOESN&#8217;T blow away your formatting or randomly replace the text with html entities, gimme a shout please!</p>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/04/03/griffon-bash-completion/' rel='bookmark' title='Griffon bash completion&#8230;'>Griffon bash completion&#8230;</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/08/09/using-the-testng-dataprovider-with-groovy/' rel='bookmark' title='Using the TestNG DataProvider with Groovy'>Using the TestNG DataProvider with Groovy</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/' rel='bookmark' title='Groovy and Hibernate Validator for Dynamic Constraints'>Groovy and Hibernate Validator for Dynamic Constraints</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/04/14/groovy-and-bash-can-scripting-get-much-easier/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Griffon bash completion&#8230;</title>
		<link>http://www.kellyrob99.com/blog/2009/04/03/griffon-bash-completion/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=griffon-bash-completion</link>
		<comments>http://www.kellyrob99.com/blog/2009/04/03/griffon-bash-completion/#comments</comments>
		<pubDate>Sat, 04 Apr 2009 05:18:13 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[Griffon]]></category>
		<category><![CDATA[MacPorts]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[mvn]]></category>
		<category><![CDATA[Shell]]></category>
		<category><![CDATA[Unix]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=152</guid>
		<description><![CDATA[&#8230; means I don&#8217;t have to remember all of the available Griffon commands. My primary development platform is a Mac, so I used MacPorts to install the bash-completion package long ago. This script is based entirely on the excellent maven completion script documented here on willcodeforbeer. It does the same job for Griffon and includes [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/04/14/groovy-and-bash-can-scripting-get-much-easier/' rel='bookmark' title='Groovy and Bash &#8211; can scripting get much easier?'>Groovy and Bash &#8211; can scripting get much easier?</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/03/swingset-on-griffon/' rel='bookmark' title='SwingSet on Griffon'>SwingSet on Griffon</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/08/griffon-swingx-fest-testing/' rel='bookmark' title='Griffon SwingX Fest testing'>Griffon SwingX Fest testing</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>&#8230; means I don&#8217;t have to remember all of the available Griffon commands. My primary development platform is a Mac, so I used <a href="http://www.macports.org/">MacPorts</a> to install the <a href="http://www.caliban.org/bash/#completion">bash-completion</a> package long ago.<br />
This script is based entirely on the excellent maven completion script documented here on <a href="http://willcode4beer.com/tips.jsp?set=tabMaven">willcodeforbeer</a>. It does the same job for Griffon and includes commands for the plugins I&#8217;m using.</p>
<pre class="brush: bash; smart-tabs: true; title: ; notranslate">
# Griffon completion for the bash shell
#
_griffon()
{
   local cmds cur colonprefixes
   cmds=&quot;bootstrap clean compile console create-app           \
      create-fest-test create-integration-test create-mvc     \
      create-plugin create-script  create-unit-test           \
      create-fest-test run-fest -cobertura help init          \
      install-plugin list-plugins package package-plugin      \
      plugin-info release-plugin run-app run-applet run-fest  \
      run-webstart set-proxy set-version shell stats test-app \
      test-app-cobertura uninstall-plugin upgrade&quot;
   COMPREPLY=()
   cur=${COMP_WORDS[COMP_CWORD]}
   # Work-around bash_completion issue where bash interprets a colon
   # as a separator.
   # Work-around borrowed from the darcs work-around for the same
   # issue.
   colonprefixes=${cur%&quot;${cur##*:}&quot;}
   COMPREPLY=( $(compgen -W '$cmds'  -- $cur))
   local i=${#COMPREPLY[*]}
   while [ $((--i)) -ge 0 ]; do
      COMPREPLY[$i]=${COMPREPLY[$i]#&quot;$colonprefixes&quot;}
   done

        return 0
} &amp;&amp;
complete -F _griffon griffon
</pre>
<p>Add this to your .bash_profile file and you&#8217;re good to go for saving a whole bunch of keystrokes and calls to &#8216;griffon help&#8217;. </p>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/86bba6a2-47f8-4f4d-ab3c-18b78b9e3fa5/" title="Zemified by Zemanta"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=86bba6a2-47f8-4f4d-ab3c-18b78b9e3fa5" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2009/04/14/groovy-and-bash-can-scripting-get-much-easier/' rel='bookmark' title='Groovy and Bash &#8211; can scripting get much easier?'>Groovy and Bash &#8211; can scripting get much easier?</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/03/swingset-on-griffon/' rel='bookmark' title='SwingSet on Griffon'>SwingSet on Griffon</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/08/griffon-swingx-fest-testing/' rel='bookmark' title='Griffon SwingX Fest testing'>Griffon SwingX Fest testing</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/04/03/griffon-bash-completion/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

