<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>eclecticlogic.github.io</title>
 <link href="http://www.eclecticlogic.com/atom.xml" rel="self"/>
 <link href="http://www.eclecticlogic.com/"/>
 <updated>2019-05-18T23:13:41+00:00</updated>
 <id>http://www.eclecticlogic.com</id>
 <author>
   <name>Karthik Abram</name>
   <email></email>
 </author>

 
 <entry>
   <title>Fluent Interfaces without Recursive Generics</title>
   <link href="http://www.eclecticlogic.com/2016/12/31/fluent-interfaces-generics/"/>
   <updated>2016-12-31T00:00:00+00:00</updated>
   <id>http://www.eclecticlogic.com/2016/12/31/fluent-interfaces-generics</id>
   <content type="html">&lt;p&gt;Fluent interfaces are an API design style that allow you to be expressive while being terse. Consider the following &lt;em&gt;pseudo&lt;/em&gt; example API to split a string.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;n&quot;&gt;Splitter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;splitter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Splitter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;,&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;splitter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setOmitEmptyStrings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;splitter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setTrimOutput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;splitter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;splitToList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;That is four lines packed with a lot of noise. The two setters could have been written as parameter-less methods but I wanted to stick to Javabean specifications here. Now compare this with the fluent version of &lt;a href=&quot;https://github.com/google/guava/wiki/StringsExplained#splitter&quot;&gt;Splitter&lt;/a&gt; from &lt;a href=&quot;https://github.com/google/guava&quot;&gt;Google Guava&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Splitter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;,&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;omitEmptyStrings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;trimResults&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;splitToList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Still four lines but now each line clearly conveys intent in a very “fluent” dialogue like manner. So armed with an understanding of the elegancy that fluent interfaces bring to the table, you set out to create a fluent version of your new animal API. You have written up the following classes with fluent API:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;eat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Food&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;food&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;food&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;consumedBy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    
    
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;distance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// some logic here&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Dog&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dog&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bark&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// logic&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    
    
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dog&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;chaseTail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// logic here&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now you attempt to use your newly created fluent API and write up the following client code:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;someMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;eat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bark&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Cannot resolve method bark ???&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You are suddenly perplexed. Why can’t you call method bark()? It is because eat returns an instance of Animal, not Dog and so even though the runtime instance created is a Dog, the static type checking only knows that you have an instance of Animal. This particular situation is easily resolved by switching the two methods:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;someMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bark&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;eat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In a real world API, we may not have the luxury of switching methods like this (what if the dog really only likes to bark after eating!) and requiring particular ordering of calls makes for an ugly API. The standard solution in such a case is to introduce generics with a particular twist - &lt;a href=&quot;http://stackoverflow.com/questions/26304527/recursive-generic-and-fluent-interface&quot;&gt;recursive generics&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Animal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Animal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;eat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;food&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//food.consumedBy(this);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;distance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// some logic here&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Dog&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Animal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dog&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bark&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// logic&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dog&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;chaseTail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// logic here&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// in some method ...&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Animal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;eat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bark&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Problem solved? Well, almost. Until you realize that if you know include Animal as a member of any class, you bring along baggage - in the form of recursive generics that you have to apply to the container class (or method) and this can easily mushroom into very complex generic definitions. There is an alternate way of building fluent interfaces with inheritance but without generics by accepting a slight compromise. We do this by introduce a very specific typing method that allows us to switch the static type.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;eat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;food&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//food.consumedBy(this);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;distance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// some logic here&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


    &lt;span class=&quot;c1&quot;&gt;// A way to cast our return type into a specific sub-type.&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Animal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;typed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Dog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// caller&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;eat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;typed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bark&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;While not perfect, this technique allows us to switch between methods of the parent or child class and not incur the added design-time overhead of generics.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Curve Fitting</title>
   <link href="http://www.eclecticlogic.com/2015/07/17/curve-fitting/"/>
   <updated>2015-07-17T00:00:00+00:00</updated>
   <id>http://www.eclecticlogic.com/2015/07/17/curve-fitting</id>
   <content type="html">&lt;p&gt;Here is a simple technique to modify linear data points to a curve of your choice. If your function looks linear like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/images/blog/curve/linear-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;or even has an inverse linear form like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/images/blog/curve/linear-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And you want to instead map it to a curve that accentuates the initial values and suppresses the tail:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/images/blog/curve/curve-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;or has an exponential drop at the end points like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/images/blog/curve/curve-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;then, Cubic Bezier curves can be used to achieve the desired transformation. A Cubic Bezier curve is given by:&lt;/p&gt;

&lt;p&gt;B(t) = (1 - t)&lt;sup&gt;3&lt;/sup&gt;&lt;strong&gt;P&lt;sub&gt;0&lt;/sub&gt;&lt;/strong&gt; + 3(1 -t)&lt;sup&gt;2&lt;/sup&gt;t&lt;strong&gt;P&lt;sub&gt;1&lt;/sub&gt;&lt;/strong&gt; + 3(1 -t)t&lt;sup&gt;2&lt;/sup&gt;&lt;strong&gt;P&lt;sub&gt;2&lt;/sub&gt;&lt;/strong&gt; + t&lt;sup&gt;3&lt;/sup&gt;&lt;strong&gt;P&lt;sub&gt;3&lt;/sub&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here P&lt;sub&gt;0&lt;/sub&gt;, P&lt;sub&gt;3&lt;/sub&gt; are the end-points of the curve and P&lt;sub&gt;1&lt;/sub&gt; and P&lt;sub&gt;2&lt;/sub&gt; are control points. A Cubic Bezier curve, at the starting point is always tangential to the line segment P&lt;sub&gt;0&lt;/sub&gt;, P&lt;sub&gt;1&lt;/sub&gt; and in the direction of P&lt;sub&gt;0&lt;/sub&gt;, P&lt;sub&gt;1&lt;/sub&gt;. At the endpoint, the curve is tangential to P&lt;sub&gt;2&lt;/sub&gt;, P&lt;sub&gt;3&lt;/sub&gt; and is in the direction of P&lt;sub&gt;2&lt;/sub&gt;, P&lt;sub&gt;3&lt;/sub&gt;. You can play around with various Cubic Beziers shapes at &lt;a href=&quot;https://www.desmos.com/calculator/cahqdxeshd&quot;&gt;desmos.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When implementing a Cubic Bezier curve, the first oddity you will encounter is the fact that unlike polynomial equations, the Bezier does not give you y-coordinates as a function of x-coordinates. Instead, it independently gives you x and y coordinates as a function of a parameter t which varies from 0 to 1. When t = 0, the curve is at point P&lt;sub&gt;0&lt;/sub&gt; and when t = 1, the curve is at point P&lt;sub&gt;3&lt;/sub&gt;. Worse, when you vary t linearly, you do not get linear increments of x. Instead, you get linear increments along the curve’s length. In fact, it is this property of Bezier curves that makes them suitable as easing functions for animations. By constructive a Cubic Bezier with steep starting and ending slopes, you can get a slow start in the x axis followed by an acceleration in the middle and a gradual slowdown towards the end. But for mapping a traditional function of the form y = f(x), we would like to transform the Bezier to a similar function.&lt;/p&gt;

&lt;p&gt;There is no simple mathematical way to achieve this given expressions like t&lt;sup&gt;2&lt;/sup&gt; and t&lt;sup&gt;3&lt;/sup&gt; in the equation. Instead, one can approximate a solution by doing a binary search along t, computing the corresponding x until we are within a tolerance limit. At that point, the value of y can be computed. The gist below shows a Java program to do that. In addition, the program allows you to pre-compute y = Bezier(x) for x = (start, end) in specified increments.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/eclecticlogic/e46120cb719d38f5360e.js?file=CubicBezierCurve.java&quot;&gt; &lt;/script&gt;

&lt;p&gt;The class above can be extended to create a composite Cubic Bezier curve fitting algorithm that combines multiple Cubic Bezier curves to model any shape you want to create.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Groovy Oddities</title>
   <link href="http://www.eclecticlogic.com/2015/02/17/groovy-oddities/"/>
   <updated>2015-02-17T00:00:00+00:00</updated>
   <id>http://www.eclecticlogic.com/2015/02/17/groovy-oddities</id>
   <content type="html">&lt;p&gt;Groovy is a popular language for the JVM with a syntax that includes and extends Java’s. Groovy’s appeal comes from the extended syntax - optional semicolons, type-inference (strictly speaking, Groovy is typeless), literals for lists and maps, closures, operator overloading, etc. However, these extra features are not always intuitive in their interaction, leading to some syntactic oddities. Here is a list of oddities that I’ve encountered. This is not an exhaustive list. If you have run into other issues, please do leave a commment below.&lt;/p&gt;

&lt;h3 id=&quot;null-safety-in-every-step&quot;&gt;Null safety in every step&lt;/h3&gt;

&lt;p&gt;The null-safe operator allows the in-lining of nullability checks. So instead of:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;if (student.name != null) {
	lower = student.name.toLowercase()
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can write&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;lower = student.name?.toLowercase()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The variable &lt;code class=&quot;highlighter-rouge&quot;&gt;lower&lt;/code&gt; will be null if &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt; is null. Armed with this powerful operator, you set about to show your newly acquired skill. You are writing a function that accepts Account objects. You know that sometimes the account may be null (if a spurious username is provided). However, if an account is non-null, you know that it has a non-null createdOn field. Your task is to get the month from this field. You write something like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void accumulateMonths(Account account) {
   def month = account?.createdOn.month
   if (month) {
	  // Do something with month
   }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You run the program and upon receiving a &lt;code class=&quot;highlighter-rouge&quot;&gt;null&lt;/code&gt; Account object, you see an exception!&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Exception in thread &quot;main&quot; java.lang.NullPointerException: Cannot get property 'month' on null object
at org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:57)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Why did Groovy not stop when it evaluated &lt;code class=&quot;highlighter-rouge&quot;&gt;account?.&lt;/code&gt; ? Why is it complaining about not being able to get the month property? The exception was thrown because we incorrectly interpreted the semantics of the &lt;code class=&quot;highlighter-rouge&quot;&gt;?.&lt;/code&gt; operator. The null-safe operator in fact does not abort the current chain of calls on encountering a null. It is better translated to the construct below.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;def a = account == null ? null : account.createdOn
def month = a.month
if (month) {
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The null-safe operator is a close-cousin of the ternary operator, not the &lt;code class=&quot;highlighter-rouge&quot;&gt;if&lt;/code&gt; condition!&lt;/p&gt;

&lt;h3 id=&quot;applying-null-safe-retrieval-to-map-entries&quot;&gt;Applying null-safe retrieval to map entries.&lt;/h3&gt;

&lt;p&gt;In Groovy, you can access map entries as &lt;code class=&quot;highlighter-rouge&quot;&gt;map[key]&lt;/code&gt; and list entries as &lt;code class=&quot;highlighter-rouge&quot;&gt;list[index]&lt;/code&gt;. So if we had a &lt;code class=&quot;highlighter-rouge&quot;&gt;Map&amp;lt;String, List&amp;lt;Integer&amp;gt;&amp;gt;&lt;/code&gt;, and we want to make sure a map entry is not null before we access the list, should we be able to use the null-safe operator?&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class NullSafeWithMap {

    static void main(def args) {     
        Map&amp;lt;String, List&amp;lt;Integer&amp;gt;&amp;gt; myMap = ['a': [1, 2, 3], 'b': null, 'c': [4, 5, 6]]
        println (myMap['b']?[0]) // Syntax here here.
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Unfortunately you will get a syntax error since Groovy thinks the &lt;code class=&quot;highlighter-rouge&quot;&gt;?&lt;/code&gt; is part of the ternary operator. This is because the null-safe operator is &lt;code class=&quot;highlighter-rouge&quot;&gt;?.&lt;/code&gt; not just a &lt;code class=&quot;highlighter-rouge&quot;&gt;?&lt;/code&gt; Putting a period after the question-mark will not help either.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;myMap['b']?.[0] // Still a syntax error.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you replace the list subscript operator with the &lt;code class=&quot;highlighter-rouge&quot;&gt;get()&lt;/code&gt; method, the code will work:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;println (myMap['b']?.get(0))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;an-equation-to-get-npe&quot;&gt;An equation to get NPE&lt;/h3&gt;

&lt;p&gt;Here is a brain teaser. What is the output of the program below?&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;static void main(def args) {
     println 4 + 5 * 3
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Alright, that’s not much of a brain-teaser. The answer is obviously 19. Turns out, what I wanted was really (4 + 5) * 3 so that I get 27. That’s easy:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;static void main(def args) {
	println (4 + 5) * 3
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Think the answer will be 27? Think again! Lost in the focus on the math equation is the fact that you were able to write &lt;code class=&quot;highlighter-rouge&quot;&gt;println 4 + 5 * 3&lt;/code&gt; in the first place because Groovy lets you drop parenthesis if you have a single argument and the call is unambiguous. So instead of printing out the product of 4 + 5 and 3, Groovy is attempting to multiply the result of &lt;code class=&quot;highlighter-rouge&quot;&gt;println (4 + 5)&lt;/code&gt; and 3. &lt;code class=&quot;highlighter-rouge&quot;&gt;println&lt;/code&gt; has a return type of void which when forced into a return value becomes null. So at runtime, Groovy throws an exception stating that it cannot call &lt;code class=&quot;highlighter-rouge&quot;&gt;multiply()&lt;/code&gt; on a null object.&lt;/p&gt;

&lt;h3 id=&quot;operator-precedence-rules&quot;&gt;Operator precedence rules&lt;/h3&gt;

&lt;p&gt;Groovy supports operator overloading and provides several pre-defined operators to make your code succinct, such as the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;&amp;lt;&lt;/code&gt; operator to add to lists.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;List fruits = []
fruits &amp;lt;&amp;lt; 'Apples' // fruits = ['Apples']
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;While writing your code, you come across a case where if citrus is true, you want to add ‘Oranges’ but otherwise you want to add ‘Apples’. Eager to show off your newly acquired Groovy skill, you write the following:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;List fruits = []
boolean citrus = ... 
fruits &amp;lt;&amp;lt; citrus ? 'Oranges' : 'Applies'

println fruits

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you extol the virtues of Groovy to your colleagues, you look at the output and are horrified to find:
&lt;code class=&quot;highlighter-rouge&quot;&gt;[true]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What just happend? Well, turns out the operator precedence puts the left-shift operator at a higher precedence than the ternary operator. So the expression you really wrote is:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(fruits &amp;lt;&amp;lt; citrus) ? 'Oranges' : 'Apples'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In Groovy, a list has a &lt;code class=&quot;highlighter-rouge&quot;&gt;true&lt;/code&gt; value if it is non-null and non-empty. So ‘Oranges’ was selected as the value of the expression and sent to … /dev/null? To fix the issue, you have to write&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;fruits &amp;lt;&amp;lt; (citrus ? 'Oranges' : 'Apples')
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;block-scoped-local-variables&quot;&gt;Block scoped local variables&lt;/h3&gt;

&lt;p&gt;Seasoned programmers develop habits to prevent certain types of errors. One of those habits is to use blocks to scope local variables so that copy-paste of the code (hopefully confined to some hastily written unit test) doesn’t result in redefinition of the variables, which invariably leads to an attempt to rename the variables, which occasionally results in one rename being left off, which results in a hard-to-find bug. So we write&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{
   int a = 5;
   callSomeMethod(a);
}
{
   int a = 10;
   callSomeMethod(a);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;There are more legitimate uses for the block-scope in methods, such as to ensure that logic that follows does not rely on some previous variable. When translated to Groovy, Java code with blocks fail because Groovy thinks that you have defined closures and therefore skips over them. The workaround?&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1.times {
   int a = 5;
   callSomeMethod(a);
}
1.times {
   int a = 10;
   callSomeMethod(a);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The above construct is arguably a hack, but it works nevertheless.&lt;/p&gt;

&lt;h3 id=&quot;map-literal-oddities&quot;&gt;Map literal oddities&lt;/h3&gt;

&lt;p&gt;Groovy supports map literals. This allows you to create a map with a compact and readable syntax.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Map&amp;lt;String, Integer&amp;gt; myMap = ['a': 25]
myMap['b'] = 35
int d = myMap['a']
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Armed with this new-found knowledge, you proceed to construct a map as follows.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;String name = 'joe'
Map&amp;lt;String, Integer&amp;gt; myMap = [name: 25]
...
int value = myMap[name]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You run your program to discover a runtime exception saying that null cannot be converted to &lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt;! Upon further inspection with a debugger, you discover that your map is &lt;code class=&quot;highlighter-rouge&quot;&gt;['name': 25]&lt;/code&gt; not &lt;code class=&quot;highlighter-rouge&quot;&gt;['joe': 25]&lt;/code&gt;. What happened? Turns out you can’t have variables in a map initialization. To achieve the intent above, you have to use a GString variable or enclose the variable in parenthesis.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;String name = 'joe'
Map&amp;lt;String, Integer&amp;gt; myMap = [&quot;$name&quot;: 25] // or [(name): 25]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Map initialization cannot take the return values of functions or enums either. These also need to be turned into a GString expression or wrapped in parenthesis.&lt;/p&gt;

&lt;h3 id=&quot;primitive-arrays&quot;&gt;Primitive arrays&lt;/h3&gt;

&lt;p&gt;If you argue that Java’s primitive arrays are an aberration, you win. Now lets deal with with the real world problem presented by the fact that many java api have been written to accept primitive arrays. Since Groovy uses &lt;code class=&quot;highlighter-rouge&quot;&gt;[]&lt;/code&gt; to represent lists, how do you define a primitive array instead?&lt;/p&gt;

&lt;p&gt;Given the java method&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public class SomeClass {

    public static void soStuff(int[] values) {
        for (int i : values) {
            System.out.println(i);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;the following Groovy code will fail.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;def values = [1, 2, 3]
SomeClass.soStuff(values) 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To coerce &lt;code class=&quot;highlighter-rouge&quot;&gt;values&lt;/code&gt; into a primitive array, use the &lt;code class=&quot;highlighter-rouge&quot;&gt;as&lt;/code&gt; operator with &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;type&amp;gt;[]&lt;/code&gt; type definition.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;def values = [1, 2, 3]
SomeClass.soStuff(values as int[])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;type-lessness&quot;&gt;Type-lessness&lt;/h3&gt;

&lt;p&gt;Groovy supports duck typing. Yes, but what kind of duck allows this?&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;static int abc = new AtomicInteger()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Remember that in Groovy, type declarations in your code are completely ignored. So the compiler will happily compile the above. Groovy 2.0 introduced specific annotations, &lt;code class=&quot;highlighter-rouge&quot;&gt;@TypeChecked&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;@CompileStatic&lt;/code&gt; to alleviate some of these bugs. There are some caveats to be aware of when using these annotations. Refer to this &lt;a href=&quot;http://portal.sliderocket.com/vmware/Groovy-2-0-Static-Type-Checking-and-Compilation&quot;&gt;presentation&lt;/a&gt; for a good overview.&lt;/p&gt;

&lt;h3 id=&quot;bigdecimal-everywhere&quot;&gt;BigDecimal everywhere&lt;/h3&gt;

&lt;p&gt;Sometimes features built with good intent can have unintended consequences. The next three topics present examples of such features in Groovy. Groovy converts all division to BigDecimal. This is especially useful in financial services apps. However, it converts all division to BigDecimal as I found out. I was writing code to determine the number of threads to use to process a list of objects. I wanted the thread count to be one-tenth the list size but with a minimum of 1 and a maximum of 50.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;int threads = Math.max(1, Math.min(list.size() / 10, 50))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When I ran the program, I got an exception stating, &lt;code class=&quot;highlighter-rouge&quot;&gt;Cannot resolve which method to invoke for [class java.math.BigDecimal, class java.lang.Integer] due to overlapping prototypes between ...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Uh? I was expecting integer division and Groovy instead offered a BigDecimal and couldn’t find an appropriate &lt;code class=&quot;highlighter-rouge&quot;&gt;Math.min()&lt;/code&gt; method. The code needs to be rewritten to&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;int threads = Math.max(1, Math.min((list.size() / 10).intValue(), 50))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;groovy-truth&quot;&gt;Groovy Truth&lt;/h3&gt;

&lt;p&gt;Groovy evaluates truth as many things - null objects are false, empty lists are false, zero is false. Takes you back to the days of C/C++. People bemoaned the unexpected evaluations of clever expressions in C/C++. Java came along and eschewed all cleverness. People bemoaned the verbose conditional expressions in Java. Groovy came back with C/C++ style truth evaluation.&lt;/p&gt;

&lt;p&gt;In a payment app, we want to make sure the amount has been defined. So we write a test of nullability.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;if (!amount) {
	throw new IllegalArgumentException(...
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Except somehow, the amount ends up being exactly zero (lets say this is the amount to be charged and a coupon made the amount zero). Well, the code unexpectedly fails.&lt;/p&gt;

&lt;h3 id=&quot;safe-navigation-operator&quot;&gt;Safe-navigation operator&lt;/h3&gt;

&lt;p&gt;Groovy allows you to test for nullability and continue an operation by using the safe-navigation operator &lt;code class=&quot;highlighter-rouge&quot;&gt;?&lt;/code&gt;. This is an operator that is frequently abused (its use masquerading for thoughtful analysis of nullability) and sometimes results in side-effects too.&lt;/p&gt;

&lt;p&gt;Consider the following condition&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;if (!someObject.someProperty?.taxable) {
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The author’s intent was that if taxable is false, some piece of code should be executed. However, if someProperty itself is null, in this particular case, the code should not have been executed. The author realized that someProperty is a nullable field and therefore came up with the above construct. If someProperty is null, the expression evaluates to true! The actual condition required was&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;if (someObject.someProperty &amp;amp;&amp;amp; someObject.someProperty.taxable) {
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;language-philosophy&quot;&gt;Language philosophy&lt;/h3&gt;

&lt;p&gt;Groovy introduced a number of new language constructs to the JVM and offered a terse and powerful language to program in. Groovy is particularly suited to unit-tests and DSLs and frameworks such as Grails. What is not apparent in the power of Groovy is a trade-off that has been made between discipline and power. Programmers can abuse the power of Groovy with greater ease than Java and the result is bad code that is tersely defined versus bad code that is verbosely defined. The ease of use of maps and lists in Groovy leads to their excessive use often at the expense of proper Object-Orientedness.&lt;/p&gt;

&lt;p&gt;Its been an interesting journey since the days of C, C++. C and C++ allowed all kinds of clever programming tricks and shortcuts. Developers grew tired of the side-effects of the tricks and unfortunately, at least with Java, the language designers pivoted to the other extreme. Groovy in some respects represents a swing back to the C/C++ paradigm. Language designers are now attempting to strike the right balance between concise expression vs. correctness, static type vs. verbosity and terseness vs. comprehensibility. Some of the newer languages like &lt;a href=&quot;https://www.dartlang.org/&quot;&gt;Dart&lt;/a&gt;, &lt;a href=&quot;https://developer.apple.com/swift/&quot;&gt;Swift&lt;/a&gt;, &lt;a href=&quot;http://kotlinlang.org/&quot;&gt;Kotlin&lt;/a&gt; and &lt;a href=&quot;http://ceylon-lang.org/&quot;&gt;Ceylon&lt;/a&gt; exemplify such a design trend. Ceylon in particular is an exciting JVM language that is based on the philosophy that code is read more often than written. Ceylon has one of the most &lt;a href=&quot;http://blog.jooq.org/2013/12/03/top-10-ceylon-language-features-i-wish-we-had-in-java/&quot;&gt;exciting type-systems&lt;/a&gt; and I for one am eagerly looking forward to using it.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>High Performance Postgresql in Java with Pedal</title>
   <link href="http://www.eclecticlogic.com/2015/01/09/high-performance-postgresql-in-java/"/>
   <updated>2015-01-09T00:00:00+00:00</updated>
   <id>http://www.eclecticlogic.com/2015/01/09/high-performance-postgresql-in-java</id>
   <content type="html">&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;/h3&gt;

&lt;p&gt;Postgresql is one of the most popular open-source databases in use. It has good standards support and an impressive feature set - rich data types and advanced runtime management. The Pedal framework for Java enables fast inserts (we are talking orders of magnitude faster) into Postgresql through the &lt;a href=&quot;http://www.postgresql.org/docs/9.4/static/sql-copy.html&quot;&gt;Copy&lt;/a&gt; command directly at the JPA entity level. In this article, we provide an overview of the Pedal framework and show how to use the Copy command.&lt;/p&gt;

&lt;p&gt;The Pedal framework consists of three libraries.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.eclecticlogic.com/pedal-dialect&quot;&gt;pedal-dialect&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.eclecticlogic.com/pedal-tx&quot;&gt;pedal-tx&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.eclecticlogic.com/pedal-loader&quot;&gt;pedal-loader&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href=&quot;http://www.eclecticlogic.com/pedal-dialect&quot;&gt;pedal-dialect&lt;/a&gt; enables dialect (i.e., database) and provider (e.g., Hibernate) level features such as retrieval of schema name, mapped table name given a JPA entity, user-types (arrays, bit strings), etc. It also provides support for the Copy command in Posgresql. &lt;a href=&quot;http://www.eclecticlogic.com/pedal-tx&quot;&gt;pedal-tx&lt;/a&gt; is a Java-8 only framework that allows for transaction demarcation using Java 8 lambdas, transaction attached storage and transaction attached pre/post commit lambdas. In addition it also provides a DAO abstraction layer with support for fluent JQL/HQL and native queries. With &lt;a href=&quot;http://www.eclecticlogic.com/pedal-loader&quot;&gt;pedal-loader&lt;/a&gt; data population scripts for db-unit tests can be written in a Groovy DSL while working at the JPA entity level (with mapped column types, object-level foreign-keys, etc).&lt;/p&gt;

&lt;h3 id=&quot;using-the-copy-command&quot;&gt;Using the Copy Command&lt;/h3&gt;

&lt;p&gt;To enable copy support, first create an instance of &lt;code class=&quot;highlighter-rouge&quot;&gt;com.eclecticlogic.pedal.dialect.postgresql.CopyCommand&lt;/code&gt;, ideally setup as a Spring-bean. It requires access to &lt;code class=&quot;highlighter-rouge&quot;&gt;com.eclecticlogic.pedal.provider.ProviderAccessSpi&lt;/code&gt; which can be configured by creating a &lt;code class=&quot;highlighter-rouge&quot;&gt;com.eclecticlogic.pedal.provider.hibernate.HibernateProviderAccessSpiImpl.HibernateProviderAccessSpiImpl&lt;/code&gt; passing it a reference to the &lt;code class=&quot;highlighter-rouge&quot;&gt;EntityManagerFactory&lt;/code&gt;. Using Spring with Java-based configuration, the code would look like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    @Bean
    HibernateProviderAccessSpiImpl hibernateProvider(EntityManagerFactory factory) {
        HibernateProviderAccessSpiImpl impl = new HibernateProviderAccessSpiImpl();
        impl.setEntityManagerFactory(factory);
        return impl;
    }

    @Bean
    public CopyCommand copyCommand(ProviderAccessSpi provider) {
        CopyCommand command = new CopyCommand();
        command.setProviderAccessSpi(provider);
        command.setConnectionAccessor(new TomcatJdbcConnectionAccessor());
        return command;
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The connection accessor is specific to the connection pool you are using. It is used to get a handle to the underlying JDBC-4 compliant Postgresql native connection. Pedal-dialect ships with support for the following connection pools:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://jolbox.com/&quot;&gt;BoneCP&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://commons.apache.org/proper/commons-dbcp/&quot;&gt;Commons DBCP 2&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/brettwooldridge/HikariCP&quot;&gt;Hikari&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html&quot;&gt;Tomcat JDBC&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To create one for an unsupported connection pool, implement the &lt;code class=&quot;highlighter-rouge&quot;&gt;com.eclecticlogic.pedal.connection.ConnectionAccessor&lt;/code&gt; interface.&lt;/p&gt;

&lt;p&gt;So what does the code to actual insert rows using the &lt;code class=&quot;highlighter-rouge&quot;&gt;CopyCommand&lt;/code&gt; look like? Its simple. Create instance of your entity and copy them into a &lt;code class=&quot;highlighter-rouge&quot;&gt;CopyList&amp;lt;T&amp;gt;&lt;/code&gt;. Then pass the &lt;code class=&quot;highlighter-rouge&quot;&gt;CopyList&lt;/code&gt; instance to the copy command. Here is the test code in pedal-dialect:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;        CopyList&amp;lt;ExoticTypes&amp;gt; list = new CopyList&amp;lt;&amp;gt;();

        // The copy-command can insert 100k of these per second.
        for (int i = 0; i &amp;lt; 10; i++) {
            ExoticTypes et = new ExoticTypes();
            et.setLogin(&quot;copyCommand&quot; + i);
            BitSet bs = new BitSet(7);
            bs.set(1);
            bs.set(3);
            bs.set(4);
            et.setCountries(bs);
            et.setAuthorizations(Sets.newHashSet(&quot;a&quot;, &quot;b&quot;, &quot;b&quot;, &quot;c&quot;));
            if (i != 9) {
                et.setScores(Lists.newArrayList(1L, 2L, 3L));
            } else {
                et.setScores(Lists.&amp;lt;Long&amp;gt; newArrayList());
            }
            et.setStatus(Status.ACTIVE);
            et.setCustom(&quot;this will be made uppercase&quot;);
            list.add(et);
        }

        copyCommand.insert(entityManager, list);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;CopyCommand&lt;/code&gt; supports a subset of JPA features. Check &lt;a href=&quot;http://www.eclecticlogic.com/pedal-dialect#CopyCommandSupportedFeatures&quot;&gt;here&lt;/a&gt; for the current supported feature set.&lt;/p&gt;

&lt;p&gt;For a moderate row size (100 to 200 bytes), 100k inserts using &lt;code class=&quot;highlighter-rouge&quot;&gt;EntityManager.persist()&lt;/code&gt; took 34 seconds while the &lt;code class=&quot;highlighter-rouge&quot;&gt;CopyCommand&lt;/code&gt; took 1.4 seconds! That is a 24x speed-up. Make sure you read up on the limitations of the copy feature in Postgresql. In addition, the Copy command will bypass JPA/Hibernate interceptors. So don’t expect Envers to work with it.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>SMTP-Bit - An email protocol to fight spam using Bitcoins.</title>
   <link href="http://www.eclecticlogic.com/2014/12/20/smtpbit/"/>
   <updated>2014-12-20T00:00:00+00:00</updated>
   <id>http://www.eclecticlogic.com/2014/12/20/smtpbit</id>
   <content type="html">&lt;h3 id=&quot;core-idea&quot;&gt;Core Idea&lt;/h3&gt;
&lt;p&gt;Email spams and spoofs are a constant nuisance for all. While filters grow in sophistication every year, the fraud perpetrators are always devising new ways around it. So here is a simple proposal to put an end to spam and scam artists (or at least make it an expensive proposition). Proof-of-work (e.g. &lt;a href=&quot;http://www.hashcash.org/&quot;&gt;Hashcash&lt;/a&gt;) and Bitcoin based spam filters have been proposed before. This protocol is simply a refinement of the latter.&lt;/p&gt;

&lt;p&gt;Email is perhaps the most pervasively used protocol on the Internet with approx 200 billion sent per day. It is unrealistic to expect the installed infrastructure supporting emails to be upgraded to a new protocol easily. Therefore any solution must work with the existing SMTP protocol and offer an option to upgrade to a newer protocol gradually.&lt;/p&gt;

&lt;p&gt;The SMTP-Bit protocol associates wallets with email addresses to protect against spam. An email message is required to identify the wallet associated with the sender’s email, a signature to prove that the sender owns the wallet and the public key for the wallet. Before accepting an email, the server checks the public ledger for a transaction from the sender’s wallet to the recipient’s wallet (the transaction needs to transfer a minimum of 1 Satoshi). If it finds such a transaction, the email is accepted. Otherwise it is rejected. To make the verification of the transaction from the public ledger more efficient, the email message can include the transaction id or the receiver’s mail server can store a cache of transactions involving the recipient’s wallet. The transactions can be specially tagged to make them easier to locate from the public ledger.&lt;/p&gt;

&lt;p&gt;With such a setup, the bitcoin transaction from party A to party B serves as a trust identifier. If party A uses a different email address, they can continue to communicate with party B based on the previously established trust relationship. Spam filters based on explicit trust (called permission based filters) have been tried before. &lt;a href=&quot;http://www.digiportal.com/&quot;&gt;ChoiceMail&lt;/a&gt; is one such example. The downfall of these filters has always been the need to trust a third-party with confidential information. The Bitcoin protocol with its trust-less blockchain algorithm removes this hurdle.&lt;/p&gt;

&lt;h3 id=&quot;bootstrapping&quot;&gt;Bootstrapping&lt;/h3&gt;
&lt;p&gt;For such a protocol to work, we need to provide an efficient mechanism for the recipient’s wallet to be discovered. We would ideally like the registry to be publicly accessible and not under any single party’s control. The Bitcoin transaction ledger can serve as such a registry. To associate a wallet with an email address, the user could be required to tag a transaction from the wallet to any other wallet with the email address (or multiple addresses). Such a transaction could be part of the process of setting up an email account in the first place. It may seem that having a publicly accessible email address would be folly. However, if the protocol is successful at stopping spam, such a public registry would not prove detrimental and in fact could promote legitimate communication.&lt;/p&gt;

&lt;p&gt;The protocol will face a chicken-n-egg hurdle to get going. One will not have an incentive to setup an SMTP-Bit enabled email address while others haven’t. It would be rather lonely. However, if the value proposition of not having to spam is worthwhile, it may prove to be sufficient an incentive for multitudes to join.&lt;/p&gt;

&lt;h3 id=&quot;spammers-and-spoofers&quot;&gt;Spammers and Spoofers&lt;/h3&gt;
&lt;p&gt;A spammer will need to send you a Satoshi before he/she can send you an unsolicited email. This makes it somewhat expensive to send out bulk emails. Upon receiving the spam, the recipient can simply add the sender’s wallet to a black-list thereby prohibiting future spam.&lt;/p&gt;

&lt;h3 id=&quot;domain-level-wallets&quot;&gt;Domain level wallets&lt;/h3&gt;
&lt;p&gt;The protocol can be extended to allow the association of a domain-level wallet (perhaps as a TXT record in the DNS entry). This will allow corporations to establish trust with individuals or between corporations without having to enable it on a per-email address basis.&lt;/p&gt;

&lt;h3 id=&quot;subscriptions&quot;&gt;Subscriptions&lt;/h3&gt;
&lt;p&gt;Marketing departments wanting to send you emails would need to establish a transaction to your wallet. You can unsubscribe by simply blocking their wallet.&lt;/p&gt;

&lt;h3 id=&quot;high-profile-emails&quot;&gt;High Profile Emails&lt;/h3&gt;
&lt;p&gt;The SMTP-bit protocol could also open up celebrity emails to the general public. Lets say - I’m going to pick a dead, not-generally-well-known person - Geerhardus Vos wanted his email to be publicly available but he wanted to restrict people from sending him a flood of emails. He could set up a higher transaction threshold for unknown wallets and create a white-list of wallets of his known friends and contacts (folks would then want to give a celebrity their wallet address when making an acquaintance). Nothing prevents an average Joe from setting a higher threshold either - chances are folks will not be willing to pay a higher premium to email your average Joe (or Jane!).&lt;/p&gt;

&lt;h3 id=&quot;loss-or-compromise-of-wallet&quot;&gt;Loss or compromise of Wallet&lt;/h3&gt;
&lt;p&gt;If your wallet is compromised, the situation is not too different from your email address being compromised. You simply have to ask others to black-list your old wallet and re-establish trust against your new wallet.&lt;/p&gt;

&lt;h3 id=&quot;other-considerations&quot;&gt;Other Considerations&lt;/h3&gt;
&lt;p&gt;When all 22 million bitcoins are issued, miners will need to be supported by transaction fees. In such a setup, 1 Satoshi may not suffice. A simple solution then is to use 2 Satoshis and pay out 1 Satoshi as the transaction fee.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Dynamic dependency injection with Spring</title>
   <link href="http://www.eclecticlogic.com/2014/12/05/dynamic-dependency-injection-with-spring/"/>
   <updated>2014-12-05T00:00:00+00:00</updated>
   <id>http://www.eclecticlogic.com/2014/12/05/dynamic-dependency-injection-with-spring</id>
   <content type="html">&lt;p&gt;Out of the box, Spring provides various techniques to define your beans and their dependencies - XML files, Java annotations and since version 4.0, even using &lt;a href=&quot;http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/support/GenericGroovyApplicationContext.html&quot;&gt;groovy scripts&lt;/a&gt;. Furthermore, you can control the creation of the beans using &lt;a href=&quot;http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/FactoryBean.html&quot;&gt;FactoryBean&lt;/a&gt; and bean &lt;a href=&quot;http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/config/BeanPostProcessor.html&quot;&gt;post-processors&lt;/a&gt;. Still, there are times when it would be very convenient to create an instance of some random class and have its dependencies satisfied at runtime without Spring knowing anything about that class a priori.&lt;/p&gt;

&lt;p&gt;If you are willing to accept a few limitations - only bean dependencies, not simple scalar properties, and only those annotated with &lt;code class=&quot;highlighter-rouge&quot;&gt;@javax.inject.Inject&lt;/code&gt;, then the following code creates a dependency injector that you can use to dynamically “bind” random objects.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/eclecticlogic/f384dcfd967a8537a890.js?file=DependencyInjector.java&quot;&gt; &lt;/script&gt;

&lt;p&gt;The dependency injector itself should be a spring bean and available to your code that wants to inject something else. In addition, you need to have an instance of &lt;a href=&quot;http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html&quot;&gt;AutowiredAnnotationBeanPostProcessor&lt;/a&gt;. This bean is automatically included if you have the annotation-config directive in your Spring context file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;	&lt;span class=&quot;nt&quot;&gt;&amp;lt;context:annotation-config&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can now use the dependency injector to bind dependencies at runtime as follows:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nd&quot;&gt;@Inject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeOtherObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// SomeOtherObject is spring managed
&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


	&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MyObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;withDependencies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dependencyInjector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</content>
 </entry>
 
 <entry>
   <title>Of Slurpees and Bean Burritos</title>
   <link href="http://www.eclecticlogic.com/2014/11/11/of-slurpees-and-bean-burrittos/"/>
   <updated>2014-11-11T00:00:00+00:00</updated>
   <id>http://www.eclecticlogic.com/2014/11/11/of-slurpees-and-bean-burrittos</id>
   <content type="html">&lt;p&gt;Groovy has some classes with very interesting names - &lt;code class=&quot;highlighter-rouge&quot;&gt;ConfigSlurper&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;XmlSlurper&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;JsonSlurper&lt;/code&gt;. I wonder if the engineer who wrote this class had a 7-Eleven slurpee addiction!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/images/blog/slurpee.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I can imagine &lt;code class=&quot;highlighter-rouge&quot;&gt;ConfigSlurper&lt;/code&gt; (and its cousins) making a slurping noise as it executes (slurps?), complete with a louder noise as it ends - similar to an annoying kid sucking at the last bit of drink from an empty cup filled with ice. One has to wonder about the wisdom behind calling a class Slurper in a professional software library. But perhaps such concerns are not valid when dealing with a language called Groovy.  The software world has a penchant for coming up with interesting names. Apart from culinary and beverage related names such as Java, Beans, Cocoa and Guava topped with Sugar and eliciting a Yum response, we also have reptilian and warrior names like Python, Boa and Ninja. Indeed a simple perusal of Github leads to encounters with Pigshell, Nightmare and Phantom. Not to be left behind, the hardware world is re-calibrating from sophisticated names like Centrino and Ivy Bridge to Raspberry Pi and Beaglebone.&lt;/p&gt;

&lt;p&gt;In object oriented design, coming up with a good name is a hard problem. In fact, most of the arguments in OO design are related to naming objects. As a professor once said, there are just two problems in Computer Science:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Naming objects&lt;/li&gt;
  &lt;li&gt;Cache invalidation and&lt;/li&gt;
  &lt;li&gt;Off by one errors.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Having had my share of endless arguments over class names, I decided to investigate open source software to see what words appear in class names. I wrote up a program to download the source jars for the latest version of all Java libraries available via Maven Central. An hour later I had 60,000 odd jars downloaded on my hard-drive and ready to analyze. Mining Maven central programmatically is interesting enough to deserve an article of its own. Stay tuned for that. I wrote a simple program to then read the jars and parse all class names into its constituent pieces. I owe the parsing of the names to a clever bit of regex that I found on &lt;a href=&quot;http://stackoverflow.com/questions/2559759/how-do-i-convert-camelcase-into-human-readable-names-in-java&quot;&gt;Stackoverflow&lt;/a&gt;. Its only fitting that the answer was by a user named poly-gene-lubricants!&lt;/p&gt;

&lt;p&gt;Here are some findings from parsing the names:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;It looks like we software engineers are an ego-centric bunch. While I found 2,487 references to “My” in classnames, I only found 4 references to “Your.”&lt;/li&gt;
  &lt;li&gt;The most common word was … Type! A whopping 107,246 times. But that is from a total of 6,906,643 words.&lt;/li&gt;
  &lt;li&gt;We seem to be doing a good job of separating interfaces from implementation as evidenced by the close runner up - Impl - with 102,786 references.&lt;/li&gt;
  &lt;li&gt;We like our fruits - Fruit (18), Apple (133), Berry (36), Banana (12), Peach (2), Mango (35) and Grape (23). And we have some die-hard screaming fans of APPLE (23).&lt;/li&gt;
  &lt;li&gt;We do not like our vegetables. Perhaps those who’s mothers fail to impress upon them the importance of eating vegetables end up as engineers? The first lady may want to take note! Broccoli (0), Spinach (0), Squash (5). Who are these wierdo squash lovers?&lt;/li&gt;
  &lt;li&gt;But we do like meat! Meatball (1), Meat (2), Chicken (58), Beef (2). I shudder to use the Chicken library.&lt;/li&gt;
  &lt;li&gt;Oh and we like cheese with that (36).&lt;/li&gt;
  &lt;li&gt;Some of us secretly wish we were in the Restaurant business: Cook (19), Waiter (84), Server (17,166), Host (4,772) and Janitor (30). I found no reference to Hostess, proof positive that we do have a gender problem in tech!&lt;/li&gt;
  &lt;li&gt;If we started a zoo, we’d find: Pandas (1), Monkeys (20), Tigers (83), Dogs (132), Cats (351), Snakes (95), Donkeys (5), Zebras (26), Horses (28), Cows (68), Elephants (19), Giraffes (10) and Lions (21).&lt;/li&gt;
  &lt;li&gt;Is there a lot of workplace violence associated with software development? There really ought to be more - Punch (39), Beat (49), Box (4,993), Poke (6) and Kick (20).&lt;/li&gt;
  &lt;li&gt;Among unusual names, I found:
    &lt;ol&gt;
      &lt;li&gt;Valorizer - since nerdy engineer and valor never appear in the same sentence together.&lt;/li&gt;
      &lt;li&gt;Dateless - a reference to the bespectacled geek in the office.&lt;/li&gt;
      &lt;li&gt;Datefind - the geek’s attempt to cure the above stated malady.&lt;/li&gt;
      &lt;li&gt;Autodate - When the geek resorts to chatting with an IM bot.&lt;/li&gt;
      &lt;li&gt;Ntpdate - What a geek does to schedule the one accidental date he lands.&lt;/li&gt;
      &lt;li&gt;Undated - The result of the one accidental date.&lt;/li&gt;
      &lt;li&gt;Unblack - pseudonym for Michael Jackson?&lt;/li&gt;
      &lt;li&gt;Pockuito - A delectable Polish sausage recommended with Prosciutto.&lt;/li&gt;
      &lt;li&gt;Sweetener - A class used to make you sign the employment agreement.&lt;/li&gt;
      &lt;li&gt;Cobbled - A general reference to the way most software is put together. Shame! only one guy was willing to admit it.&lt;/li&gt;
      &lt;li&gt;Monotonous - Denotes a class with a lot of copy-n-paste!&lt;/li&gt;
      &lt;li&gt;Seniority - Hooray! We don’t have an age problem in IT. Oh wait! There was only one reference to it.&lt;/li&gt;
      &lt;li&gt;Switcheroo - Evidence we didn’t pay attention during English class.&lt;/li&gt;
      &lt;li&gt;Duplciate - More evidence we didn’t pay attention during English class.&lt;/li&gt;
      &lt;li&gt;Boogaloo - A disruptive software solution to the Ghostbusters.&lt;/li&gt;
      &lt;li&gt;Anonymizing - What the author of Boogaloo did.&lt;/li&gt;
      &lt;li&gt;Absolutechildren - Remnant of someone’s militaristic upbringing.&lt;/li&gt;
      &lt;li&gt;Delinquency - Unfortunately not of the juvenile (0) type.&lt;/li&gt;
      &lt;li&gt;Greenish - a sophisticated word in the male vocabulary for Teal.&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are 2,760 class names that are greater than 50 characters in length. Among the largest are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“Has This Type Pattern Tried To Sneak In Some Generic Or Parameterized Type Pattern matching Stuff Anywhere Visitor” (from Apache ServiceMix aspectJ 1.8.0)&lt;/li&gt;
  &lt;li&gt;“Web Get Number Of Parent Process Instances With Active User And Activity Instance Expected End Date” (from Bonita Server 5.10.2)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would have loved to be a fly on the wall when these names were being discussed!&lt;/p&gt;

&lt;p&gt;The raw class component names data is available as a &lt;a href=&quot;/public/data/class-name-word-frequency.csv&quot;&gt;CSV file&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Solving Wordament</title>
   <link href="http://www.eclecticlogic.com/2014/10/17/wordament-solver/"/>
   <updated>2014-10-17T00:00:00+00:00</updated>
   <id>http://www.eclecticlogic.com/2014/10/17/wordament-solver</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Statutory Disclaimer: This post is simply an exercise in algorithm development. It is not a warrant to attempt to cheat while playing Wordament. Any attempt to cheat the game will get you booted. The booting will be well deserved and this blog takes no responsibility for it.&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;game-time&quot;&gt;Game Time&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://www.wordament.com/&quot;&gt;Wordament&lt;/a&gt; is a very popular word puzzle that is available on all the mobile app stores. The object of the game is to identify as many words as possible from a 4x4 grid of letters. Words are formed by sliding your finger on the letters. You can form words by moving in any direction as long as you don’t repeat the letters. You get points for your words - longer words earn more points and there are special bonuses for uncommon words and words that contain letter sequences that are specifically called out.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.wordament.com/wp-content/uploads/2013/01/wordament_512x512.png&quot; alt=&quot;Wordament for XBox&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A first time casual player will be simultaneously astounded at the number of words identified by the winners of any given round and embarrassed by their own dismal  performance. In fact, the winners are jaw-droppingly fast. Have a look at this video of a face-off (or is that word-off?):&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;420&quot; allowfullscreen=&quot;allowfullscreen&quot; src=&quot;http://www.youtube.com/embed/zYeCYS7hk-g?color=white&amp;amp;theme=light&quot;&gt; &lt;/iframe&gt;

&lt;p&gt;Some of us speed-challenged folks, especially the geeks at heart may consider instead the challenge of algorithmically finding all the words. The problem is relatively straightforward and with adequate setup may even make a great interview question. If you do use this as an interview question, I would strongly suggest letting the candidate program on a computer with an IDE/language of their choice and not on a whiteboard.&lt;/p&gt;

&lt;h3 id=&quot;word-bank&quot;&gt;Word Bank&lt;/h3&gt;

&lt;p&gt;First we need a database of valid words. Here are a couple of sources to get such a list of words:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www-01.sil.org/linguistics/wordlists/english/&quot;&gt;SIL English Wordlist&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://wordlist.aspell.net/&quot;&gt;SCOWL&lt;/a&gt; dictionary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At a high-level, our task will be to navigate the grid adding letters to a sequence and testing if what we have is a valid word. Our challenge is to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Ensure that we navigate all permutations of the letters.&lt;/li&gt;
  &lt;li&gt;Not visit any letter more than once.&lt;/li&gt;
  &lt;li&gt;Determine if the sequence of letters we have is a valid word.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The last step is straightforward. We can simply load the entire list of valid words into a HashMap and check to see if the word we’ve assembled is valid. However, for our purpose, we are going to eschew the HashMap based approach and instead construct a tree of valid words such that we can more efficiently figure out if a word is valid or not. From a practical computational standpoint, this extra optimization is not going to make a material difference. However, the optimization does have academic value.&lt;/p&gt;

&lt;h3 id=&quot;from-word-bank-to-word-tree&quot;&gt;From Word Bank to Word Tree&lt;/h3&gt;

&lt;p&gt;We will construct our word tree by creating nodes that have two properties:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;A letter value.&lt;/li&gt;
  &lt;li&gt;An index of up to 26 child nodes, one per letter that can follow the current node.&lt;/li&gt;
  &lt;li&gt;A flag that indicates if the path from the root to the current node represents a valid word.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We use two classes to construct the nodes, a &lt;code class=&quot;highlighter-rouge&quot;&gt;NodeLoader&lt;/code&gt; and the &lt;code class=&quot;highlighter-rouge&quot;&gt;Node&lt;/code&gt; itself. The code for these classes is shown below:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NodeLoader&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IOException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// LineIterator and FileUtils are from apache commons io.
&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;LineIterator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FileUtils&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lineIterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;src/main/resources/dict.txt&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
		
		&lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setWord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		
		&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;hasNext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toLowerCase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;trim&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;createNodes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setWord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
		
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
	

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createNodes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;createOrGet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;charAt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createNodes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Notice that root node does not represent a letter. In fact, the Nodes don’t explicitly represent a letter. The letter representation is implicit from their position in the parent. For example, the sequence from the root node of the first child node, its second child node and its third child node represent the letter sequence ‘abc’.&lt;/p&gt;

&lt;p&gt;The Node is a simple class of mostly boilerplate code (please Oracle, if you are listening, at least add &lt;a href=&quot;http://projectlombok.org/&quot;&gt;Lombok&lt;/a&gt; style @Getter/@Setter annotations to Java 9?)&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;branches&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;];&lt;/span&gt;


    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;isWord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setWord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;word&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getNode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'a'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;branches&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createOrGet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getNode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;branches&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'a'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;wording-it-together&quot;&gt;“Wording” it together&lt;/h3&gt;

&lt;p&gt;Armed with our word-tree, we can now write the grid input and traverse logic. For reading in the input, we will require the user to type in four lines of letters with each line containing 4 letters. We can then parse the letters and put them into a two-dimensional array:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;        	&lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NodeLoader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Scanner&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scanner&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Scanner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[][]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;];&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;parts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scanner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;nextLine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;parts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scanner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;nextLine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;parts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scanner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;nextLine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;parts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scanner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;nextLine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;charAt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;With the grid initialized we now have to traverse the grid. Our grid traversal must consider every location in the grid as a starting point. As we traverse the grid and identify valid words, we add it to a set (thus eliminating duplicates). Once the words have all been identified, we can sort them by length and print them. At a high level, assuming a “traverse” method, the code required is:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;       &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;traverse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ArrayList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wordsFound&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Collections&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Comparator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

            &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;compare&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;o1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;o2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;o2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;o1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The variable &lt;code class=&quot;highlighter-rouge&quot;&gt;wordsFound&lt;/code&gt; is simple HashSet. The only thing left to flush out is the traverse routine. Grid traversal is easily written as a recursive routine. Our job is to consider the current location, add the letter to the sequence by grabbing the appropriate child node of the current node (indexed by the letter) and seeing if the node represents a complete word. If it does, we add it to our list of valid words and then try to traverse by moving in each of the 8 different directions we can head in (left, right, up, down, diagonally to the top-right, top-left, bottom-right and bottom-left).&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cm&quot;&gt;/**
     * @param grid The grid of letters representing the game.
     * @param visited A grid of indicators telling us which letters have already been visited.
     * @param i Our current location in the grid. x-axis
     * @param j Our current location in the grid. y-axis
     * @param node The node we have just visited.
     * @param current The currently formulated word.
     */&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;traverse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[][]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[][]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newStr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Character&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getNode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isWord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newStr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;wordsFound&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newStr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;traverse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newStr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;traverse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newStr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;traverse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newStr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;traverse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newStr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;traverse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newStr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;traverse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newStr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;traverse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newStr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;traverse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newStr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;visited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Here is a sample run. The letters entered are:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;abcd&lt;/code&gt;&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;efgh&lt;/code&gt;&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;ijkl&lt;/code&gt;&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;mnop&lt;/code&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;This gives us the following words:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;knife&lt;/li&gt;
  &lt;li&gt;plonk&lt;/li&gt;
  &lt;li&gt;glop&lt;/li&gt;
  &lt;li&gt;mink&lt;/li&gt;
  &lt;li&gt;jink&lt;/li&gt;
  &lt;li&gt;fink&lt;/li&gt;
  &lt;li&gt;fab&lt;/li&gt;
  &lt;li&gt;ink&lt;/li&gt;
  &lt;li&gt;fin&lt;/li&gt;
  &lt;li&gt;lop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The complete code is available at &lt;a href=&quot;https://github.com/eclecticlogic/wordament&quot;&gt;Github&lt;/a&gt;. The code comes with a plea to use it to further academic interest in such puzzle solvers and not to get cheap thrills from cheating in the real game.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Groovier Groovy DSL</title>
   <link href="http://www.eclecticlogic.com/2014/09/26/groovy-dsl-executor/"/>
   <updated>2014-09-26T00:00:00+00:00</updated>
   <id>http://www.eclecticlogic.com/2014/09/26/groovy-dsl-executor</id>
   <content type="html">&lt;p&gt;DSLs allow a programmer to tailor-make keywords and syntax to express a higher abstract representation of a problem domain. Recognizing the power of DSLs, most modern JVM languages have taken to support them. &lt;a href=&quot;http://www.scala-lang.org/old/node/1403&quot;&gt;Scala&lt;/a&gt;, &lt;a href=&quot;http://groovy.codehaus.org/Writing+Domain-Specific+Languages&quot;&gt;Groovy&lt;/a&gt; and the up-and-coming &lt;a href=&quot;http://ceylon-lang.org/documentation/1.0/tour/named-arguments/&quot;&gt;Ceylon&lt;/a&gt; all support writing DSLs.&lt;/p&gt;

&lt;p&gt;Recently I needed to build a Groovy DSL to facilitate some complex data setup for executing automated scenario tests. The GroovyBuilder mechanism wasn’t to my liking as it seemed too closely tied to object instantiation and the canonical constructor syntax. While researching other options I came across &lt;a href=&quot;http://groovy.dzone.com/news/groovy-dsl-scratch-2-hours&quot;&gt;Steven Devijver’s&lt;/a&gt; post on creating Groovy DSLs. Steve’s technique works by defining a closure to bootstrap the script execution and redirecting method resolution using delegate modification and prioritization. The idea while intriguing had two aspects that didn’t fit well with my requirement:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;There wasn’t an easy way to supply the closure to a self-contained “DSL executor.”&lt;/li&gt;
  &lt;li&gt;I would have to provide closure definitions for every top-level method I wanted to have in my DSL.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;My ideal solution would involve giving a self-contained &lt;code class=&quot;highlighter-rouge&quot;&gt;DSLExecutor&lt;/code&gt; object a script filename and a handler object that had the method definitions for the script. I decided to dig through Spring’s &lt;code class=&quot;highlighter-rouge&quot;&gt;GenericGroovyApplicationContext&lt;/code&gt; that provides a DSL for Spring context configuration and the &lt;code class=&quot;highlighter-rouge&quot;&gt;groovy.lang.Script&lt;/code&gt; class for inspiration and clues to achieve this. Spring’s Groovy context loader takes advantage of the fact that the &lt;code class=&quot;highlighter-rouge&quot;&gt;groovy.lang.Script&lt;/code&gt; class, using an overridden invoke method, attempts to see if the &lt;code class=&quot;highlighter-rouge&quot;&gt;Binding&lt;/code&gt; object has a closure definition of the same name as the method that just failed to resolve:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-groovy&quot; data-lang=&quot;groovy&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;invokeMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;invokeMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// if the method was not found in the current scope (the script's methods)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// let's try to see if there's a method closure with the same name in the binding&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MissingMethodException&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mme&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mme&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;boundClosure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;boundClosure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;boundClosure&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Closure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Closure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;boundClosure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[])&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mme&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mme&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MissingPropertyException&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mpe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mme&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Combining ideas from Steve’s post, Spring and the groovy.lang.Script implementations, I realized that by supplying the  &lt;code class=&quot;highlighter-rouge&quot;&gt;groovy.lang.Script&lt;/code&gt;’s metaclass with a &lt;a href=&quot;http://groovy.codehaus.org/Using+methodMissing+and+propertyMissing&quot;&gt;methodMissing&lt;/a&gt; closure, I can effectively route unmatched methods to any arbitrary object. The result is a simple standalone DSL executor:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/eclecticlogic/2b8a8d78dab281a26378.js?file=DSLExecutor.groovy&quot;&gt; &lt;/script&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;DSLExecutor.execute()&lt;/code&gt; method accepts a script filename and a handler object. The script is resolved using Spring’s resource loader (you can therefore prefix the filename with &lt;code class=&quot;highlighter-rouge&quot;&gt;classpath:&lt;/code&gt; or other prefixes that Spring supports). The handler object is expected to have methods for your constructs in the DSL. The &lt;code class=&quot;highlighter-rouge&quot;&gt;execute()&lt;/code&gt; method returns a map of variables returned by the script.&lt;/p&gt;

&lt;p&gt;A simple example of a handler is shown below:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-groovy&quot; data-lang=&quot;groovy&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyHandler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

   &lt;span class=&quot;kt&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;printMe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Closure&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;println&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Hello $name&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The above code allows a simple DSL of the form:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-groovy&quot; data-lang=&quot;groovy&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;printMe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Dude&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We can extend the handler paradigm by making it hierarchical, wherein the handler delegates processing of some methods to a more specialized handler. For example, if our DSL had a section dealing with users, we may want to be able to write a construct such as:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-groovy&quot; data-lang=&quot;groovy&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;printMe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Dude&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tom&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Tom&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;login&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tom&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setRememberMe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We may want to segregate the responsibility for all user related methods to a UserHandler class. This is easily achieved within the primary handler by setting the delegate on the closure supplied to the users method.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-groovy&quot; data-lang=&quot;groovy&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserHandler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;c1&quot;&gt;// ... various methods&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyHandler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

   &lt;span class=&quot;kt&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;printMe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Closure&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;println&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Hello $name&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

   &lt;span class=&quot;kt&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Closure&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;UserHandler&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UserHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;delegate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handler&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;resolveStrategy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Closure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;DELEGATE_FIRST&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We thus have yet-another-DSL construction paradigm using Groovy. I hope other folks find this useful and are able to create some elegant tailor-made DSLs with it.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Classpath scanning with Spring</title>
   <link href="http://www.eclecticlogic.com/2014/09/01/classpath-scanning/"/>
   <updated>2014-09-01T00:00:00+00:00</updated>
   <id>http://www.eclecticlogic.com/2014/09/01/classpath-scanning</id>
   <content type="html">&lt;p&gt;Spring has a number of utilities that the framework ships with. One of them is a classpath scanner provided by &lt;code class=&quot;highlighter-rouge&quot;&gt;ClassPathScanningCandidateComponentProvider&lt;/code&gt;. That is a long name and a mouthful. The class allows you to enable auto-discovery features in your own framework or code. Here is a simple example to demonstrate its use:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/eclecticlogic/7551622.js?file=SpringClasspathScanner.java&quot;&gt; &lt;/script&gt;

&lt;p&gt;The constructor takes a boolean parameter to apply default filters or not. Default filters are based on annotations for &lt;code class=&quot;highlighter-rouge&quot;&gt;@Component&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;@Repository&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;@Service&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;@Controller&lt;/code&gt;. Once you have your provider, you give it filters to zero-in on the types you are interested in. Filters implement the &lt;code class=&quot;highlighter-rouge&quot;&gt;TypeFilter&lt;/code&gt; interface and Spring helpfully ships with a number of useful ones:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;AnnotationTypeFilter: filters based on annotations on the class.&lt;/li&gt;
  &lt;li&gt;AssignableTypeFilter: filters that match based on superclass or interface.&lt;/li&gt;
  &lt;li&gt;RegexPatternTypeFilter: matches a fully qualified class name against a regular expression.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Spring also has an AbstractClassTestingTypeFilter that allows you to write your own matcher against class metadata that spring provides for each Class/Interface that it finds.&lt;/p&gt;

&lt;p&gt;Once you have your filters defined, you simply give the scanning provider a root package to search within and it returns you a list of BeanDefinition objects for matches. You may incorrectly assume, because of the name BeanDefinition, that this is restricted to beans in a Spring context. Thankfully, it is not, as that would severely restrict the utility value of this class. The BeanDefinition is simply a container of useful information about the class including the &lt;code class=&quot;highlighter-rouge&quot;&gt;Class&lt;/code&gt; instance.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Introducing Whisper</title>
   <link href="http://www.eclecticlogic.com/2014/08/25/introducing-whisper/"/>
   <updated>2014-08-25T00:00:00+00:00</updated>
   <id>http://www.eclecticlogic.com/2014/08/25/introducing-whisper</id>
   <content type="html">&lt;p&gt;Its common these days for Java based projects to use a logger like Logback and it is also very common to have an Email appender delivery error emails to your development or support team. This is not only common, but it is also good practice. The enabling of timely feedback can not only help correct issues in a production environment as soon as they happen, but it also allows you to respond to users of the system who were affected by the issue proactively.&lt;/p&gt;

&lt;p&gt;A side-effect of such proactive monitoring that is often overlooked is that a simple email appender can very easily result in a flood of emails if something critical (such as user database) goes offline or if a often-used functionality stops working. Logback has a &lt;a href=&quot;http://logback.qos.ch/manual/filters.html#DuplicateMessageFilter&quot;&gt;DuplicateMessageFilter&lt;/a&gt; that one can configure to suppress duplicates but it is too simplistic. Once it starts to suppress the message, there doesn’t seem to be a mechanism to revive the logging.&lt;/p&gt;

&lt;h3 id=&quot;enter-whisper&quot;&gt;Enter Whisper&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/eclecticlogic/whisper&quot;&gt;Whisper&lt;/a&gt; is a generic appender written to solve precisely this problem. However, the architecture of Whisper allows you to throttle any other “endpoint” appender - SMTPAppender being one of them. In other words, Whisper is an appender that sits in between your log statement and the final appender. It feeds the final appender as long as a per-message threshold is not breached. Once breached it suppresses all messages until idle rate is achieved.&lt;/p&gt;

&lt;p&gt;Whisper is available via Maven Central:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.eclecticlogic&lt;span class=&quot;nt&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;whisper&lt;span class=&quot;nt&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;packaging&amp;gt;&lt;/span&gt;jar&lt;span class=&quot;nt&quot;&gt;&amp;lt;/packaging&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.3&lt;span class=&quot;nt&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The Whisper binary and source code can be downloaded from the &lt;a href=&quot;http://eclecticlogic.github.io/whisper/&quot;&gt;Github page&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;getting-started&quot;&gt;Getting started&lt;/h3&gt;

&lt;p&gt;The Whisper code ships with a sample logback configuration (under src/sample/resources). But here is the configuration for use with Logback to handle the most common case of suppressing ERROR messages that are sent via the email appender.&lt;/p&gt;

&lt;p&gt;To configure the Whisper appender, first you must configure two other appenders - the regular email appender for ERROR level logs and a second email appender for sending the suppression Digests when suppression kicks in.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;appender&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;errorEmail&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ch.qos.logback.classic.net.SMTPAppender&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;filter&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ch.qos.logback.classic.filter.LevelFilter&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;level&amp;gt;&lt;/span&gt;ERROR&lt;span class=&quot;nt&quot;&gt;&amp;lt;/level&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;onMatch&amp;gt;&lt;/span&gt;ACCEPT&lt;span class=&quot;nt&quot;&gt;&amp;lt;/onMatch&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;onMismatch&amp;gt;&lt;/span&gt;DENY&lt;span class=&quot;nt&quot;&gt;&amp;lt;/onMismatch&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/filter&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;smtpHost&amp;gt;&lt;/span&gt;ADDRESS-OF-YOUR-SMTP-HOST&lt;span class=&quot;nt&quot;&gt;&amp;lt;/smtpHost&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;to&amp;gt;&lt;/span&gt;EMAIL-DESTINATION&lt;span class=&quot;nt&quot;&gt;&amp;lt;/to&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;from&amp;gt;&lt;/span&gt;SENDER-EMAIL&lt;span class=&quot;nt&quot;&gt;&amp;lt;/from&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;subject&amp;gt;&lt;/span&gt;TESTING: %logger{20} - %m&lt;span class=&quot;nt&quot;&gt;&amp;lt;/subject&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;layout&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ch.qos.logback.classic.PatternLayout&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;pattern&amp;gt;&lt;/span&gt;%date %-5level %logger{35} - %message%n&lt;span class=&quot;nt&quot;&gt;&amp;lt;/pattern&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/layout&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/appender&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;appender&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;errorDigest&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ch.qos.logback.classic.net.SMTPAppender&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;smtpHost&amp;gt;&lt;/span&gt;ADDRESS-OF-YOUR-SMTP-HOST&lt;span class=&quot;nt&quot;&gt;&amp;lt;/smtpHost&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;to&amp;gt;&lt;/span&gt;EMAIL-DESTINATION&lt;span class=&quot;nt&quot;&gt;&amp;lt;/to&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;from&amp;gt;&lt;/span&gt;SENDER-EMAIL&lt;span class=&quot;nt&quot;&gt;&amp;lt;/from&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;subject&amp;gt;&lt;/span&gt;%X{whisper.digest.subject}&lt;span class=&quot;nt&quot;&gt;&amp;lt;/subject&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;layout&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ch.qos.logback.classic.PatternLayout&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;pattern&amp;gt;&lt;/span&gt;%date %-5level %logger{35} - %message%n&lt;span class=&quot;nt&quot;&gt;&amp;lt;/pattern&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/layout&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/appender&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;As you can see Whisper adds a special entry into the Mapped-Diagnostic-Context (MDC) to convey an appropriate email subject for the error digest.&lt;/p&gt;

&lt;p&gt;Next we configure the Whisper appender itself.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;appender&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;whisper&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.eclecticlogic.whisper.logback.WhisperAppender&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Filter out non error logs --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;filter&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ch.qos.logback.classic.filter.LevelFilter&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;level&amp;gt;&lt;/span&gt;ERROR&lt;span class=&quot;nt&quot;&gt;&amp;lt;/level&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;onMatch&amp;gt;&lt;/span&gt;ACCEPT&lt;span class=&quot;nt&quot;&gt;&amp;lt;/onMatch&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;onMismatch&amp;gt;&lt;/span&gt;DENY&lt;span class=&quot;nt&quot;&gt;&amp;lt;/onMismatch&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/filter&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- This is the name of the logging category to use to send out error digests. This is associated with the 
    errorDigest appender. --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;digestLoggerName&amp;gt;&lt;/span&gt;digest.appender.logger&lt;span class=&quot;nt&quot;&gt;&amp;lt;/digestLoggerName&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;&amp;lt;!--  suppressAfter specifies the criteria to enter suppression. The example below says that if 3 errors of the same kind
    are encountered within a 5 minute window, then suppression should kick in. --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;suppressAfter&amp;gt;&lt;/span&gt;3 in 5 minutes&lt;span class=&quot;nt&quot;&gt;&amp;lt;/suppressAfter&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- expireAfter specifies how much of silence the logger must see between messages before stopping suppression. --&amp;gt;&lt;/span&gt; 
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;expireAfter&amp;gt;&lt;/span&gt;4 minutes&lt;span class=&quot;nt&quot;&gt;&amp;lt;/expireAfter&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- digestFrequency specifies how often error email digests should be sent containing statistics on messages 
    suppressed --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;digestFrequency&amp;gt;&lt;/span&gt;20 minutes&lt;span class=&quot;nt&quot;&gt;&amp;lt;/digestFrequency&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- The pass-through appender for the normal case when suppression is not in-force. --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;appender-ref&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;ref=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;errorEmail&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/appender&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The units for the &lt;code class=&quot;highlighter-rouge&quot;&gt;suppressAfter&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;expireAfter&lt;/code&gt; elements can be seconds (s, sec, or secs), minutes (m, min or mins) and hours (h, hr or hrs).&lt;/p&gt;

&lt;p&gt;The digest logger name is then associated with the digestAppender and the whisper appender is included in the list of default appenders.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;logger&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;digest.appender.logger&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;level=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;error&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;additivity=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;false&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;appender-ref&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;ref=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;errorDigest&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/logger&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;root&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;level=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;debug&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;appender-ref&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;ref=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;whisper&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;appender-ref&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;ref=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;fileAppender&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/root&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Whisper has been released under the Apache License 2.0. &lt;a href=&quot;https://github.com/eclecticlogic/whisper/tarball/master&quot;&gt;Download&lt;/a&gt; the library or &lt;a href=&quot;https://github.com/eclecticlogic/whisper/fork&quot;&gt;fork&lt;/a&gt; the code and give it a shot. I’d love to hear your feedback.&lt;/p&gt;
</content>
 </entry>
 

</feed>
