<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D0QCSHg_fCp7ImA9WxBVE04.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745</id><updated>2010-02-16T15:49:29.644Z</updated><title>i haz teh codez</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>17</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/IHazTehCodez" /><feedburner:info uri="ihaztehcodez" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DkAGQnc8fSp7ImA9WxNaGEg.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-3419337027245180458</id><published>2009-12-03T15:38:00.000Z</published><updated>2009-12-03T15:38:43.975Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-03T15:38:43.975Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="html" /><category scheme="http://www.blogger.com/atom/ns#" term="teh codez" /><title>Code Dump: Stripping out HTML</title><content type="html">Two solutions for this seam to pop up - Regex and using &lt;a href="http://stackoverflow.com/questions/240546/removing-html-from-a-java-string"&gt;HTMLEditorKit&lt;/a&gt;. The first is very broken and can not handle escape characters, the latter works well but does not maintain formatting. So here is my &lt;a href="http://github.com/mlk/ihaztehcodez/blob/master/src/ihaztehcodez/utils/StripHtml.java"&gt;expanded version &lt;/a&gt;which also breaks when it encounters a tag that breaks the flow.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;div class="line" id="LC1"&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="n"&gt;ihaztehcodez&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;utils&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC2"&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="line" id="LC3"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC4"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.Reader&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC5"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.StringReader&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC6"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Arrays&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC7"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Collection&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC8"&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="line" id="LC9"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.swing.text.MutableAttributeSet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC10"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.swing.text.html.HTML&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC11"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.swing.text.html.HTMLEditorKit&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC12"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.swing.text.html.parser.ParserDelegator&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC13"&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="line" id="LC14"&gt;&lt;span class="cm"&gt;/** Strips HTML from text. &lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC15"&gt;&lt;span class="cm"&gt; * &lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC16"&gt;&lt;span class="cm"&gt; * @author mlk&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC17"&gt;&lt;span class="cm"&gt; *&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC18"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC19"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StripHtml&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC20"&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="line" id="LC21"&gt; &lt;span class="cm"&gt;/** Utility class. */&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC22"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;StripHtml&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC23"&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="line" id="LC24"&gt; &lt;span class="cm"&gt;/** Strips HTML from the content given.&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC25"&gt;&lt;span class="cm"&gt;  * &lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC26"&gt;&lt;span class="cm"&gt;  * @param value The string to strip.&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC27"&gt;&lt;span class="cm"&gt;  * @return A textual representation.&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC28"&gt;&lt;span class="cm"&gt;  */&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC29"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;stripped&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC30"&gt;  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC31"&gt;   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;stripped&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;StringReader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC32"&gt;  &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;ioe&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC33"&gt;   &lt;span class="c1"&gt;// This should never happen as the StringReader can not throw an IOE.&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC34"&gt;   &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ioe&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC35"&gt;  &lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC36"&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="line" id="LC37"&gt; &lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC38"&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="line" id="LC39"&gt; &lt;span class="cm"&gt;/** Strips HTML from the content given.&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC40"&gt;&lt;span class="cm"&gt;  * &lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC41"&gt;&lt;span class="cm"&gt;  * @param value The content to strip.&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC42"&gt;&lt;span class="cm"&gt;  * @return A textual representation.&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC43"&gt;&lt;span class="cm"&gt;  */&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC44"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;stripped&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Reader&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="n"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC45"&gt;  &lt;span class="n"&gt;ParserDelegator&lt;/span&gt; &lt;span class="n"&gt;delegator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ParserDelegator&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC46"&gt;  &lt;span class="n"&gt;StripOMatic&lt;/span&gt; &lt;span class="n"&gt;matic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;StripOMatic&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC47"&gt;  &lt;span class="n"&gt;delegator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;matic&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC48"&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="line" id="LC49"&gt;  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;matic&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC50"&gt; &lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC51"&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="line" id="LC52"&gt; &lt;span class="cm"&gt;/** Read in the text file and adds a new line when a breaking tag is encountered.&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC53"&gt;&lt;span class="cm"&gt;  * &lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC54"&gt;&lt;span class="cm"&gt;  * @author Michael Lee&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC55"&gt;&lt;span class="cm"&gt;  *&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC56"&gt;&lt;span class="cm"&gt;  */&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC57"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StripOMatic&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;HTMLEditorKit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ParserCallback&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC58"&gt;  &lt;span class="cm"&gt;/** The string value. */&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC59"&gt;  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC60"&gt;  &lt;span class="cm"&gt;/** Some tags should be ignored. */&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC61"&gt;  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HTML&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Tag&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ignore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HTML&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Tag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HTML&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;/div&gt;&lt;div class="line" id="LC62"&gt;    &lt;span class="n"&gt;HTML&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Tag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;BODY&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HTML&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Tag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HEAD&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC63"&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="line" id="LC64"&gt;  &lt;span class="cm"&gt;/** If the tag breaks the flow then add a new line, otherwise ignore.&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC65"&gt;&lt;span class="cm"&gt;   * {@inheritDoc} &lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC66"&gt;&lt;span class="cm"&gt;   */&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC67"&gt;  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;handleStartTag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;HTML&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Tag&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;MutableAttributeSet&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC68"&gt;   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ignore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC69"&gt;    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC70"&gt;   &lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC71"&gt;   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;breaksFlow&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC72"&gt;    &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\n"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC73"&gt;   &lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC74"&gt;  &lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC75"&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="line" id="LC76"&gt;  &lt;span class="cm"&gt;/** Delegates to handleStartTag.&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC77"&gt;&lt;span class="cm"&gt;   * {@inheritDoc} &lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC78"&gt;&lt;span class="cm"&gt;   */&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC79"&gt;  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;handleSimpleTag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;HTML&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Tag&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;MutableAttributeSet&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC80"&gt;   &lt;span class="n"&gt;handleStartTag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC81"&gt;  &lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC82"&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="line" id="LC83"&gt;  &lt;span class="cm"&gt;/** Adds the following chunk of text.&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC84"&gt;&lt;span class="cm"&gt;   * &lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC85"&gt;&lt;span class="cm"&gt;   * {@inheritDoc}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC86"&gt;&lt;span class="cm"&gt;   */&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC87"&gt;  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;handleText&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC88"&gt;   &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC89"&gt;  &lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC90"&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="line" id="LC91"&gt;  &lt;span class="cm"&gt;/** @return The text version of the data parsed so far. */&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC92"&gt;  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC93"&gt;   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC94"&gt;  &lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC95"&gt; &lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC96"&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-3419337027245180458?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/3419337027245180458/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=3419337027245180458" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/3419337027245180458?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/3419337027245180458?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/ksgPozzaNvA/code-dump-stripping-out-html.html" title="Code Dump: Stripping out HTML" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2009/12/code-dump-stripping-out-html.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YAQHcycSp7ImA9WxNaFUQ.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-4339341386253399152</id><published>2009-11-30T15:28:00.002Z</published><updated>2009-11-30T15:32:21.999Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-30T15:32:21.999Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rambling" /><category scheme="http://www.blogger.com/atom/ns#" term="teh codez" /><title>Code Dump: Stubbing with a map</title><content type="html">A year or so back I wrote a cool little utility class &lt;a href="http://github.com/mlk/ihaztehcodez/blob/master/src/ihaztehcodez/testing/MapInvocationHandler.java" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;MyInvocationHandler&lt;/a&gt;. This is used by simply creating a map of the proprieties and their values simply as I felt that:&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Map&lt;string, object=""&gt; backing = new HashMap&lt;string, object=""&gt;();&lt;/string,&gt;&lt;/string,&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;backing.put("title", "ihaztehcodez");&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;backing.put("getURL",&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "ihaztehcodez.michael-lloyd-lee.me.uk");&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Blog thisHereBlog = create(backing, Blog.class);&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
was easier on the eyes that the EasyMock styled&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Blog thisHereBlog = createNiceMock(Blog.class);&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;expect(thisHereBlog.getTitle())&lt;br /&gt;
&amp;nbsp;&amp;nbsp; .andReturn("ihaztehcodez").anyTimes();&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;expect(thisHereBlog.getURL())&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; .andReturn("ihaztehcodez.michael-lloyd-lee.me.uk")&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; .anyTimes();&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;replay(thisHereBlog);&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
However I was wrong to use either method. If I was to do so again I'd use write a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;BlogBuilder&lt;/span&gt;. It is a good chunk more work up front, but it leads to significantly better reading code.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Blog thisHereBlog = new BlogBuilder()&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .withTitle("ihaztehcodez")&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; .withURL( "ihaztehcodez.michael-lloyd-lee.me.uk")&lt;br /&gt;
&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; .build();&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: inherit;"&gt;This does mean I now have a mini project to start. Write a JPA thingie to generate a&lt;/span&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; builder.&lt;/span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-4339341386253399152?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/4339341386253399152/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=4339341386253399152" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/4339341386253399152?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/4339341386253399152?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/7lcozYPrYGQ/code-dump-stubbing-with-map.html" title="Code Dump: Stubbing with a map" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2009/11/code-dump-stubbing-with-map.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAFQ3c6eyp7ImA9WxNaEUk.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-2808902142345459121</id><published>2009-11-25T11:16:00.003Z</published><updated>2009-11-25T11:31:52.913Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-25T11:31:52.913Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="mini-article" /><category scheme="http://www.blogger.com/atom/ns#" term="multiple instances" /><title>Preventing multiple instances of an application from running.</title><content type="html">This is a common question, with a very common answer - create a machine wide &lt;a href="http://en.wikipedia.org/wiki/Semaphore_%28programming%29"&gt;semaphore&lt;/a&gt;. The most common recommendation in Java is to use a &lt;a href="http://stackoverflow.com/questions/177189/how-to-implement-a-single-instance-java-application"&gt;socket&lt;/a&gt;. However this answer has a flaw. In a multi-user environment you do not want a machine-wide, you want a user-wide semaphore. I have seen some very complex solutions to this issue but there is a very simple answer. Use a file lock.&lt;br /&gt;
The common reason against using files is that they are not automatically cleaned when the application is forcible terminated (for example hitting the big red button). This is true if you use the existence of a file to determine if a previous instance is running, but there is a better option than this. Use the &lt;a href="http://java.sun.com/javase/6/docs/api/java/nio/channels/FileLock.html"&gt;FileLock&lt;/a&gt; for a file in the users home directory. FileLocks are automatically cleaned by the OS should the application die without unlocking and can be placed in a location that will be local to the user allowing this solution to work on multi-user environment such as &lt;a href="http://en.wikipedia.org/wiki/Remote_Desktop_Services"&gt;Windows Terminal Server&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.io.File;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.io.IOException;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.io.RandomAccessFile;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.nio.channels.FileChannel;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.nio.channels.FileLock;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.nio.channels.OverlappingFileLockException;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.util.logging.Level;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.util.logging.Logger;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/** Prevents two instances of the application from starting at the same time.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;* &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;* @author Mlk&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;* &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;*/&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public final class InstanceChecker {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /** A singleton instance. */&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static final InstanceChecker INSTANCE = new InstanceChecker();&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /** The file channel to be locked. */&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private FileChannel channel;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /** The lock on the file. */&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private FileLock lock;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /** The file to be locked. */&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private final File file = new File(new File(System.getProperty("user.home")), "/APPLICATION_NAME.lock");&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /** Logger. */&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Logger log = Logger.getLogger(getClass().getName());&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /** ctor. */&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private InstanceChecker() {&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /** Is this the only instance of this application currently executing.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* @return should the application be allowed to start up.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public boolean onlyInstance() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; channel = new RandomAccessFile(file, "rw").getChannel();&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; lock = channel.tryLock();&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (OverlappingFileLockException e) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (lock == null) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Runtime.getRuntime().addShutdownHook(new Thread() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; public void run() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; close();&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (IOException e) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; log.log(Level.WARNING, "Failed to lock file: " + file, e);&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /** Unlocks the file. */&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void close() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (lock != null) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; lock.release();&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (channel != null) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; channel.close();&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; file.delete();&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (final IOException e) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; System.err.println("Failed to unlock file!");&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
And you use it:&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public static void main(String argv...) {&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; if( !InstanceChecker.&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;INSTANCE&lt;/span&gt;.onlyInstance()) {&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Die!&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
It currently lacks the inter application communication, but I think that would be easily added by also having a "ping" file that would be touched during the die section of code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-2808902142345459121?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/2808902142345459121/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=2808902142345459121" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/2808902142345459121?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/2808902142345459121?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/Joo1TbUr6u8/preventing-multiple-instances-of.html" title="Preventing multiple instances of an application from running." /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2009/11/preventing-multiple-instances-of.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAERngzfSp7ImA9WxNUEUs.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-4255424568776228430</id><published>2009-11-02T13:15:00.000Z</published><updated>2009-11-02T13:15:07.685Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-02T13:15:07.685Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="stack overflow" /><category scheme="http://www.blogger.com/atom/ns#" term="html" /><category scheme="http://www.blogger.com/atom/ns#" term="screenshot" /><title>How to render HTML in Java then save this as an image</title><content type="html">A few Java based HTML renders exist, all with different sets of drawbacks. The most common is the one&amp;nbsp;&lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/text/html/HTMLEditorKit.html"&gt;built in&lt;/a&gt;. This is quite simple and can only render fairly basic HTML. The most interesting I know of is The &lt;a href="https://xhtmlrenderer.dev.java.net/"&gt;Flying Saucer Project&lt;/a&gt;. This can render fairly complex XHTML but you will have to convert HTML before you can use it (&lt;a href="http://jtidy.sourceforge.net/"&gt;JTindy&lt;/a&gt; or&amp;nbsp; may be able to help here). Taking a Swing component and creating a image is fairly simple, you just pass an &lt;a href="http://java.sun.com/javase/6/docs/api/java/awt/image/BufferedImage.html" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;BufferedImage&lt;/a&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;s&amp;nbsp;&lt;/span&gt;&lt;a href="http://java.sun.com/javase/6/docs/api/java/awt/image/BufferedImage.html#createGraphics%28%29"&gt;graphics&lt;/a&gt; object and pass it to the Swing components&amp;nbsp;&lt;a href="http://java.sun.com/javase/6/docs/api/javax/swing/JComponent.html#paint%28java.awt.Graphics%29"&gt;paint&lt;/a&gt; method. Then splat that out with &lt;a href="http://java.sun.com/javase/6/docs/api/javax/imageio/ImageIO.html" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ImageIO&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
A big advantage to this would be that the renderer would be headless. The disadvantage is that it would not be a perfect rendering and it would lack any plugin support.&lt;br /&gt;
&lt;br /&gt;
The second option requires you to start a web browser, work out where it is and then take a screen shot. Optionally you may also wish to strip out all the Firefox/IE/Opera/etc menus leaving you with just image. To get the dimensions of the web browser the simplest option would be to start it full screen. The other option would be to use something like JDICs&amp;nbsp;&lt;a href="https://jdic.dev.java.net/nonav/documentation/javadoc/jdic/org/jdesktop/jdic/browser"&gt;browser&lt;/a&gt; component to include it as part of the Java application. It would then be able to specify where the HTML is being rendered on screen and then simply use&amp;nbsp;&lt;a href="http://java.sun.com/javase/6/docs/api/java/awt/Robot.html" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Robot&lt;/a&gt; to create a screen shot of that area.&lt;br /&gt;
&lt;br /&gt;
The big advantage to this is that it will give a perfect rendering (for a given browser). The two disadvantages is that it would require native code (or at least using a native component) and it could not be headless¹.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) You could use a virtual frame buffer. But that is outside Java.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-4255424568776228430?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/4255424568776228430/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=4255424568776228430" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/4255424568776228430?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/4255424568776228430?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/lydtCj1od48/how-to-render-html-in-java-then-save.html" title="How to render HTML in Java then save this as an image" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2009/11/how-to-render-html-in-java-then-save.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEABQnk9eSp7ImA9WxNVGEw.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-4763740920537394463</id><published>2009-10-29T11:45:00.000Z</published><updated>2009-10-29T11:45:53.761Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-29T11:45:53.761Z</app:edited><title>Sad day. Sad sad day.</title><content type="html">Today I found out that &lt;a href="http://schmidt.devlib.org/"&gt;schmidt.devlib.org&lt;/a&gt; has been eaten by the great Noodly One in the sky. A real shame it was a very useful resource for Java developer. &lt;br /&gt;
&lt;br /&gt;
Hopefully it has found a new home.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-4763740920537394463?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/4763740920537394463/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=4763740920537394463" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/4763740920537394463?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/4763740920537394463?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/YCLMkaGh4Yg/sad-day-sad-sad-day.html" title="Sad day. Sad sad day." /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2009/10/sad-day-sad-sad-day.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8BR3Y7eCp7ImA9WxNVGU0.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-2292908426056575133</id><published>2009-10-27T13:46:00.003Z</published><updated>2009-10-30T11:57:36.800Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-30T11:57:36.800Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mock" /><category scheme="http://www.blogger.com/atom/ns#" term="unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="stack overflow" /><title>Mocking System Classes</title><content type="html">Today I answered a &lt;a href="http://stackoverflow.com/questions/1629841/how-to-jmockit-system-getenvstring/1630015#1630015"&gt;question &lt;/a&gt;about mocking system classes in Java on &lt;a href="http://stackoverflow.com/"&gt;Stack Overflow&lt;/a&gt;. I found the documentation for doing this somewhat limited, so I'm going to rework and repost my answer here.&lt;br /&gt;
&lt;br /&gt;
First things first. If you have to mock system classes then do you have anything slightly smelly in your design? Can you work the direct link between the two out by say introducing a &lt;a href="http://en.wikipedia.org/wiki/Facade_pattern"&gt;facade &lt;/a&gt;between the real dependency (java.lang.System) and the SUT.&lt;br /&gt;
&lt;br /&gt;
Assuming that you can not or do not want to then you have at least two options: &lt;a href="http://code.google.com/p/powermock/"&gt;PowerMock&lt;/a&gt; and &lt;a href="http://code.google.com/p/jmockit/"&gt;JMockIt.&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Lets first make a class to test &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;EnvOMatic&lt;/span&gt;. &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;EnvOMatic &lt;/span&gt;has one method, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;clean&lt;span style="font-family: inherit;"&gt; This loads&lt;/span&gt;&lt;/span&gt; a value from the Environment and cleans of dirty words. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class EnvOMatic {&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String clean(String key) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;String value = System.getenv(key);&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (value==null) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return null&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return value.replaceAll("Groovy", "naughty");&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;PowerMock&lt;/b&gt;&lt;br /&gt;
&lt;span style="font-family: inherit;"&gt;Power Mock has some &lt;a href="http://code.google.com/p/powermock/wiki/MockSystem"&gt;decent documentation &lt;/a&gt;for &lt;/span&gt;mocking system classes, but lets show an example of it&lt;br /&gt;
here.&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;package playtest;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import org.junit.Test;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import org.junit.runner.RunWith;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import org.powermock.core.classloader.annotations.PrepareForTest;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import org.powermock.modules.junit4.legacy.PowerMockRunner;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import static org.powermock.api.easymock.PowerMock.*;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import static org.easymock.EasyMock.*;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import static junit.framework.Assert.*;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@RunWith(PowerMockRunner.class)&lt;/span&gt; &lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@PrepareForTest( { EnvOMatic.class })&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class TestPowerMock {&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Test&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void assertThatMockingOfFinalSystemClassesWorks() throws Exception {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mockStatic(System.class);&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; final String key = "boo";&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; final String expected = "Bye";&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; expect(System.getenv(key)).andReturn(expected);&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; replayAll();&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assertEquals(expected, new EnvOMatic().clean(key));&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; verifyAll();&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
So in this we tell JUnit to use the PowerMock runner, then specify the SUT that uses the System class via annotations. Then in the test class we inform PowerMock that we are mocking &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;java.lang.System &lt;/span&gt;and finally use it as we would use any other &lt;a href="http://easymock.org/"&gt;EasyMock &lt;/a&gt;mock.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;One thing that caught me out was that the JUnit 4.7 provided in the "With Dependencies" download did not work. JUnit 4.4 shipped Eclipse did.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;JMockIt&lt;/b&gt;&lt;br /&gt;
Unlike PowerMock above I could not find any documentation on how to do this. The code below is various examples super glued together until it worked.&amp;nbsp;&lt;b&gt; &lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import org.junit.*;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import org.junit.runner.RunWith;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@RunWith(JMockit.class)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class TestJMockIt {&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Test&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void assertThatMockingOfFinalSystemClassesWorks() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Mockit.setUpMocks(MockSystem.class);&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; final String key = "boo";&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; final String expected = "Bye";&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; MockSystem.put(key, expected);&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; assertEquals(expected, new EnvOMatic().clean(key));&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @MockClass(realClass = System.class)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static class MockSystem {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; static Map&lt;string, string=""&gt; env = new HashMap&lt;string, string=""&gt;();&lt;/string,&gt;&lt;/string,&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; static void put(String key, String value) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; env.put(key, value);&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; @Mock&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; public static String getenv(String key) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return env.get(key);&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: inherit;"&gt;One thing to note about this is that we are not &lt;i&gt;mocking&lt;/i&gt; but &lt;i&gt;stubbing&lt;/i&gt; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;java.lang.System&lt;/span&gt;. &lt;/span&gt;Now in this case I don't think this is a problem.&lt;br /&gt;
To make this work we need to use a custom runner again, this time &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;JMockit&lt;span style="font-family: inherit;"&gt;. This runner does requires JUnit 4.5 or above.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: inherit;"&gt;Then we create a class with static methods stubs defined.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: inherit;"&gt;Finally we inform MockIt of the stub implementation.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: inherit;"&gt;So there you have two ways of stubbing and mocking&amp;nbsp; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;java.lang.System&lt;/span&gt;. They both have same restriction - a custom runner, and I'm sure they are equally as powerful, so the choice of which to use will depend solely on your API preference. &lt;/span&gt;&lt;span style="font-family: inherit;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-2292908426056575133?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/2292908426056575133/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=2292908426056575133" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/2292908426056575133?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/2292908426056575133?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/RP7JM80QqRg/mocking-system-classes.html" title="Mocking System Classes" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2009/10/mocking-system-classes.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MFQHo6fSp7ImA9WxNVEk0.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-7702488286780772368</id><published>2009-10-22T10:56:00.002+01:00</published><updated>2009-10-22T10:56:51.415+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-22T10:56:51.415+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rant" /><category scheme="http://www.blogger.com/atom/ns#" term="pmd" /><category scheme="http://www.blogger.com/atom/ns#" term="documentation" /><category scheme="http://www.blogger.com/atom/ns#" term="stack overflow" /><title>*headbash*</title><content type="html">&lt;div style="text-align: justify;"&gt;I got sucked into the evil time vortex that is StackOverflow again and decided to have a go on a &lt;a href="http://www.facebook.com/note_redirect.php?note_id=160679863818&amp;amp;h=bea4567f6cba44677eb225039aca98d3&amp;amp;url=http%3A%2F%2Fstackoverflow.com%2Fquestions%2F1565366%2Fpmd-check-for-too-many-public-methods-but-exclude-constructors-and-getters-set%2F1601206" target="_blank" title="http://stackoverflow.com/questions/1565366/pmd-check-for-too-many-public-methods-but-exclude-constructors-and-getters-set/1601206"&gt;PMD question&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
My god people put some sodding docs up.&lt;br /&gt;
&lt;br /&gt;
I spend the last few hours digging about for any documentation that I could find on the tree structure and just could not find a damn thing. I had to spend my time scanning other peoples rules to attempt to work out what was going on.&lt;br /&gt;
&lt;br /&gt;
So please developers of open source projects think for a few seconds about the poor bastards that actually use your software and invest a little time into the very unsexy act of writing documentation.&lt;br /&gt;
Thanks.&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-7702488286780772368?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/7702488286780772368/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=7702488286780772368" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/7702488286780772368?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/7702488286780772368?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/On0qISDn_uc/headbash.html" title="*headbash*" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2009/10/headbash.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4FSHs-fip7ImA9WxNVEEg.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-8629888839148503095</id><published>2009-10-20T16:35:00.000+01:00</published><updated>2009-10-20T16:35:19.556+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-20T16:35:19.556+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="store procedures" /><category scheme="http://www.blogger.com/atom/ns#" term="from dot-plan" /><category scheme="http://www.blogger.com/atom/ns#" term="teh codez" /><category scheme="http://www.blogger.com/atom/ns#" term="magic-procedures" /><category scheme="http://www.blogger.com/atom/ns#" term="jdbc" /><category scheme="http://www.blogger.com/atom/ns#" term="oracle" /><title>My Nifty Idea</title><content type="html">I have had a cool idea floating at the back of my mind for a little while and today as I have work I really don't want to do I worked out how to make it work and have thrown together a prototype. So first some background. I find myself writing a fair amount of database code. A lot of this is simple wrappers around a oracle package. The JDBC gods demand a fair amount of boiler plate. Even without going all the way to a ORM tool like Hibernate I know APIs exist to reduce said boilerplate but I've always felt (rightly or not) that I'd still end up doing a fair bit of boilerplate code even so or they were tied to an API I don't already use (i.e. Spring JDBC is slightly tried to Spring). I know the proper answer is likely to bite the bullet and use Spring. But sod that, I want to roll my own. &lt;br /&gt;
Mmm. Sorry slipping into irrelevant babbling. What I want out of an API is to define an interface and have that magically fill in the blanks. So for example if I define:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public interface Queue {&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;code&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int &lt;/span&gt;&lt;/code&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;getCount&lt;/span&gt;&lt;/span&gt;&lt;code&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;();&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
then all I'd have to do would be add some annotations to tell &lt;i&gt;the Magic&lt;/i&gt; what I want and it would go ahead and make it happen. So today I created a prototype. &lt;br /&gt;
First the annotation:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;package playtest;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.lang.annotation.Retention;&lt;br /&gt;
import java.lang.annotation.RetentionPolicy;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Retention(RetentionPolicy.RUNTIME)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public @interface Execute {&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; String script();&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
You then annotate the method you want to be magical.&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;package playtest;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public interface Queue {&lt;br /&gt;
&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; @Execute(script="{? = call Queue.getCount}")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; Integer getCount();&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Next the magic. Note: I'm using a Guice provider to get hold of the database. I'm not 100% that is the right way to go as while I'm very likely to use Guice do I really want to tie the implementation down to Guice? This play test of an implementation can only return void or Integer. If I was to go forward with this I'd have to get it to be able to return all primitive types at least and ideally be able to marshal complex types. Likely via annotations in the complex types. Maybe what I really want is JPA.&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;package playtest;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.lang.reflect.InvocationHandler;&lt;br /&gt;
import java.lang.reflect.Method;&lt;br /&gt;
import java.sql.CallableStatement;&lt;br /&gt;
import java.sql.Connection;&lt;br /&gt;
import java.sql.SQLException;&lt;br /&gt;
import java.sql.Statement;&lt;br /&gt;
import java.sql.Types;&lt;br /&gt;
import java.util.logging.Level;&lt;br /&gt;
import java.util.logging.Logger;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import com.google.inject.Provider;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class QuickAndDirtySQLHandler implements InvocationHandler {&lt;br /&gt;
private final Logger log = Logger.getLogger(getClass().getName());&lt;br /&gt;
private final Provider&lt;connection&gt; connectionProvider;&lt;br /&gt;
&lt;br /&gt;
public QuickAndDirtySQLHandler(final Provider&lt;connection&gt; connectionProvider) {&lt;br /&gt;
this.connectionProvider = connectionProvider;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@Override&lt;br /&gt;
public Object invoke(Object proxy, Method method, Object[] args)&lt;br /&gt;
throws Throwable {&lt;br /&gt;
Execute execute = method.getAnnotation(Execute.class);&lt;br /&gt;
if (execute == null) {&lt;br /&gt;
throw new IllegalStateException("Required annotation missing!");&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
boolean returnsValue = false;&lt;br /&gt;
&lt;br /&gt;
if (method.getReturnType().equals(Integer.c&lt;wbr&gt;&lt;/wbr&gt;lass)) {&lt;br /&gt;
returnsValue = true;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Connection connection = connectionProvider.get();&lt;br /&gt;
CallableStatement statement = null;&lt;br /&gt;
&lt;br /&gt;
try {&lt;br /&gt;
statement = connection.prepareCall(execute.script())&lt;wbr&gt;&lt;/wbr&gt;;&lt;br /&gt;
if (returnsValue) {&lt;br /&gt;
statement.registerOutParameter(1, Types.INTEGER);&lt;br /&gt;
}&lt;br /&gt;
statement.execute();&lt;br /&gt;
&lt;br /&gt;
if (returnsValue) {&lt;br /&gt;
return statement.getInt(1);&lt;br /&gt;
} else {&lt;br /&gt;
return null;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
} finally {&lt;br /&gt;
&lt;br /&gt;
close(statement);&lt;br /&gt;
connection.close();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;/connection&gt;&lt;/connection&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; private void close(Statement s) {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;  if (s == null) {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;   return;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;  }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;  try {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;   s.close();&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;  } catch(SQLException sqle) {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;   log.log(Level.WARNING, "Failed to close statement", sqle);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;  }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
Next a helper class to handle database access.&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;package playtest.db;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.sql.Connection;&lt;br /&gt;
import java.sql.SQLException;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import org.apache.commons.dbcp.BasicDataSource;&lt;wbr&gt;&lt;/wbr&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import com.google.inject.Provider;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class ExampleDatabaseProvider implements Provider&lt;connection&gt;{&lt;/connection&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; private final BasicDataSource ds = new BasicDataSource();&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public ExampleDatabaseProvider(String driver, String username,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String password, String url) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ds.setDriverClassName(driver);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ds.setUsername(username);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ds.setPassword(password);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ds.setUrl(url);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ds.setMaxActive(1);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ds.setDefaultAutoCommit(false);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; @Override&lt;br /&gt;
&amp;nbsp; public Connection get() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; return ds.getConnection();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch(SQLException sqle) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // Switch to a throwing provider?&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new IllegalStateException(sqle);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public void close() throws SQLException {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;  ds.close();&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
And finally some magic:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;package playtest;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.lang.reflect.Proxy;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import playtest.db.ExampleDatabaseProvider;&lt;br /&gt;
&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class KickStart {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public static void main(String argv[]) throws Exception {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExampleDatabaseProvider dbProvider =&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new ExampleDatabaseProvider(&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "jdbc.driver",&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;"username", "password", "jdbc:database");&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;  &lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Queue example = (Queue)Proxy.newProxyInstance(&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; KickStart.class.g&lt;/span&gt;&lt;wbr style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/wbr&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;etClassLoader(), &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new Class[] {Queue.class}, &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new QuickAndDirtySQLHandler(dbProvider));&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;  &lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; System.out.println(example.getCount());&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;  &lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; dbProvider.close();&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
I think that would be much better than raw JDBC for projects that demand the use of stored procedures (like all projects at my current employer). I should really look at how JPA handles forced use of stored procedures.&lt;br /&gt;
&lt;br /&gt;
I think this is a cool idea and I plan to run with it (if I can find the time). I'll post updates here under the tag &lt;a href="http://ihaztehcodez.blogspot.com/search/label/magic-procedures"&gt;magic-procedures&lt;/a&gt;. The GitHub site is: &lt;a href="http://github.com/mlk/magic-procedures"&gt;http://github.com/mlk/magic-procedures&lt;/a&gt; and the public repository is &lt;a href="git+ssh://git@github.com:mlk/magic-procedures.git"&gt;git@github.com:mlk/magic-procedures.git&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-8629888839148503095?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/8629888839148503095/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=8629888839148503095" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/8629888839148503095?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/8629888839148503095?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/Dr3wGgg4uqA/my-nifty-idea.html" title="My Nifty Idea" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2009/10/my-nifty-idea.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUER3s5fyp7ImA9WxNaEUk.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-3734659028897145207</id><published>2009-10-20T15:23:00.001+01:00</published><updated>2009-11-25T11:23:26.527Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-25T11:23:26.527Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="git" /><category scheme="http://www.blogger.com/atom/ns#" term="teh codez" /><title>Code now on GitHub</title><content type="html">I need to play with &lt;a href="http://git-scm.com/"&gt;Git &lt;/a&gt;for a bit as I just don't understand what all the fuss is about. So I've thrown the code I've written for this blog on to &lt;a href="https://github.com/"&gt;GitHub&lt;/a&gt;. The public repository is:&lt;br /&gt;
&lt;a href="git://github.com/mlk/ihaztehcodez.git"&gt;git://github.com/mlk/ihaztehcodez.git&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-3734659028897145207?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/3734659028897145207/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=3734659028897145207" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/3734659028897145207?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/3734659028897145207?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/hhpUBtLw3qI/code-now-on-github.html" title="Code now on GitHub" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2009/10/code-now-on-github.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4CRXw5fip7ImA9WxNVGE4.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-4698954505658093963</id><published>2009-10-20T11:21:00.001+01:00</published><updated>2009-10-29T16:16:04.226Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-29T16:16:04.226Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="junit" /><title>JUnit 4.7 - TemporaryFolder</title><content type="html">&lt;a href="http://www.junit.org/node/574"&gt;JUnit 4.7&lt;/a&gt; adds a cool looking new feature - &lt;a href="http://github.com/KentBeck/junit/blob/master/src/main/java/org/junit/Rule.java"&gt;Rule&lt;/a&gt;s. These should get rid of the need to write a new &lt;a href="http://junit.org/junit/javadoc/4.5/org/junit/runner/Runner.html"&gt;Runner &lt;/a&gt;every time you want something nifty to happen. &lt;br /&gt;
One of the rules is &lt;a href="http://github.com/KentBeck/junit/blob/master/src/main/java/org/junit/rules/TemporaryFolder.java"&gt;TemporaryFolder&lt;/a&gt;. This automatically creates and destroys a temporary folder at the start and end of a test. A neat extra and something I'd already &lt;a href="http://github.com/mlk/ihaztehcodez/blob/master/src/ihaztehcodez/testing/io/SimpleTestFileUtils.java"&gt;thrown together for my own use&lt;/a&gt;. However my version did one thing different - it destroyed on start up not shut down. Why? The same reason my &lt;a href="http://www.dbunit.org/bestpractices.html#nocleanup"&gt;database tests do this&lt;/a&gt;. When testing I can quickly go back to any test and check the files it created and attempt to work out why a test is failing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-4698954505658093963?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/4698954505658093963/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=4698954505658093963" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/4698954505658093963?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/4698954505658093963?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/7cr23_XkhD0/junit-47-temporaryfolder.html" title="JUnit 4.7 - TemporaryFolder" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2009/10/junit-47-temporaryfolder.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8GQHkzcSp7ImA9WxNVEE4.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-7166240708590294639</id><published>2009-10-20T10:56:00.002+01:00</published><updated>2009-10-20T11:17:01.789+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-20T11:17:01.789+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mutator" /><category scheme="http://www.blogger.com/atom/ns#" term="easymock" /><category scheme="http://www.blogger.com/atom/ns#" term="stack overflow" /><category scheme="http://www.blogger.com/atom/ns#" term="get/set" /><category scheme="http://www.blogger.com/atom/ns#" term="teh codez" /><title>Mocking a Get/Set Pair using EasyMock</title><content type="html">Once again I'm going to tart up a post of &lt;a href="http://stackoverflow.com/questions/1587193/mocking-inter-method-dependencies/1587681#1587681"&gt;SO &lt;/a&gt;and throw it on here: &lt;br /&gt;
&lt;br /&gt;
Say you have an interface with a get/set pair that get populated and retrieved. And you need these to match.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="color: black;"&gt;public interface &lt;/span&gt;GetSetId {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public int getID();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setID(int id);&lt;br /&gt;
&amp;nbsp; &amp;nbsp; public void somethingThatMakesThisNotAValueObject();&lt;br /&gt;
&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
When it comes to testing items that depend on this you need to either - be able to know the get/set values in advance or write a little wrapper to remember the get/sets. In order to simplify this I humbly present:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class GetSetAnswers&amp;lt;T&amp;gt; {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private T value;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IAnswer&amp;lt;Object&amp;gt; set() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return new IAnswer&amp;lt;Object&amp;gt;() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; @Override&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; public Object answer() throws Throwable {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Object[] arguments = getCurrentArguments();&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; value = (T) arguments[0];&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return null;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IAnswer&amp;lt;T&amp;gt; get() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return new IAnswer&amp;lt;T&amp;gt;() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; @Override&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; public T answer() throws Throwable {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return value;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;You can then use it thusly:&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class TestGetSet {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Test&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void testSetGet() {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GetSetAnswers&amp;lt;Integer&amp;gt; value = new GetSetAnswers&amp;lt;Integer&amp;gt;();&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GetSetId id = createMock(GetSetId.class);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; id.setID(anyInt());&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; expectLastCall().andAnswer(value.set());&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; expect(id.getID()).andAnswer(value.get());&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; replay(id);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int generatedValue = (int) (Math.random() * 100.0); &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; id.setID(generatedValue);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.assertEquals(generatedValue, id.getID());&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; verify(id);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-7166240708590294639?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/7166240708590294639/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=7166240708590294639" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/7166240708590294639?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/7166240708590294639?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/sGVyn78FW6g/mocking-getset-pair-using-easymock.html" title="Mocking a Get/Set Pair using EasyMock" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2009/10/mocking-getset-pair-using-easymock.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4DRns8eSp7ImA9WxNXFE0.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-3056383501447830388</id><published>2009-10-01T15:39:00.000+01:00</published><updated>2009-10-01T15:39:37.571+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-01T15:39:37.571+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="integration tests" /><category scheme="http://www.blogger.com/atom/ns#" term="unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="not as long as I wanted" /><category scheme="http://www.blogger.com/atom/ns#" term="stack overflow" /><title>Integration vs Unit test for the database layer</title><content type="html">A commonly posted question on &lt;a href="http://stackoverflow.com/"&gt;Stack Overflow &lt;/a&gt;is how to unit testing the database layer. Any question about this generally ends up with two diverse answers. The first is that all database activities should be mocked and tested during integration testing, the second is that a real database should be used.&lt;br /&gt;
&lt;br /&gt;
I feel that testing against a database is important and should be done frequently. As it needs to be done frequently it should be quick to set up and execute.&amp;nbsp;Now setting up a database may sound like work, but if all developers have access to a &lt;a href="http://dbunit.wikidot.com/onedatabaseperdeveloper"&gt;dedicated database&lt;/a&gt; that sits either on the local machine or on a decent sized box in the background and the dataset are restricted to use what is reliant to the test then this take little time to connect to and set up.&lt;br /&gt;
&lt;br /&gt;
As I'm a lazy git I don't really want to be using different technologies for different sets of tests. Any test that wants to run frequently and is fast to run just becomes a &lt;a href="http://www.junit.org/"&gt;JUnit&lt;/a&gt; test.&lt;br /&gt;
&lt;br /&gt;
So finally when should I write it? Well I know before starting a second of code what the data should look like before and after the test runs. So I write the test first. Now I could set up a &lt;a href="http://en.wikipedia.org/wiki/Mock_object"&gt;mock&lt;/a&gt;ed &lt;a href="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html"&gt;Statement&lt;/a&gt;, &lt;a href="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html"&gt;ResultSet&lt;/a&gt; and all that fun stuff but really that is a lot more work than creating the XML files for &lt;a href="http://www.dbunit.org/"&gt;dbUni&lt;/a&gt;t and I'm going to have to set up all this data for integration tests. So why repeat myself.&lt;br /&gt;
&lt;br /&gt;
I think the name used is not as important as the doing. Still if I had to pick a side, it would be "unit test".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-3056383501447830388?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/3056383501447830388/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=3056383501447830388" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/3056383501447830388?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/3056383501447830388?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/KWJGhabUCIk/integration-vs-unit-test-for-database.html" title="Integration vs Unit test for the database layer" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2009/10/integration-vs-unit-test-for-database.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8HQ3c9cCp7ImA9WxNQGEU.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-4929893245840081199</id><published>2009-09-22T09:33:00.001+01:00</published><updated>2009-09-25T15:27:12.968+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-25T15:27:12.968+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="deployment" /><category scheme="http://www.blogger.com/atom/ns#" term="mini-article" /><title>Options for deploying desktop software in Java</title><content type="html">Like my yesterday I'm going to copy &amp;amp; paste an answer from &lt;a href="http://stackoverflow.com/questions/1453369/i-have-never-seen-a-software-be-released-as-jar-so-how-can-i-make-a-software-be/1453477#1453477"&gt;Stack Overflow&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="post-text"&gt;Java software can be release in a number of ways depending on the target market.&lt;br /&gt;
&lt;br /&gt;
The simplest for the developer (but hardest for the end user) is to &lt;b&gt;just release a jar file&lt;/b&gt; (or set of Jar files). On many systems the JAR will be "double-click-able", and so act as an executable. But if the end user does not have Java installed it will not work.&lt;br /&gt;
&lt;i&gt;Good&lt;/i&gt; if you control the target environment. Also good if you want to target Windows, Mac and Linux all at once. Any platform with Java can run it, including platforms you had not considered.&lt;br /&gt;
&lt;i&gt;Bad&lt;/i&gt; if you are targeting normal users. It can not do "install tasks", set up anything in the start menu or associate itself with a file type.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Java Web Start&lt;/b&gt; is my preference in most cases. It gives a Java based installer and can set up the start menu, associate file types and all that goodness. But does bring up a security box on install. &lt;br /&gt;
&lt;i&gt;Good&lt;/i&gt; for most cases. You have just the one link for all OSes.&lt;br /&gt;
&lt;i&gt;Bad&lt;/i&gt; if you suspect the user does not have a JRE installed or you don't want the end user to be aware that the application is written in Java.&lt;br /&gt;
&lt;br /&gt;
You could release a zip file with the Jars in and a &lt;b&gt;.bat file and a .sh&lt;/b&gt; file to get the going. &lt;br /&gt;
&lt;i&gt;Good&lt;/i&gt; for administrators, developers and command line applications. &lt;br /&gt;
&lt;i&gt;Bad&lt;/i&gt; for end users who don't really know what a bat and shell script are and would have no idea what to do if the script was broken for their system.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;A thin .exe wrapper&lt;/b&gt; round the Jar file. This gives the impression to the end user that the application is native. They normally come with...&lt;br /&gt;
&lt;br /&gt;
A &lt;b&gt;Java aware installer&lt;/b&gt;. This is a native installer (so different installers for Windows, Mac &amp;amp; Linux). This will be able to detect if the target machine has Java installed and if not be able to kick off the installation of the JRE. It will also be able to do all the fun post-install stuff such as setting file associations and add items to the start menu.&lt;br /&gt;
&lt;i&gt;Good&lt;/i&gt; for most cases.&lt;br /&gt;
&lt;i&gt;Bad&lt;/i&gt; if you are targeting multiply platforms as you will need to maintain an installer for each platform. Also bad if one of the target platforms does not have a Java aware installer (you will then need to use of of the other methods above for that one platform).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Native EXE&lt;/b&gt;. Using a Java-to-native compiler (Jet or GCJ) you create a native executable. &lt;br /&gt;
&lt;i&gt;Good&lt;/i&gt; if you really don't want people to know you are using Java.&lt;br /&gt;
&lt;i&gt;Bad&lt;/i&gt; as people think that this will magically make the application faster when it will not.&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-4929893245840081199?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/4929893245840081199/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=4929893245840081199" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/4929893245840081199?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/4929893245840081199?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/-xWz7i3PtYE/4-deployararting-sftwrs.html" title="Options for deploying desktop software in Java" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2009/09/4-deployararting-sftwrs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkADSHs6cCp7ImA9WxNQGEU.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-7798987220762585988</id><published>2009-09-21T17:26:00.003+01:00</published><updated>2009-09-25T15:26:19.518+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-25T15:26:19.518+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="junit" /><category scheme="http://www.blogger.com/atom/ns#" term="teh codez" /><title>Randomly Ordered JUnit Tests</title><content type="html">&lt;div class="caption"&gt;Could not be arsed to work for a bit, so got sucked into &lt;a href="http://stackoverflow.com/questions/1444314/how-can-i-make-my-junit-tests-run-in-random-order"&gt;Stack Overview &lt;/a&gt;for a bit.         &lt;br /&gt;
&lt;/div&gt;Never a good thing. Anyway one question was about how to run JUnit tests in a random order. So I sat down and looked over the APIs and gave it a bash:&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.util.Collections;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import java.util.List;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import org.junit.runners.BlockJUnit4ClassRunner;&lt;wbr&gt;&lt;/wbr&gt;&lt;br /&gt;
import org.junit.runners.model.FrameworkMethod;&lt;wbr&gt;&lt;/wbr&gt;&lt;br /&gt;
import org.junit.runners.model.InitializationEr&lt;wbr&gt;&lt;/wbr&gt;ror;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/** Runs JUnit tests in a random order.&lt;br /&gt;
* &lt;br /&gt;
* @author mlk&lt;br /&gt;
*&lt;br /&gt;
*/&lt;br /&gt;
public class RandomBlockJUnit4ClassRunner extends BlockJUnit4ClassRunner {&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; public RandomBlockJUnit4ClassRunner(Class klass)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throws InitializationError {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; super(klass);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; /** {@inheritDoc} */&lt;br /&gt;
&amp;nbsp;&amp;nbsp; protected java.util.List&lt;frameworkmethod&gt; computeTestMethods() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&lt;frameworkmethod&gt; methods = super.computeTestMethods();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Collections.shuffle(methods);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return methods;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; }&lt;/frameworkmethod&gt;&lt;/frameworkmethod&gt;&lt;br /&gt;
&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Annotate any class you want the unit tests to run in a random order with "&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@RunWith(RandomBlockJUnit4ClassRunner.c&lt;/span&gt;&lt;wbr style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/wbr&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;lass)&lt;/span&gt;" and hey presto randomly ordered unit tests. (Note: This required JUnit 4.5 or above).&lt;br /&gt;
Now JUnit does have a Sortable interface, but I've no idea how to actually ruddy use it. :'(&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-7798987220762585988?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/7798987220762585988/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=7798987220762585988" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/7798987220762585988?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/7798987220762585988?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/weu0rof_2QU/4-teh-random-junits.html" title="Randomly Ordered JUnit Tests" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2009/09/4-teh-random-junits.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAAQHgyeip7ImA9WxNQGEU.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-4605217820995654140</id><published>2008-08-03T23:00:00.002+01:00</published><updated>2009-09-25T15:25:41.692+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-25T15:25:41.692+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="development" /><category scheme="http://www.blogger.com/atom/ns#" term="mini-article" /><title>How to become a developer</title><content type="html">Every now and again I see a request on the JDC for teh magick knowledge that will turn a person from random guy to developer. So for the second time today I'd like to vomit my wisdom all over the internets.&lt;br /&gt;
&lt;br /&gt;
First learn how to use the command line. Ideally both Unix (Cygwin if you don't have access to Unix-a-like) and Windows Command Processor. I'm not saying you should have mad hacker skillz, just be able to navigate the directory structure, set (and check) environment variables, start new applications and maybe some basic control structures (if statements and loops).&lt;br /&gt;
While you improve your development skills, try to also update you knowledge of the command line. Commands like grep, tail, awk, cut and paste have simplified many an awkward job.&lt;br /&gt;
&lt;br /&gt;
I don't think I need to tell you to learn the basics of your chosen language, but I've just been bitten for assuming people don't need to be told the obvious so I'll state it here. Learn the basics of your chosen language.&lt;br /&gt;
That done, the people at &lt;a href="http://www.pragprog.com/"&gt;The Pragmatic Bookshelf&lt;/a&gt; have asked themselves the same question I'm now answering, and came up with the following three books - &lt;a href="http://www.pragprog.com/titles/svn2/pragmatic-version-control-using-subversion"&gt;Pragmatic Version Control&lt;/a&gt;, &lt;a href="http://www.pragprog.com/titles/utj/pragmatic-unit-testing-in-java-with-junit"&gt;Pragmatic Unit Testing&lt;/a&gt; and &lt;a href="http://www.pragprog.com/titles/auto/pragmatic-project-automation"&gt;Pragmatic Automation&lt;/a&gt;. I agree completely with the subjects they have selected. Get yourself a book, or some online tutorials on all three subjects.&lt;br /&gt;
Now what you need most is experience. Knowing cool shit like &lt;a href="http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612"&gt;patterns&lt;/a&gt; will help in the long run, but without the experience to place them in context they will be of limited use. So go out and play. Think of a project and do it so you can learn from your cock ups.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-4605217820995654140?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/4605217820995654140/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=4605217820995654140" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/4605217820995654140?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/4605217820995654140?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/kB8mNCBtebk/4-becomingz-dev.html" title="How to become a developer" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2008/08/4-becomingz-dev.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEDSX87cSp7ImA9WxNQGEU.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-7067287831546041696</id><published>2008-08-03T13:17:00.004+01:00</published><updated>2009-09-25T15:24:38.109+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-25T15:24:38.109+01:00</app:edited><title>Defensive Coding</title><content type="html">Google Testing recently recommended against &lt;a href="http://googletesting.blogspot.com/2008/07/how-to-write-3v1l-untestable-code.html"&gt;being defensive&lt;/a&gt;. The rationale behind this was that testers found it easier to simply pass a null when testing than passing in a constructed object. I disagree with this. Creating a null object either with an existing mock object framework or by using the &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/reflect/Proxy.html"&gt;proxy capabilities&lt;/a&gt; in Java makes passing a null object no harder than passing null.&lt;br /&gt;
Now some codez:&lt;br /&gt;
&lt;span style="color: black;"&gt;&lt;span style="font-family: courier new;"&gt;package ihaztehcodez.nullobject;&lt;br /&gt;
&lt;br /&gt;
import java.lang.reflect.InvocationHandler;&lt;br /&gt;
import java.lang.reflect.Method;&lt;br /&gt;
import static&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new;"&gt; java.lang.reflect.Proxy.newProxyInstance;&lt;br /&gt;
&lt;br /&gt;
/** Provides a simple alternative to passing null.&lt;br /&gt;
&amp;nbsp;* @author &lt;a href="http://ihaztehcodez.blogspot.com/"&gt;Mike Lee&lt;/a&gt;&lt;br /&gt;
&amp;nbsp;*/&lt;br /&gt;
public class NullObjectFactory {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; /** Utility class, should never be created. */&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; private NullObjectFactory() { }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; public static &lt;t&gt; T createNullObject(Class&lt;t&gt;&amp;lt;T&amp;gt; clazz) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return (T) newProxyInstance(ClassLoader.getSystemClassLoader(),&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; new Class [] { clazz }, new SadInvocationHandler() );&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class SadInvocationHandler implements InvocationHandler {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; public&amp;nbsp; Object &amp;nbsp;&amp;nbsp; invoke(Object proxy, Method method, Object[] args) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; throw new IllegalStateException("Proxy does not support method calls.");&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
package ihaztehcodez.fourtehnalzobj;&lt;br /&gt;
&lt;br /&gt;
import static ihaztehcodez.fourtehnalzobj.NullObjectFactory.createNullObject;&lt;br /&gt;
&lt;br /&gt;
public class NullObjectFactoryExample {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; public void testThingie() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Thingie thingie = new Thingie(createNullObject(Whatsit.class));&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class Thingie {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; Thingie(Whatsit whatsit) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
interface Whatsit {&lt;br /&gt;
}&lt;/t&gt;&lt;/t&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-7067287831546041696?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/7067287831546041696/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=7067287831546041696" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/7067287831546041696?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/7067287831546041696?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/se9nfXM0iKU/4-teh-nalz-obj.html" title="Defensive Coding" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2008/08/4-teh-nalz-obj.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEFQXcycCp7ImA9WxNQGEU.&quot;"><id>tag:blogger.com,1999:blog-1319685701804027745.post-7684032522369095840</id><published>2008-08-02T22:06:00.003+01:00</published><updated>2009-09-25T15:23:30.998+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-25T15:23:30.998+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="word" /><category scheme="http://www.blogger.com/atom/ns#" term="freemarker" /><category scheme="http://www.blogger.com/atom/ns#" term="apache fop" /><category scheme="http://www.blogger.com/atom/ns#" term="rtf" /><title>Generating Word Documents In Java</title><content type="html">&lt;div&gt;&lt;span style="font-weight: bold;"&gt;UPDATE&lt;/span&gt;: I think need to depricated this post. Go with FOP.&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;Very now and again I see this on the JDC, and as I have recently needed to do this I thought it would be good to write down how to do this.&lt;br /&gt;
&lt;br /&gt;
Are you creating word documents or editing existing Word documents? If the latter then &lt;a href="http://schmidt.devlib.org/java/libraries-word.html"&gt;here you go&lt;/a&gt;. Good luck.&lt;br /&gt;
&lt;br /&gt;
If you need to create a new Word document then first it might be worth using RTF. Word 97 used RTF instead of Words native format so don't worry; no-one will ever know our dirty little secret. The advantage of using RTF is it is a text file not a scary binary file and the &lt;a href="http://msdn.microsoft.com/en-us/library/aa140277.aspx"&gt;specification&lt;/a&gt; is a free download. Java also has some &lt;a href="http://java.sun.com/javase/6/docs/api/javax/swing/text/rtf/package-summary.html"&gt;primitive support&lt;/a&gt; for RTFs.&lt;br /&gt;
&lt;br /&gt;
I am going to guess that you don't simply wish to create a free-form word document but rather you will be applying a model to a simple template?&lt;br /&gt;
&lt;br /&gt;
For those who do not know what that means:&lt;br /&gt;
&lt;br /&gt;
Lets give this a little context, we want to send a bill out, so we some key details about our customer, and the order.&lt;br /&gt;
&lt;code&gt;customer_name=Bob MacBobby&lt;br /&gt;
items=(&lt;br /&gt;
&amp;nbsp;        (name="blow up sheep", cost=12.5),&lt;br /&gt;
&amp;nbsp;        (name="Fun with Goats, the motion picture", cost=9.99&lt;br /&gt;
&amp;nbsp;       )&lt;br /&gt;
total_untaxed= 22.49&lt;br /&gt;
vat= 3.94&lt;br /&gt;
total= 26.43&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
And we want:&lt;br /&gt;
&lt;br /&gt;
Dear &lt;b&gt;Bob MacBobby&lt;/b&gt;,&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Item&lt;/b&gt;: blow up sheep&lt;br /&gt;
Cost: 12.5&lt;br /&gt;
&lt;b&gt;Item&lt;/b&gt;: Fun with Goats, the motion picture&lt;br /&gt;
Cost: 9.99&lt;br /&gt;
&lt;br /&gt;
Total (without tax): 22.49&lt;br /&gt;
VAT: 3.94&lt;br /&gt;
Total:  26.46&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Doing this is very easy. First we need to go get a templating engine. I've used &lt;a href="http://freemarker.org/"&gt;Freemarker&lt;/a&gt; before and it works nicely.&lt;br /&gt;
&lt;br /&gt;
The only issue with this is that creating a RTF template can be a bit of a bitch, the way to do it is to create the RTF document looks how you want it to look in say Word. Where you need a variable don't use ${blah} that Freemarker requires but use an all uppercase word. This is because RTF uses { }.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://img359.imageshack.us/my.php?image=sourcebillyo5.png" target="_blank"&gt;&lt;img alt="Word Document RTF" border="0" src="http://img359.imageshack.us/img359/16/sourcebillyo5.th.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Now we need to edit it so it is a valid freemarker template. Open the document in a plain text editor. Find the INSERT_XXX_HERE and replace them with the Freemarker syntax: ${xxx?rtf}. Take note of the ?rtf.&lt;br /&gt;
Finally we need the loop. Simply add &amp;lt;#list …&amp;gt; to the line above the items you want to loop over, and  to the line below. The template file is alas not a valid RTF document, but running Freemarker over it will create a nice valid RTF document.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: courier new;"&gt;{\rtf1\ansi\ansicpg1252\uc1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang2057\deflangfe2057{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f36\froman\fcharset238\fprq2 Times New Roman CE;}&lt;br /&gt;
{\f37\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f39\froman\fcharset161\fprq2 Times New Roman Greek;}{\f40\froman\fcharset162\fprq2 Times New Roman Tur;}{\f41\froman\fcharset177\fprq2 Times New Roman (Hebrew);}&lt;br /&gt;
{\f42\froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f43\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f44\froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;&lt;br /&gt;
\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;&lt;br /&gt;
\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang2057\langfe2057\cgrid\langnp2057\langfenp2057 \snext0 Normal;}{\*\cs10 \additive \ssemihidden&lt;br /&gt;
Default Paragraph Font;}{\*\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv&lt;br /&gt;
\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}}{\*\latentstyles\lsdstimax156\lsdlockeddef0}{\*\rsidtbl \rsid14418598\rsid15407471&lt;br /&gt;
\rsid16010694}{\*\generator Microsoft Word 11.0.5604;}{\info{\title Dear INSERT_NAME_HERE}{\author Michael Lee}{\operator Michael Lee}{\creatim\yr2008\mo8\dy2\hr21\min49}{\revtim\yr2008\mo8\dy2\hr21\min55}{\version1}{\edmins3}{\nofpages1}{\nofwords30}&lt;br /&gt;
{\nofchars177}{\*\company Your Company Name}{\nofcharsws206}{\vern24689}}\paperw11906\paperh16838 \widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1701&lt;br /&gt;
\dgvorigin1984\dghshow1\dgvshow1\jexpand\viewkind4\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct&lt;br /&gt;
\asianbrkrule\rsidroot14418598\newtblstyruls\nogrowautofit \fet0\sectd \linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2&lt;br /&gt;
\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6&lt;br /&gt;
\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang&lt;br /&gt;
{\pntxtb (}{\pntxta )}}\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang2057\langfe2057\cgrid\langnp2057\langfenp2057 {\insrsid14418598 Dear }{\b\insrsid14418598\charrsid14418598 &lt;b&gt;&lt;span style="color: #006600;"&gt;${customer_name}&lt;/span&gt;&lt;/b&gt;}{&lt;br /&gt;
\insrsid16010694&lt;br /&gt;
\par }{\insrsid14418598&lt;br /&gt;
\par Thank you for your order. Now pay up.&lt;br /&gt;
\par&lt;br /&gt;
&lt;b&gt;&lt;span style="color: #006600;"&gt;&amp;lt;#list items as item&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
\par }{\b\insrsid14418598\charrsid14418598 Item}{\insrsid14418598 : &lt;/span&gt;&lt;span style="font-family: courier new;"&gt;&lt;b&gt;&lt;span style="color: #006600;"&gt;${item.name?rtf}&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;&lt;br /&gt;
\par Cost: &lt;span style="color: #006600;"&gt;&lt;b&gt;${item.cost}&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #006600;"&gt;&amp;lt;/#list&amp;gt;&lt;/span&gt;&lt;br /&gt;
\par&lt;br /&gt;
\par Total (without tax): &lt;b&gt;&lt;span style="color: #006600;"&gt;${total_untaxed}&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
\par VAT: &lt;b&gt;&lt;span style="color: #006600;"&gt;${vat}&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
\par Total:&lt;span style="color: #006600;"&gt;&lt;b&gt; ${total}&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
\par }}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This alas is not perfect. While static images are simple enough, just add them into the template file, I have no idea how to do dynamic images. Which is why I'm now looking into &lt;a href="http://xmlgraphics.apache.org/fop/"&gt;Apache FOP.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1319685701804027745-7684032522369095840?l=ihaztehcodez.michael-lloyd-lee.me.uk' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ihaztehcodez.michael-lloyd-lee.me.uk/feeds/7684032522369095840/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1319685701804027745&amp;postID=7684032522369095840" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/7684032522369095840?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1319685701804027745/posts/default/7684032522369095840?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IHazTehCodez/~3/92UjbBk9HK4/4-teh-word-documents.html" title="Generating Word Documents In Java" /><author><name>Mike Lee</name><uri>http://www.blogger.com/profile/04267783111219770327</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15507923349262487525" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://ihaztehcodez.michael-lloyd-lee.me.uk/2008/08/4-teh-word-documents.html</feedburner:origLink></entry></feed>
