<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.3.1" -->
<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/"
	>

<channel>
	<title>The Disco Blog</title>
	<link>http://thediscoblog.com</link>
	<description>Can you dig it man?</description>
	<pubDate>Mon, 28 Apr 2008 20:37:27 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.1</generator>
	<language>en</language>
			<item>
		<title>Gant to Ant automagically</title>
		<link>http://thediscoblog.com/2008/04/28/gant-to-ant-automagically/</link>
		<comments>http://thediscoblog.com/2008/04/28/gant-to-ant-automagically/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 19:37:07 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Build Process]]></category>

		<category><![CDATA[Groovy]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/04/28/gant-to-ant-automagically/</guid>
		<description><![CDATA[On more than one occasion, I&#8217;ve been asked by various hip developers if there was a conversion script for transforming existing Ant build files into Gant build files. Russel Winder, the copasetic guru behind Gant updated the Gant website with a link to a trippin&#8217; script (dubbed ant2gant.groovy) that&#8217;ll do just that, baby! 
I tested [...]]]></description>
			<content:encoded><![CDATA[<p>On more than one occasion, I&#8217;ve been asked by various hip developers if there was a conversion script for transforming existing Ant build files into <a href="http://gant.codehaus.org/">Gant</a> build files. <a href="http://www.russel.org.uk/">Russel Winder</a>, the copasetic guru behind Gant updated the <a href="http://gant.codehaus.org/ant2gant+script">Gant website with a link to a trippin&#8217; script</a> (dubbed ant2gant.groovy) that&#8217;ll do just that, baby! </p>
<p>I tested it out with a normal Ant build file and it worked like a charm&#8211; just make sure you have in your classpath:</p>
<ul>
<li><code>ant.jar</code> (I used 1.7.0)</li>
<li><code>ant-launcher.jar</code> (I used 1.7.0 as well)</li>
<li><code>commons-cli.jar</code> (I used 1.1)</li>
</ul>
<p>Also too, my Ant build.xml file had a <code>path</code> element living outside of a <code>target</code> like so:</p>
<pre><code>&lt;path id="build.classpath"&gt;
 &lt;fileset dir="lib"&gt;
  &lt;include name="**/*.jar"/&gt;
 &lt;/fileset&gt;
&lt;/path&gt;</code></pre>
<p>This was causing the script (really Ant&#8217;s <code>Project</code> object) to blow up; consequently, I moved it into an initializing <code>target</code> and things worked copasetically from there. </p>
<p>If you haven&#8217;t tried Gant yet and you find yourself beating your head against the wall when it comes to adding behavior to Ant (such as looping, etc), then give your head a rest and take a look at Gant&#8211; this is a smokin&#8217; tool that adds a refreshing level of flexibility and expressiveness to Ant (using Groovy, man!).</p>
 <p><center>I also blog at <a href="http://www.testearly.com">testearly.com</a> | <a href="http://www.stelligent.com/">My company</a> is <a href="http://www.stelligent.com/content/view/8/39/">hiring gurus</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/04/28/gant-to-ant-automagically/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The weekly bag&#8211; April 18</title>
		<link>http://thediscoblog.com/2008/04/18/the-weekly-bag-april-18/</link>
		<comments>http://thediscoblog.com/2008/04/18/the-weekly-bag-april-18/#comments</comments>
		<pubDate>Fri, 18 Apr 2008 15:17:43 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Weekly Bag]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/04/18/the-weekly-bag-april-18/</guid>
		<description><![CDATA[Well, well. Looks what&#8217;s back, baby! 

JBehave 2, naming tests and developing libraries with BDD- JBehave lives! It&#8217;s copasetic to see they&#8217;re working on another release&#8211; I think it is a good move to leverage JUnit; however, I wonder if 2.0&#8217;s features will be compelling enough to use. 
Easy Does It With easyb- Speaking of [...]]]></description>
			<content:encoded><![CDATA[<p>Well, well. Looks what&#8217;s back, baby! </p>
<ul>
<li><a href="http://sirenian.livejournal.com/46846.html">JBehave 2, naming tests and developing libraries with BDD</a>- <a href="http://www.ibm.com/developerworks/web/library/j-cq09187/index.html">JBehave</a> lives! It&#8217;s copasetic to see they&#8217;re working on another release&#8211; I think it is a good move to leverage JUnit; however, I wonder if 2.0&#8217;s features will be compelling enough to use. </li>
<li><a href="http://binstock.blogspot.com/2008/04/easy-does-it-with-easyb.html">Easy Does It With easyb</a>- Speaking of JBehave and BDD, Andrew Binstock seems to appreciate <a href="http://easyb.org/">easyb</a> and its leveraging of a hip customer-oriented DSL.</li>
<li><a href="http://www.testearly.com/2008/04/01/saving-the-day-with-bdd/">Saving the day with BDD</a>- Customer-oriented thinking in action, baby.</li>
<li><a href="http://www.build-doctor.com/2008/04/ant-best-practices-provide-clean-target.html">Ant Best Practices: Provide a clean target</a>- the build doctor has a prescription for you, man.</li>
<li><a href="http://benrady.typepad.com/radyology/2008/03/infinitest-v3-r.html">Infinitest v3 Released!</a>- If you haven&#8217;t seen my friend Ben&#8217;s Infinitest yet, you should really take a look!</li>
<li><a href="http://www.javaworld.com/javaworld/jw-03-2008/jw-03-agile-adoption.html">Is Agile at a standstill?</a>- If you want to have a lot of fun, ask some Agile-ists to define what Agile means&#8230;</li>
<li><a href="http://tomcopeland.blogs.com/juniordeveloper/2008/04/problem-trends.html">Problem trends with PMDReports</a>- Trending metrics? Why would <a href="http://thediscoblog.com/2006/12/15/the-meaning-of-code-metrics/">anyone want to do that</a>, man? Seriously though, PMDReports looks great!</li>
</ul>
 <p><center>I also blog at <a href="http://www.testearly.com">testearly.com</a> | <a href="http://www.stelligent.com/">My company</a> is <a href="http://www.stelligent.com/content/view/8/39/">hiring gurus</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/04/18/the-weekly-bag-april-18/feed/</wfw:commentRss>
		</item>
		<item>
		<title>0.8 is easyb&#8217;s bag</title>
		<link>http://thediscoblog.com/2008/04/03/08-is-easybs-bag/</link>
		<comments>http://thediscoblog.com/2008/04/03/08-is-easybs-bag/#comments</comments>
		<pubDate>Thu, 03 Apr 2008 02:03:31 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Developer Testing]]></category>

		<category><![CDATA[Groovy]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/04/03/08-is-easybs-bag/</guid>
		<description><![CDATA[The hip folks over at easyb.org have released version 0.8 of easyb. If you haven&#8217;t seen easyb yet, then you are in a for a real treat as easyb is the coolest thing since sliced bread, baby. As a BDD framework for the Java platform, easyb makes it super easy to craft executable documentation for [...]]]></description>
			<content:encoded><![CDATA[<p><img style="PADDING-LEFT: 0.1em; PADDING-RIGHT: 1.0em; PADDING-TOP: .3em; FLOAT: LEFT; PADDING-BOTTOM: .3em" src="/images/easyb/thumbsup.jpg" alt="hudson-groovy" width="161" height="214"/>The hip folks over at <a href="http://easyb.org/">easyb.org</a> have released <a href="http://easyb.org/download.html">version 0.8 of easyb</a>. If you haven&#8217;t seen easyb yet, then you are in a for a real treat as easyb is the coolest thing since sliced bread, baby. As a BDD framework for the Java platform, <a href="http://testearly.com/2008/03/12/functional-web-stories/">easyb makes it super easy</a> to <a href="http://testearly.com/2008/04/01/saving-the-day-with-bdd/">craft executable documentation</a> for software requirements by leveraging a flexible (and easy) story based <a href="http://thediscoblog.com/2008/01/23/stories-are-easy-man/">domain specific language</a>. </p>
<p>What&#8217;s particularly copasetic about the 0.8 release is the inclusion of a new <a href="http://easyb.googlecode.com/files/easyb-plugin-0.8.zip"> IntelliJ plug-in</a>, which makes working with easyb, well, even easier (if that&#8217;s possible, man). Many thanks to Rod Coffin for his hard work on this and the Maven 2 plug-in! </p>
<p>The DSL has been refined slightly to permit adding a <code>description</code> phrase (way to go Rodrigo Urubatan!); plus, because it&#8217;s everyone&#8217;s bag, you can chain phrases via <code>and</code> now&#8211; the DSL now permits a second repeated phrase substitute <code>and</code> instead as follows:</p>
<pre><code>scenario "text",{
 given "text", {}
 and "given text", {}
 when "text", {}
 then "text", {}
 and "then text", {}
}</code></pre>
<p>Abstract stories are now possible; thus, the proceeding closure to any phrase is now optional&#8211; easyb will make the story as <i>pending</i>. Kudos to Ken Brooks for this and the vast reporting improvements! </p>
<p>Other noteworthy changes: </p>
<ul>
<li>HTML story report generation via <a href="http://easyb.org/maven-easyb-plugin/">the Maven 2 plugin</a></li>
<li>Groovy 1.5.4 compatible</li>
<li>Numerous reporting improvements</li>
<li><code>shouldNotHave</code></li>
<li>bug fixes like exception catching</li>
<li>naming clarifications</li>
</ul>
<p>If you haven&#8217;t had a chance to check out <a href="http://code.google.com/p/easyb/">easyb</a>, then start lookin&#8217; baby! See the <a href="http://groups.google.com/group/easyb-users">mailing list</a> or be a copasetic disco dancer and <a href="http://easyb.googlecode.com/files/easyb-0.8.tar.gz">just download it</a>! </p>
 <p><center>I also blog at <a href="http://www.testearly.com">testearly.com</a> | <a href="http://www.stelligent.com/">My company</a> is <a href="http://www.stelligent.com/content/view/8/39/">hiring gurus</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/04/03/08-is-easybs-bag/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Abecedarian Groovy</title>
		<link>http://thediscoblog.com/2008/03/31/abecedarian-groovy/</link>
		<comments>http://thediscoblog.com/2008/03/31/abecedarian-groovy/#comments</comments>
		<pubDate>Mon, 31 Mar 2008 21:22:28 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Articles]]></category>

		<category><![CDATA[Groovy]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/03/31/abecedarian-groovy/</guid>
		<description><![CDATA[New to Groovy? Fear not, hip daredevil! While &#8220;Groovy in Action&#8221; is undoubtedly your vade mecum as it is for countless other madcaps, the copasetic folks at IBM developerWorks have recently published &#8220;Fluently Groovy&#8221; to quell your Groovy thirsts, baby.  
This tutorial is for hip developers unfamiliar with Groovy and who want a quick [...]]]></description>
			<content:encoded><![CDATA[<p>New to Groovy? Fear not, hip daredevil! While &#8220;<a href="http://www.manning.com/koenig/">Groovy in Action</a>&#8221; is undoubtedly your vade mecum as it is for countless other madcaps, the copasetic folks at <a href="http://www.ibm.com/developerworks/java">IBM developerWorks</a> have recently published &#8220;<a href="http://www.ibm.com/developerworks/edu/j-dw-java-jgroovy-i.html">Fluently Groovy</a>&#8221; to quell your Groovy thirsts, baby.  </p>
<p>This tutorial is for hip developers unfamiliar with Groovy and who want a quick and copasetic introduction to the basics, man. Get started with Groovy&#8217;s simplified variation of the Java syntax and learn about essential features like native collections and closures. Write your first Groovy class, and then see how easily you can use JUnit to test it, baby. </p>
<p>Because it&#8217;s your bag, you&#8217;ll walk (no, dance!) away from this one-hour tutorial with a fully functioning Groovy development environment and the skills to use it. Right on! Best of all, you&#8217;ll have learned first-hand how to use Groovy and Java code together in your everyday Java application development. How&#8217;s that sound for a party, baby?! What are you waiting for? <a href="http://www.ibm.com/developerworks/edu/j-dw-java-jgroovy-i.html">Read on</a>! </p>
 <p><center>I also blog at <a href="http://www.testearly.com">testearly.com</a> | <a href="http://www.stelligent.com/">My company</a> is <a href="http://www.stelligent.com/content/view/8/39/">hiring gurus</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/03/31/abecedarian-groovy/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The weekly bag&#8211; March 21</title>
		<link>http://thediscoblog.com/2008/03/24/the-weekly-bag-march-21/</link>
		<comments>http://thediscoblog.com/2008/03/24/the-weekly-bag-march-21/#comments</comments>
		<pubDate>Mon, 24 Mar 2008 01:23:36 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Weekly Bag]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/03/24/the-weekly-bag-march-21/</guid>
		<description><![CDATA[Missed a week! Don&#8217;t fret, such a mishap doesn&#8217;t imply there weren&#8217;t any links hip enough to list. It was disco night at the local YMCA&#8230;

FEST in &#8220;Java Power Tools&#8221;- John&#8217;s upcoming book is a true masterpiece&#8211; I can&#8217;t recommend a better book for the Java community, baby!
Debunking Cyclomatic Complexity- My friend, Andrew, has a [...]]]></description>
			<content:encoded><![CDATA[<p>Missed a week! Don&#8217;t fret, such a mishap doesn&#8217;t imply there weren&#8217;t any links hip enough to list. It was disco night at the local YMCA&#8230;</p>
<ul>
<li><a href="http://www.jroller.com/alexRuiz/entry/java_power_tools_includes_fest">FEST in &#8220;Java Power Tools&#8221;</a>- John&#8217;s upcoming book is a true masterpiece&#8211; I can&#8217;t recommend a better book for the Java community, baby!</li>
<li><a href="http://www.sdtimes.com/content/article.aspx?ArticleID=31820">Debunking Cyclomatic Complexity</a>- My friend, Andrew, has a copasetic argument here.</li>
<li><a href="http://hamletdarcy.blogspot.com/2008/03/mockito-new-mock-framework-on-block.html">Mockito - The New Mock Framework on the Block</a>- Hamlet has made the switch&#8211; what do you think?</li>
<li><a href="http://blogs.msdn.com/buckh/archive/2008/03/18/msbuild-project-analysis-tool-buildcop.aspx">MSBuild project analysis tool: BuildCop</a>- The fuzz is after your build, man!</li>
<li><a href="http://dannorth.net/2008/03/better-best-practices">Better Best Practices</a>- Dan North&#8217;s article is definitely worth reading. </li>
<li><a href="http://googletesting.blogspot.com/2008/03/cost-benefit-analysis-of-test.html">Cost-Benefit Analysis of a Test</a>- This post reminds me of an excellent quote: &#8220;If you think education is expensive, try ignorance&#8221; (Derek Bok, Former President of Harvard).</li>
</ul>
 <p><center>I also blog at <a href="http://www.testearly.com">testearly.com</a> | <a href="http://www.stelligent.com/">My company</a> is <a href="http://www.stelligent.com/content/view/8/39/">hiring gurus</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/03/24/the-weekly-bag-march-21/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Unambiguously analyzing metrics</title>
		<link>http://thediscoblog.com/2008/03/20/unambiguously-analyzing-metrics/</link>
		<comments>http://thediscoblog.com/2008/03/20/unambiguously-analyzing-metrics/#comments</comments>
		<pubDate>Thu, 20 Mar 2008 02:11:18 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Code Metrics]]></category>

		<category><![CDATA[Groovy]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/03/20/unambiguously-analyzing-metrics/</guid>
		<description><![CDATA[Software metrics are objective measurements of particular aspects of code&#8211; for instance, Cyclomatic complexity measures complexity without any regard for why code contains a certain number of paths. For metrics to be useful, baby,  they must be applied subjectively. In the case of complexity, there may be circumstances that warrant such code (although, I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<p>Software metrics are <i>objective</i> measurements of particular aspects of code&#8211; for instance, Cyclomatic complexity measures complexity without any regard for why code contains a certain number of paths. For metrics to be useful, baby,  they must be applied <i>subjectively</i>. In the case of complexity, there may be circumstances that warrant such code (although, I&#8217;ve yet to find complex code that still can&#8217;t benefit from refactoring). I&#8217;ve also found that, on the whole, metrics are more <a href="http://www.youtube.com/watch?v=1feldcDJ__M&amp;feature=related">copasetic</a> when <a href="http://thediscoblog.com/2006/12/15/the-meaning-of-code-metrics/">combined with other metrics and trended</a>&#8211; for instance, complexity alone is somewhat interesting, but pairing <a href="http://thediscoblog.com/2007/10/25/this-podcast-doesnt-stink-man/">complexity with code coverage</a> paints a much more detailed metric that bears understanding. High complexity with low coverage is clearly more risky than the same complexity with high code coverage&#8211; even the <a href="http://www.artima.com/weblogs/viewpost.jsp?thread=215899">CRAP metric</a> holds this relationship. </p>
<p>One particular hip metric that I find helpful is the ratio of copy and pasted code within a code base as unknown copy and pasted code <i>will</i> <a href="http://www.youtube.com/watch?v=zbSKnU5ZwJg">haunt you</a>, man. For instance, copy and pasted code replicates bugs and poorly coded algorithms to name a few nefarious aspects; consequently, understanding what code has been replicated can help teams refactor offending code. Having run various copy and paste analyzers on more code bases than I care to admit, (and because it&#8217;s my bag) I&#8217;ve found that all code bases have a certain level of offending code that triggers a copy and paste detection. One particular tool, <a href="http://pmd.sourceforge.net/cpd.html">CPD</a>, is nice enough to create a report containing the offending code like so:</p>
<pre><code>&lt;duplication lines="7" tokens="53"&gt;
 &lt;file line="36" path="cbd4/blackjack/src/com/stelligent/blackjack/Hand.java"/&gt;
 &lt;file line="42" path="cbd4/blackjack/src/com/stelligent/blackjack/Hand.java"/&gt;
 &lt;file line="48" path="cbd4/blackjack/src/com/stelligent/blackjack/Hand.java"/&gt;
 &lt;codefragment&gt;
 &lt;![CDATA[
    } else if (first.equals("Jack")) {
      if(!second.equals("King") &amp;&amp; !second.equals("Queen") &amp;&amp; !second.equals("Jack")){
         return Integer.parseInt(second) + 10;
     } else {
      return 20;
    }
   }else if(first.equals("9")){
]]&gt;
&lt;/codefragment&gt;
&lt;/duplication&gt;</code></pre>
<p>As you can see, CPD reports the total number of lines of copy and pasted code and where that bogue code can be found. This data is certainly helpful; however, it doesn&#8217;t paint the entire story&#8211; while 7 lines doesn&#8217;t seem like all that much code, you&#8217;d probably reconsider if it were 7 lines of code in a 30 line code base or more realistically&#8211; 700 lines in a few thousand line code base. Therein lies the catch&#8211; CPD&#8217;s data is really only helpful when viewed on the whole (or a ratio&#8211; that is, total lines of copy and pasted code over total lines of code). Unfortunately, CPD doesn&#8217;t report the total lines of code scanned&#8211; only the total lines of copy and pasted code. For instance, in this sample code base, there were 9 suspected copy and pasted code fragments totaling about 120 lines of code (or <i>CPLOC</i>). </p>
<p>Luckily, there&#8217;s another handy tool which reports the total lines of code (or <i>LOC</i>) in a code base&#8211; <a href="http://www.ibm.com/developerworks/java/library/j-cq06306/index.html">JavaNCSS</a>. Running JavaNCSS yielded a value of about 610 LOC; therefore the ratio of copy and pasted code is <code>CPLOC/LOC</code> or <code>120/610</code>, which is roughly 20%. </p>
<p>20% CPLOC is probably a bad thing&#8211; at a minimum is is worth knowing about. 20% today might not be too important to know, but knowing that it increased to 25% next week would be an indication that things are degrading&#8211; likewise, seeing a value decrease over time indicates the code base is actively being improved. Yet, how can teams possibly monitor this trippin&#8217; data? </p>
<p>Reports are hip, but in truth, reports by tools like CPD are essentially read <i>once</i>&#8211; the first time they are generated. After that, it&#8217;s anyone&#8217;s guess when someone will actively read the report again. Hence, I find it particularly helpful to essentially throw the report out and let the <a href="http://testearly.com/2007/03/10/forcing-build-failures-with-simple-thresholds/">build itself proactively tell me</a> when a particular metric gets out of hand. This essentially means that my build has to <a href="http://testearly.com/2007/02/19/making-nant-more-expressive-with-boo/">monitor a particular metric</a>&#8211; and in the case of the CPLOC ratio, my build has to gather data from two sources&#8211; JavaNCSS&#8217;s report and CPD&#8217;s. </p>
<p>Fortunately, this is easy with <a href="http://groovy.codehaus.org/">Groovy</a>&#8211; if your instance, you are using Ant for builds, you can first generate the two reports as follows:</p>
<pre><code>&lt;target name="cpd"&gt;
 &lt;mkdir dir="target/reports"/&gt;
 &lt;taskdef name="cpd" classname="net.sourceforge.pmd.cpd.CPDTask"
   classpathref="classpath"/&gt;
 &lt;cpd minimumTokenCount="10" outputFile="target/reports/cpd.xml" format="xml"&gt;
  &lt;fileset dir="src"&gt;
   &lt;include name="**/*.java"/&gt;
  &lt;/fileset&gt;
 &lt;/cpd&gt;
&lt;/target&gt;</code></pre>
<p>The code above generates a CPD XML report from all the code in a <code>src</code> directory and the following code creates a JavaNCSS report from the same code base:</p>
<pre><code>&lt;target name="javancss"&gt;
 &lt;taskdef name="javancss" classname="javancss.JavancssAntTask"
   classpathref="classpath" /&gt;
 &lt;javancss srcdir="src" generateReport="true"
   abortOnFail="true" ccnPerFuncMax="100"
   outputfile="target/reports/javancss_metrics.xml" format="xml" /&gt;
&lt;/target&gt;</code></pre>
<p>The only high-level step left to do is to put the two metrics together; however, this step actually takes a few sub-steps, baby. For instance, obtaining the total lines of CPLOC requires iterating over a collection of duplication elements in the CPD xml file. Consequently, the following steps detail the effort required to obtain this metric:</p>
<ul>
<li>parse the JavaNCSS xml report and obtain the total LOC</li>
<li>parse the CPD xml report and obtain the total CPLOC</li>
<li>divide the two and compare the result to some threshold</li>
<li>if the threshold is exceeded, fail the build</li>
</ul>
<p>Groovy, by the way, is particularly well suited for such a task (as if you didn&#8217;t know that, man?)&#8211; parsing XML with Groovy is practically effortless&#8211; like disco dancing, eh? For instance, obtaining the total LOC from JavaNCSS&#8217;s xml file is as easy as </p>
<pre><code>int ncss = Integer.parseInt(jncssroot.packages.total.ncss.text())</code></pre>
<p>Note, I&#8217;m coercing integer values as I&#8217;d like to divide (and round) my result&#8211; if I don&#8217;t explicitly specify <code>int</code>&#8217;s I&#8217;ll be left with <code>String</code> division, which doesn&#8217;t work so well. </p>
<p>Parsing CPD&#8217;s xml document is slightly more complex&#8211; slightly in that it takes 3 times as much code:</p>
<pre><code>def cpdtot = 0
cpdroot.duplication.each { elem -&gt;
 cpdtot += Integer.parseInt(elem.@lines.text())
}</code></pre>
<p>Again, parsing an XML document yields <code>String</code> values; accordingly, I need to use <code>Integer</code>&#8217;s <code>parseInt</code> method.</p>
<p>Next, all I need to do is divide the two and, in my case, I&#8217;m aggressively rounding up via Java&#8217;s ceiling call as follows:</p>
<pre><code>def ratio = Math.ceil((cpdtot / ncss) * 100)</code></pre>
<p>Multiplying the result by 100 gives me a percentage value, of course, and lastly, I compare that to a threshold value:</p>
<pre><code>if(ratio &gt; Double.parseDouble(properties.cpd_threshold)){
  ant.fail(message:
   "cut and paste ratio was greater than ${properties.cpd_threshold}%, it was ${ratio}%")
}</code></pre>
<p>Puttin&#8217; it all together, baby, yields a groovy Ant script with a hip target: </p>
<pre><code>&lt;target name="cpd-threshold" depends="metrics"&gt;
 &lt;groovy&gt;
 def jncssroot = new XmlSlurper().parse("target/reports/javancss_metrics.xml")
 int ncss = Integer.parseInt(jncssroot.packages.total.ncss.text())

 def cpdroot = new XmlSlurper().parse("target/reports/cpd.xml")

 def cpdtot = 0
 cpdroot.duplication.each { elem -&gt;
  cpdtot += Integer.parseInt(elem.@lines.text())
 }

 def ratio = Math.ceil((cpdtot / ncss) * 100)

 if(ratio &gt; Double.parseDouble(properties.cpd_threshold)){
  ant.fail(message:
   "cut and paste ratio was greater than ${properties.cpd_threshold}%, it was ${ratio}%")
 }
 &lt;/groovy&gt;
&lt;/target&gt;</code></pre>
<p>Reports are hip, but they are usually only read <i>once</i>&#8211; the first time they are generated. Rather than waiting to find out that there&#8217;s a problem, proactively analyzing a hip metric (such CPLOC/LOC) enables rapid feedback and rapid corrections&#8211; is that unambiguous or what? </p>
 <p><center>I also blog at <a href="http://www.testearly.com">testearly.com</a> | <a href="http://www.stelligent.com/">My company</a> is <a href="http://www.stelligent.com/content/view/8/39/">hiring gurus</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/03/20/unambiguously-analyzing-metrics/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The weekly bag&#8211; March 7</title>
		<link>http://thediscoblog.com/2008/03/08/the-weekly-bag-march-7/</link>
		<comments>http://thediscoblog.com/2008/03/08/the-weekly-bag-march-7/#comments</comments>
		<pubDate>Sat, 08 Mar 2008 15:12:20 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Weekly Bag]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/03/08/the-weekly-bag-march-7/</guid>
		<description><![CDATA[Sorry to have missed the leap year weekly bag, baby. Without further ado:

Design and Code Reviews : The Good, Bad and Ugly- my friend Kirk Knoernschild&#8217;s article gets a good review on InfoQ. Definately worth the read, baby!
What is a good example of unit test over specification?- looks like Roy is covering all the bases [...]]]></description>
			<content:encoded><![CDATA[<p>Sorry to have missed the leap year weekly bag, baby. Without further ado:</p>
<ul>
<li><a href="http://www.infoq.com/news/2008/03/code-review-antipatterns">Design and Code Reviews : The Good, Bad and Ugly</a>- my friend Kirk Knoernschild&#8217;s article gets a good review on InfoQ. Definately worth the read, baby!</li>
<li><a href="http://weblogs.asp.net/rosherove/archive/2008/03/01/what-is-a-good-example-of-unit-test-over-specification.aspx">What is a good example of unit test over specification?</a>- looks like Roy is covering all the bases with his upcoming book&#8211; that should be a great read!</li>
<li><a href="http://googletesting.blogspot.com/2008/03/tott-understanding-your-coverage-data.html">TotT: Understanding Your Coverage Data</a>- a timeless conversation.</li>
<li><a href="http://java.dzone.com/articles/speed-your-unit-tests-now">Speed up your Unit Tests NOW!!!</a>- GridGain looks super interesting, man!</li>
<li><a href="http://sirenian.livejournal.com/45637.html">Do I always write a test?</a>- Because it&#8217;s her bag, Elizabeth shocks Uncle Bob.</li>
<li><a href="http://tech.puredanger.com/2008/02/22/practical-unit-testing/">Practical unit testing</a>- Don&#8217;t believe in 100% code coverage? </li>
</ul>
 <p><center>I also blog at <a href="http://www.testearly.com">testearly.com</a> | <a href="http://www.stelligent.com/">My company</a> is <a href="http://www.stelligent.com/content/view/8/39/">hiring gurus</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/03/08/the-weekly-bag-march-7/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Unadulterated Java is so groovy</title>
		<link>http://thediscoblog.com/2008/03/07/unadulterated-java-is-so-groovy/</link>
		<comments>http://thediscoblog.com/2008/03/07/unadulterated-java-is-so-groovy/#comments</comments>
		<pubDate>Fri, 07 Mar 2008 20:08:23 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Groovy]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/03/07/unadulterated-java-is-so-groovy/</guid>
		<description><![CDATA[Groovy is an alternate language for the JVM&#8211; alternate in that Groovy is a simpler, more expressive Java (which, by the way, also happens to work with normal Java). In fact, if you already know Java, you basically know Groovy, man. 

Groovy’s syntax is a less strict version of Java’s and adds a few new [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://groovy.codehaus.org/">Groovy</a> is an <a href="http://www.ibm.com/developerworks/views/java/libraryview.jsp?search_by=alt.lang.jre:">alternate language</a> for the JVM&#8211; alternate in that Groovy is a simpler, more expressive Java (which, by the way, also happens to work with normal Java). In fact, if you already know Java, you basically know Groovy, man. </p>
<p><img style="PADDING-LEFT: 1.5em; PADDING-RIGHT: 1em; FLOAT: RIGHT; PADDING-BOTTOM: 1em" src="/images/unadult-definition.jpg" alt="definition" width="537" height="86"/></p>
<p>Groovy’s syntax is a <i>less strict</i> version of Java’s and adds a few new features here and there. You could say that Groovy&#8217;s syntax is terse, which yeilds a highly expressive medium for conveying behavior without a lot of extranous verbiage. But the beauty is that that verbiage isn&#8217;t gone&#8211; it&#8217;s assumed. Hence, Groovy is an unadulterated version of Java, baby. </p>
<p>As a demonstration, here is a hip Java class that represents a song, aptly named <code>Song</code>. As you can imagine, this code exists in a file named <code>Song.java</code> and is located in some sort of package structure (like <code>com.acme.blah</code>). </p>
<pre><code>public class Song {
 private String name;
 private String genre;
 private String artist;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getGenre() {
  if(genre != null){
   return genre.toUpperCase();
  }else{
   return null;
  }
 }

 public void setGenre(String genre) {
  this.genre = genre;
 }

 public String getArtist() {
  return artist;
 }

 public void setArtist(String artist) {
  this.artist = artist;
 }
}</code></pre>
<p>This bogue class doesn&#8217;t do anything particularly interesting and is basically a JavaBean&#8211; but it serves as an excellent demonstration of how you can achieve the same behavior (albeit simple) in Groovy with fewer lines of code. </p>
<p>As a first step, you can make this a Groovy class by just changing the file&#8217;s type to <code>.groovy</code>&#8211; in fact, <code>Song.groovy</code> as is, will compile just fine with <code>groovyc</code>. </p>
<p>One thing about Groovy is that it is Java <i>without</i> accessibility modifiers (i.e. you don&#8217;t have to specify <code>public</code>&#8211; everything is assumed to be so unless you say otherwise) and semi-colons. Consequently, I can trim down this class somewhat by removing all semi-colons and <code>public</code> modifiers, baby. </p>
<pre><code>class Song {
 private String name
 private String genre
 private String artist

 String getName() {
  return name
 }

 void setName(String name) {
  this.name = name
 }

 String getGenre() {
  if(genre != null){
   return genre.toUpperCase()
  }else{
   return null
  }
 }

 void setGenre(String genre) {
  this.genre = genre
 }

 String getArtist() {
  return artist
 }

 void setArtist(String artist) {
  this.artist = artist
 }
}</code></pre>
<p>Already, because it&#8217;s my bag, <code>Song</code> is getting a bit shorter, but nothing to write home about. </p>
<p>What&#8217;s particularly handy in Groovy is the way it treats properties&#8211; in this case, <code>Song</code> has 3 (<code>name</code>, <code>genre</code>, and <code>artist</code>). By convention, in Java, if you want to access these values (i.e. via getters and setters) you copasetically create corresponding <code>setProperty</code> and <code>getProperty</code> methods. In Groovy, these accessors are generated for you; consequently, in the <code>Song</code> class, I can remove those methods leaving me with the following code:</p>
<pre><code>class Song {
 private String name
 private String genre
 private String artist

 String getGenre() {
  if(genre != null){
   return genre.toUpperCase()
  }else{
   return null
  }
 }
}</code></pre>
<p>Note that I left in the <code>getGenre</code> method&#8211; that&#8217;s doing something special. </p>
<p>Be careful though, disco dancers, as in Groovy, if I leave the properties as <code>private</code> Groovy will not generate the accessors&#8211; accordingly, the next step is to remove the <code>private</code> modifier on the properties. </p>
<pre><code>class Song {
 String name
 String genre
 String artist

 String getGenre() {
  if(genre != null){
   return genre.toUpperCase()
  }else{
   return null
  }
 }
}</code></pre>
<p>Looking at this code, I can hear the Java faithful grinding their teeth over what appears to be a lack of encapsulation, baby&#8211; in fact, in Groovy, you can access the <code>name</code> property <i>directly</i>! </p>
<p>Or do you? </p>
<p>Using a simple <code>GroovyTestCase</code>, I can knock out a quick test to see property access in action:</p>
<pre><code>class SongTest extends GroovyTestCase {

 void testPropertyAccess() {
  def sng = new Song(artist:"Lipps, Inc",
      name:"FunkyTown", genre:"Disco")

  assertEquals("FunkyTown", sng.name)
  assertEquals("FunkyTown", sng.getName())
 }
}</code></pre>
<p>In the code above, I&#8217;m grabbing a property either directly or via the getter method&#8211; the same, by the way, is true for setting a value. But the question remains, when the property is seemingly accessed directly, does this by pass the getter (or setter)? </p>
<p>One way to find out is to use the <code>getGenre</code> method, right? It does something special&#8211; accordingly, the following test case demonstrates hip encapsulation in action:</p>
<pre><code>void testEncapsulatedAccess() {
 def sng = new Song(artist:"Lipps, Inc",
   name:"FunkyTown", genre:"Disco")

 assertEquals("DISCO", sng.genre)
 assertEquals("DISCO", sng.getGenre())
}</code></pre>
<p>Even though the properties in the <code>Song</code> class are not explicitly <code>private</code>, they are acting privately, aren&#8217;t they, man? </p>
<p>Going back to the <code>getGenre</code> method on the <code>Song</code> class, it turns out that Groovy also has <a href="http://thediscoblog.com/2008/02/18/defensive-programming-is-so-groovy/">a handy syntax for null pointer safety</a>, consequently, I can simply that method even further.</p>
<pre><code>class Song {
 String name
 String genre
 String artist

 String getGenre() {
  return genre?.toUpperCase()
 }
}</code></pre>
<p>Groovy also permits dropping <code>return</code> statements&#8211; in essence, the last line of a method is assumed as the <code>return</code> value. So, that leaves the <code>getGenre</code> method as:</p>
<pre><code>String getGenre() {
  genre?.toUpperCase()
}</code></pre>
<p>Groovy infers types&#8211; for instance, writing <code>String value = "groovy";</code> is a bit verbose, no? Think about it for a second&#8211; <code>String value</code> is superfluous isn&#8217;t it? <code>value</code> must be a <code>String</code> as I set it to one, right? Likewise, in Groovy, <code>value</code> is clearly a <code>String</code> (because it is set to a <code>String</code> directly!) without having to give the compiler (or runtime) a hint. Accordingly, you can drop types and replace them with Groovy&#8217;s hip <code>def</code> keyword. </p>
<pre><code>class Song {
 def name
 def genre
 def artist

 def getGenre() {
  genre?.toUpperCase()
 }
}</code></pre>
<p>Removing an explicit type does have some consequences though&#8211; in this case, given that Groovy is Java, these properties must have some type associated with them. What do you think that type is? Right! <code>java.lang.Object</code>, baby. Consequently, if you were to use this Groovy <code>Song</code> class in Java, the <code>getGenre</code> method will have a return type of <code>Object</code>, not <code>String</code> (unless you explicitly make <code>String</code> the return type).</p>
<p>Applying groovy techniques to Java yields a more effective Java&#8211; in this case, the <code>Song</code> class started out at roughly 30 lines of code. Refactoring it down a bit by leveraging Groovy, I ended up with basically 10 lines of code. The code is essentially the same&#8211; the only behavioral difference being that <code>Object</code> is now king with method return types (should you use this class in normal Java). But switching out <code>def</code> for <code>String</code> doesn&#8217;t add any new lines of code, does it?  </p>
<p>Groovy is unadulterated Java&#8211; in fact, it&#8217;s Java <i>without a lot of Java</i>. Can you dig it, baby? </p>
 <p><center>I also blog at <a href="http://www.testearly.com">testearly.com</a> | <a href="http://www.stelligent.com/">My company</a> is <a href="http://www.stelligent.com/content/view/8/39/">hiring gurus</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/03/07/unadulterated-java-is-so-groovy/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The weekly bag&#8211; Feb 22</title>
		<link>http://thediscoblog.com/2008/02/25/the-weekly-bag-feb-22/</link>
		<comments>http://thediscoblog.com/2008/02/25/the-weekly-bag-feb-22/#comments</comments>
		<pubDate>Mon, 25 Feb 2008 02:20:29 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Weekly Bag]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/02/25/the-weekly-bag-feb-22/</guid>
		<description><![CDATA[Sockin&#8217; it to you, baby:

StatSVN rocks- Indeed it does, baby!
Custom MSBuild Tasks- Start coding them!
TotT: Too Many Tests- A good problem to have, I&#8217;d say.
Glean v1.3: Code feedback tools for Ant- John&#8217;s got a good thing with Glean!
FEST-Assert 1.0a1 released!- Have you checked out what Alex and team are up to?
Java Power Tools: where it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>Sockin&#8217; it to you, baby:</p>
<ul>
<li><a href="http://mattharrah.com/blog/?p=48">StatSVN rocks</a>- Indeed it does, baby!</li>
<li><a href="http://www.infoq.com/news/2008/02/custom-msbuild-tasks">Custom MSBuild Tasks</a>- Start coding them!</li>
<li><a href="http://googletesting.blogspot.com/2008/02/in-movie-amadeus-austrian-emperor.html">TotT: Too Many Tests</a>- A good problem to have, I&#8217;d say.</li>
<li><a href="http://java.dzone.com/announcements/glean-v13-code-feedback-tools-">Glean v1.3: Code feedback tools for Ant</a>- John&#8217;s got a good thing with Glean!</li>
<li><a href="http://www.jroller.com/alexRuiz/entry/fest_assert_alpha_1_released">FEST-Assert 1.0a1 released!</a>- Have you checked out what Alex and team are up to?</li>
<li><a href="http://weblogs.java.net/blog/johnsmart/archive/2008/02/java_power_tool_6.html">Java Power Tools: where it&#8217;s at</a>- I can&#8217;t wait for this book to be officially released!</li>
</ul>
 <p><center>I also blog at <a href="http://www.testearly.com">testearly.com</a> | <a href="http://www.stelligent.com/">My company</a> is <a href="http://www.stelligent.com/content/view/8/39/">hiring gurus</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/02/25/the-weekly-bag-feb-22/feed/</wfw:commentRss>
		</item>
		<item>
		<title>easyb 0.7 is out, man</title>
		<link>http://thediscoblog.com/2008/02/19/easyb-07-is-out-man/</link>
		<comments>http://thediscoblog.com/2008/02/19/easyb-07-is-out-man/#comments</comments>
		<pubDate>Tue, 19 Feb 2008 01:01:03 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Developer Testing]]></category>

		<category><![CDATA[Groovy]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/02/19/easyb-07-is-out-man/</guid>
		<description><![CDATA[The hip folks involved with easyb just released version 0.7! The latest and greatest version includes the new should wiring to all objects (i.e. value.shouldBe false) within the context of story (or behavior); moreover, easyb now offers Maven 2 support via a new plug-in.  
What&#8217;s more, easyb.org has been updated to include documentation on [...]]]></description>
			<content:encoded><![CDATA[<p>The hip folks involved with <a href="http://www.easyb.org/index.html">easyb</a> just released <a href="http://code.google.com/p/easyb/downloads/list">version 0.7</a>! The latest and greatest version includes the new <code>should</code> wiring to all objects (i.e. <code>value.shouldBe false</code>) within the context of story (or behavior); moreover, easyb now offers <a href="http://www.easyb.org/running.html">Maven 2 support</a> via a new plug-in.  </p>
<p>What&#8217;s more, <a href="http://www.easyb.org/index.html">easyb.org</a> has been updated to include documentation on the <a href="http://www.easyb.org/dbunit.html">database plug-in</a>, how to <a href="http://www.easyb.org/running.html">use the Maven 2 plug-in</a>, and an in-depth description of the <a href="http://www.easyb.org/dsls.html">easyb <code>should</code> syntax</a>. Plus, there is a <a href="http://groups.google.com/group/easyb-users">new mailing list</a>.</p>
 <p><center>I also blog at <a href="http://www.testearly.com">testearly.com</a> | <a href="http://www.stelligent.com/">My company</a> is <a href="http://www.stelligent.com/content/view/8/39/">hiring gurus</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/02/19/easyb-07-is-out-man/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
