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

<channel>
	<title>Frank Carver&#039;s Punch Barrel &#187; stringtree</title>
	<atom:link href="http://blog.punchbarrel.com/tag/stringtree/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.punchbarrel.com</link>
	<description>Frank Carver&#039;s musings about software and life</description>
	<lastBuildDate>Tue, 07 Sep 2010 11:27:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
	<!-- podcast_generator="podPress/8.8" - maintenance_release="8.8.6.3" -->
	<copyright>2008 </copyright>
	<managingEditor>frank.carver@googlemail.com (Frank Carver)</managingEditor>
	<webMaster>frank.carver@googlemail.com (Frank Carver)</webMaster>
	<category>posts</category>
	<ttl>1440</ttl>
	<image>
		<url>http://punchbarrel.com/images/punchbarrel-144.jpg</url>
		<title>Frank Carver&#039;s Punch Barrel &#187; stringtree</title>
		<link>http://blog.punchbarrel.com</link>
		<width>144</width>
		<height>144</height>
	</image>
	<itunes:subtitle>Frank Carver spends too much time reading the web</itunes:subtitle>
	<itunes:summary>Frank Carver spends too much time reading the web</itunes:summary>
	<itunes:keywords></itunes:keywords>
	<itunes:category text="Technology" />
	<itunes:author>Frank Carver</itunes:author>
	<itunes:owner>
		<itunes:name>Frank Carver</itunes:name>
		<itunes:email>frank.carver@googlemail.com</itunes:email>
	</itunes:owner>
	<itunes:block>no</itunes:block>
	<itunes:explicit>no</itunes:explicit>
	<itunes:image href="http://punchbarrel.com/images/punchbarrel-300.jpg" />
		<item>
		<title>Ruby, Sinatra, Dreamhost, Haml, git &#8211; a smooth web app workflow &#8230; eventually</title>
		<link>http://blog.punchbarrel.com/2009/10/21/ruby-sinatra-dreamhost-haml-git-a-smooth-web-app-workflow-eventually/</link>
		<comments>http://blog.punchbarrel.com/2009/10/21/ruby-sinatra-dreamhost-haml-git-a-smooth-web-app-workflow-eventually/#comments</comments>
		<pubDate>Wed, 21 Oct 2009 15:51:08 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[Information]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[bugs]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[distributed]]></category>
		<category><![CDATA[dreamhost]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[gui]]></category>
		<category><![CDATA[haml]]></category>
		<category><![CDATA[issues]]></category>
		<category><![CDATA[mojasef]]></category>
		<category><![CDATA[planning]]></category>
		<category><![CDATA[sinatra]]></category>
		<category><![CDATA[stringtree]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[tasks]]></category>
		<category><![CDATA[teams]]></category>
		<category><![CDATA[tracking]]></category>
		<category><![CDATA[unfuddle]]></category>
		<category><![CDATA[version control]]></category>

		<guid isPermaLink="false">http://blog.punchbarrel.com/?p=1409</guid>
		<description><![CDATA[I have spent many years developing web applications in Java for corporate clients. During that time I have used a wide range of frameworks, APIs and other useful stuff. I have written my own versions (sometimes several) of many of these components, learned the tools well, and become very productive and effective. However, it has [...]]]></description>
			<content:encoded><![CDATA[<p>I have spent many years developing web applications in Java for corporate clients. During that time I have used a wide range of frameworks, APIs and other useful stuff. I have written my own versions (sometimes several) of many of these components, learned the tools well, and become very productive and effective.</p>
<p>However, it has been almost impossible to take that expertise, hard work, and custom code and easily/cheaply turn it into usable web applications for general public use. Low-cost hosting providers have generally shunned Java support. The most reasonable one I have found is <a href="http://www.lunarpages.com/?id=efficacy/">LunarPages</a> who actually support both ad-hoc JSP and deployment of custom web applications as war files, even though you have to search pretty deep in their web site to find out, and pay an extra dollar or two a month for the privilege.</p>
<p>So for my own projects I have been looking for an alternative for a long time. A way of developing and testing web apps on my various development boxes (currently running Ubuntu, MacOS X and Windows XP) and easily deploying to a low-cost hosting provider.</p>
<p>By far the most popular web development language is PHP. It&#8217;s available pretty much everywhere. It&#8217;s so focussed on web app development that the primary unit of coding is the web page. Believe me, I have <em>tried</em> to like PHP, but it&#8217;s just so clumsy. After a few paces the application begins to get tangled, development speed drops, and bugs creep in. Its web focus makes it tricky to unit test, and end-to-end testing seems to require a full-fat HTTP server. Not for me.</p>
<p>Beyond the traditional stomping ground of PHP, perl, and other CGI fodder is the new range of &#8220;trendy&#8221; languages. Ruby, Python, Erlang and even the venerable smalltalk are trying to position themselves as the thinking-person&#8217;s web development tool.</p>
<p>Erlang syntax is a bit too odd for me right now, although I may come back to it later. Smalltalk is interesting, but carries with it so much history and is hardly a popular choice for low-cost hosting providers. That leaves a short-list of Python and Ruby.</p>
<p>As languages I like both Python and Ruby. They have broadly similar design goals, both have keen developer communities with plenty of open source resources, and both are commonly found on linux-based web hosts. In order to decide between them I took a look around their frameworks and APIs.</p>
<p>Python has Google on its side. It&#8217;s the &#8220;native language&#8221; of the hugely-scalable Google AppEngine. However, a scan around the web looking for ways of writing web applications led largely to two: Zope and Django. (for balance, there are <a href="http://wiki.python.org/moin/WebFrameworks">plenty of others</a>, but these are the standout examples). Zope is old and sprawling. It has some great ideas but is hardly an obvious choice for small, tactical web apps. Django is a bit lighter, but still seems to assume a lot and require a lot of relatively fiddly config.</p>
<p>In the Ruby world the blindingly obvious choice for a web application framework is Rails. Sometimes it seems as if &#8220;Ruby&#8221; is just another way of saying &#8220;Rails&#8221;. However Rails, like Django, assumes a lot about the eventual application. Rails also makes a lot of use of code generation, which I simply do not like. I would always prefer that a framework <em>eliminate</em> boilerplate rather than just generate it for me. Looking a little further beyond Rails I came across <a href="http://accidentaltechnologist.com/ruby/10-alternative-ruby-web-frameworks/">some really interesting alternatives</a>, and the one which really sparked my interest is <a href="http://www.sinatrarb.com/">Sinatra</a>. For me this one framework made the difference. It&#8217;s <em>so</em> streamlined that a basic web app is as simple as:</p>
<blockquote><p>
require &#8216;sinatra&#8217;<br />
get &#8216;/&#8217; do<br />
  &#8216;Hello world!&#8217;<br />
end
</p></blockquote>
<p>Best of all, simply running the above file using <code>ruby hello.rb</code> starts up a web server and begins serving pages on port 4567. No extra config or faffing.</p>
<p>Looking around for low cost hosting I found that the provider I already use (<a href="http://www.dreamhost.com/r.cgi?60867">Dreamhost</a>) supports Ruby web hosting using <a href="http://www.modrails.com/">Passenger</a>. An ssh to the Dreamhost server for &#8220;gem install sinatra&#8221; followed by a little bit of FTP and my first Ruby/Sinatra application was live!</p>
<p>A key part of any web application is the pages, and a key part of generating pages is a good template language. As a general-purpose templating language, I still prefer my own Stringtree Templater, part of the <a href="http://mojasef.stringtree.org/">Mojasef</a> Java framework. So far I have not found a similar templating solution for any other language. However, for the limited and specific requirement of generating web pages, I am becoming quite fond of <a href="http://haml-lang.com/">Haml</a>. It&#8217;s not at all a general templating solution, but it does massively simplify the generation of web pages.</p>
<p>Finally, after years of CVS and Subversion, I have made the jump to distributed version control. Not only is it more trendy, but the ability to work on multiple code branches, on multiple machines, with or without an internet connection, and easily share, identify and merge when necessary has been a key benefit.  Occasionally I wonder if one of the other distributed VCS (Mercurial, Bazaar, darcs, etc.) would have been a better choice, but I needed to settle on one and get to grips with it. So I chose <a href="http://git-scm.com/">git</a>.</p>
<p>There have been a few speed-bumps. Attempting to learn git from manual entries and simplistic tutorials gives very little help on deciding what is worth doing. After about a week of following the techniques in <a href="http://reinh.com/blog/2009/03/02/a-git-workflow-for-agile-teams.html">A Git Workflow for Agile Teams</a>, though, I began to get comfortable. Add to that some lovely web deployment tricks from <a href="http://joemaller.com/2008/11/25/a-web-focused-git-workflow/">A web-focused Git workflow</a> and a selection of GUI tools ( <a href="http://cola.tuxfamily.org/">Git Cola</a>, <a href="http://gitx.frim.nl/">GitX</a>, and <a href="http://pillowfactory.org/2008/09/11/git-awareness-week-git-gui/">Git GUI</a> ) to get round all that tedious &#8220;git add&#8221; stuff and simplify infrequent operations, and git becomes a very useful and productive tool.</p>
<p>The upshot is that I currently feel very productive. </p>
<p>My toolbox has a few other things in it, but they are still candidates for change if I find anything better. I am managing my projects and git repositories using <a href="http://unfuddle.com/">Unfuddle</a> but it has a few shortcomings including a ticket system which is a pale and clumsy cousin of bugzilla. For editing I use generic syntax-highlighting text editors (gedit on Linux, TextEdit on Windows and Smultron on Mac) but none of them have the nice autocompletion and refactoring tools I grew addicted to in Eclipse. Suggestions welcome!</p>
<p>Finally, a few spare links relating to the tools mentioned above.</p>
<p><a href="http://www.rubyinside.com/sinatra-29-links-and-resources-for-a-quicker-easier-way-to-build-webapps-1371.html">Sinatra: 29 Links and Resources For A Quicker, Easier Way to Build Webapps</a></p>
<p><a href="http://haml-lang.com/docs/yardoc/HAML_REFERENCE.md.html">HAML reference</a></p>
<p><a href="http://rack.rubyforge.org/">Rack</a></p>
<p><a href="http://www.hokstad.com/mini-reviews-of-19-ruby-template-engines.html">Mini reviews of 19 Ruby template engines</a></p>
<p><a href="http://www.infoq.com/news/2007/11/forgotten-ruby-web-frameworks">The Forgotten Ruby Web Frameworks</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.punchbarrel.com/2009/10/21/ruby-sinatra-dreamhost-haml-git-a-smooth-web-app-workflow-eventually/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Stringtree/Mojasef for Java 1.4 are now proper branches</title>
		<link>http://blog.punchbarrel.com/2009/05/15/stringtreemojasef-for-java-14-are-now-proper-branches/</link>
		<comments>http://blog.punchbarrel.com/2009/05/15/stringtreemojasef-for-java-14-are-now-proper-branches/#comments</comments>
		<pubDate>Fri, 15 May 2009 12:18:24 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[stringtree]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[java 1.4]]></category>
		<category><![CDATA[java 5]]></category>
		<category><![CDATA[mojasef]]></category>

		<guid isPermaLink="false">http://blog.punchbarrel.com/?p=1321</guid>
		<description><![CDATA[A few months ago I made the decision to move the Stringtree and Mojasef code-bases on from their requirement to support older Java versions. I tagged a particular version of the code as &#8220;1.4 final&#8221; and proceeded to work through the trunk code in the repository to bring it in line with key Java 5 [...]]]></description>
			<content:encoded><![CDATA[<p>A few months ago I made the decision to move the Stringtree and Mojasef code-bases on from their requirement to support older Java versions. I tagged a particular version of the code as &#8220;1.4 final&#8221; and proceeded to work through the trunk code in the repository to bring it in line with key Java 5 features such as generics, varargs and the enhanced for loop.</p>
<p>Since then I have progressively realized that I may have been a bit optimistic. A few odd bugs have been found in the 1.4 code, and a few key improvements have been made to the Java 5 code which by rights should also be implemented for 1.4. So I have decided to try and fix the situation.</p>
<p>As of today, the tag &#8220;1.4-final&#8221; in both Stringtree and Mojasef should be considered as deprecated, and any code which used to use that tagged version should instead use the branches (&#8220;Stringtree for Java 1.4&#8243; and &#8220;Mojasef for Java 1.4&#8243;) I have just created. Initially, the code is identical, but the plan is to go through and apply known bug fixes and fully-backward-compatible internal improvements to the branched versions.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.punchbarrel.com/2009/05/15/stringtreemojasef-for-java-14-are-now-proper-branches/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stephen Colebourne&#8217;s Null-default and Null-safe operators</title>
		<link>http://blog.punchbarrel.com/2009/01/10/stephen-colebournes-null-default-and-null-safe-operators/</link>
		<comments>http://blog.punchbarrel.com/2009/01/10/stephen-colebournes-null-default-and-null-safe-operators/#comments</comments>
		<pubDate>Sat, 10 Jan 2009 20:46:09 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[Information]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[null]]></category>
		<category><![CDATA[stringtree]]></category>
		<category><![CDATA[templater]]></category>

		<guid isPermaLink="false">http://blog.punchbarrel.com/?p=989</guid>
		<description><![CDATA[An interesting proposal to solve some of the common, and tedious, issues around Java nulls. Particularly comforting is that I have already separately implemented ?: with very similar semantics in my Stringtree template language. Stephen Colebourne&#8217;s Weblog]]></description>
			<content:encoded><![CDATA[<p>An interesting proposal to solve some of the common, and tedious, issues around Java nulls. Particularly comforting is that I have already separately implemented <strong>?:</strong> with very similar semantics in my Stringtree template language.</p>
<p><a href="http://www.jroller.com/scolebourne/entry/java_7_null_default_and">Stephen Colebourne&#8217;s Weblog</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.punchbarrel.com/2009/01/10/stephen-colebournes-null-default-and-null-safe-operators/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Test-Driven Development of HTTP and REST interfaces with Mojasef</title>
		<link>http://blog.punchbarrel.com/2009/01/07/test-driven-development-of-http-and-rest-interfaces-with-mojasef/</link>
		<comments>http://blog.punchbarrel.com/2009/01/07/test-driven-development-of-http-and-rest-interfaces-with-mojasef/#comments</comments>
		<pubDate>Wed, 07 Jan 2009 09:15:42 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[Information]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[mojasef]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[stringtree]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[tests]]></category>

		<guid isPermaLink="false">http://blog.punchbarrel.com/?p=691</guid>
		<description><![CDATA[Test-Driven Development (TDD) of HTTP and REST interfaces can be tricky. This post contains some examples of how to do it using the open source Mojasef toolkit. I was prompted to write this post after recently finding and fixing an irritating bug using just this technique. First, let&#8217;s set the scene. In TDD the rules [...]]]></description>
			<content:encoded><![CDATA[<p>Test-Driven Development (TDD) of HTTP and REST interfaces can be tricky. This post contains some examples of how to do it using the open source <a href="http://mojasef.stringtree.org/">Mojasef</a> toolkit. I was prompted to write this post after recently finding and fixing an irritating bug using just this technique.</p>
<p>First, let&#8217;s set the scene. In TDD the rules are very simple: No production code is written without a failing test; just enough code is written to satisfy the current set of tests; duplication is mercilessly refactored. TDD is a very powerful and effective technique which can improve both the quality and delivery time of software. HTTP and REST interfaces provide access to a system or component using the HTTP protocol. This access may be by fetching HTML or WML pages, for example, or it may be by sending,  receiving and updating resources in some other format such as XML or JSON.</p>
<p>For a first scenario imagine we have an existing HTTP interface for which we want to write a client using TDD. This service is relatively simple to start with. To send a message requires a POST request to a particular URL with two parameters &#8220;destination&#8221; and &#8220;text&#8221;. If the destination is valid, the text message is sent to the destination and a &#8220;200&#8243; status code is returned. If the destination is not recognized, a &#8220;404&#8243; status code is returned. This interface is <em>so</em> simple that it is tempting to just write the client, test it manually and move on. But if we were to do that, then we might not think of all the test case possibilities, and there would be no regression tests to help protect the software from unexpected side-effects later. So we opt to do the right thing, and use TDD.</p>
<p>For the sake of simplicity, I will assume we are using the Stringtree HTTPClient as <a href="http://blog.punchbarrel.com/2008/01/07/a-simple-http-client-part-1-overview/">described in an earlier post</a>. So let&#8217;s start with a simple test to make sure the code compiles and the test libraries and stuff are in place:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.stringtree.http.*</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MessageSendingTest <span style="color: #000000; font-weight: bold;">extends</span> junit.<span style="color: #006633;">framework</span>.<span style="color: #006633;">TestCase</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testExceptionFromUnknownURL<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    Form form <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Form<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    form.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;destination&quot;</span>, <span style="color: #0000ff;">&quot;name@example.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    form.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;text&quot;</span>, <span style="color: #0000ff;">&quot;hello from HTTP&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    HTTPClient client <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HTTPClient<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
      client.<span style="color: #006633;">post</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://localhost:9999/send&quot;</span>, form<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      fail<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;should throw an exception&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This test serves two purposes. First, compiling it helps drive the structure of the test case, what classes need to be imported and so on. Second it documents the expected behaviour of our client if the server is not running or not where it is expected to be.  I always like to start with this sort of &#8220;null&#8221; test case wherever possible. Once we get this test working we are ready to move on to the next step, testing against an actual server.</p>
<p>It might be possible to test against a real server, perhaps by manually examining log files, or checking the actual receipt of a message. Feel free to do that, but understand that that is really integration testing rather than unit testing, and neither helps us design and debug the client, nor document and enforce the proper behaviour of our code once we move on to other work. To gain these benefits we need a server which may be started, examined and stopped quickly and under the control of a simple unit test. This is where <a href="http://mojasef.stringtree.org/">Mojasef</a> comes in.</p>
<p>Mojasef is a server and web application framework designed for efficient test-driven development of web applications. Although usually used for building applications, it is just as suitable for building test harnesses. In this case we will build a simple application which implements the HTTP interface described above. And yes, we will do it using TDD, so we leave the MessageSendingTest for the moment and start a new one to drive our test harness without requiring HTTP. As usual, I start with a &#8220;null&#8221; test to get started:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MessageHarnessTest <span style="color: #000000; font-weight: bold;">extends</span> junit.<span style="color: #006633;">framework</span>.<span style="color: #006633;">TestCase</span> <span style="color: #009900;">&#123;</span>
  MessageHarness harness<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setUp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    harness <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MessageHarness<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testNoAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    assertFalse<span style="color: #009900;">&#40;</span>harness.<span style="color: #006633;">wasCalled</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This won&#8217;t compile without a MessageHarness class, so let&#8217;s make the minimum necessary.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MessageHarness <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> wasCalled<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Good, our test now runs, so let&#8217;s add some behaviour. First another test:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testCalledWithoutArguments<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    harness.<span style="color: #006633;">send</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    assertTrue<span style="color: #009900;">&#40;</span>harness.<span style="color: #006633;">wasCalled</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>To make this compile we need to add another method to MessageHarness</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> send<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Our new test fails, so we need to make it work.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MessageHarness <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">boolean</span> called <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> wasCalled<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> called<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> send<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    called <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>That seems enough to start with. Now back to the main test case. Add a new test to call the application we have just built over HTTP and check that all the communication stuff works. With a bit of refactoring to keep the tests clean and duplication low.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.stringtree.http.*</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.stringtree.mojasef.standalone.InlineServer</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MessageSendingTest <span style="color: #000000; font-weight: bold;">extends</span> junit.<span style="color: #006633;">framework</span>.<span style="color: #006633;">TestCase</span> <span style="color: #009900;">&#123;</span>
  HTTPClient client<span style="color: #339933;">;</span>
  Form form<span style="color: #339933;">;</span>
  InlineServer server<span style="color: #339933;">;</span>
  MessageHarness app<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setUp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    client <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HTTPClient<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    form <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Form<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    app <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MessageHarness<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    server <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> InlineServer<span style="color: #009900;">&#40;</span>app, <span style="color: #0000ff;">&quot;9998&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    server.<span style="color: #006633;">start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> tearDown<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	server.<span style="color: #006633;">halt</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testExceptionFromUnknownURL<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    form.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;destination&quot;</span>, <span style="color: #0000ff;">&quot;name@example.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    form.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;text&quot;</span>, <span style="color: #0000ff;">&quot;hello from HTTP&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
      client.<span style="color: #006633;">post</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://localhost:9999/send&quot;</span>, form<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      fail<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;should throw an exception&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testHarnessWiring<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    form.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;destination&quot;</span>, <span style="color: #0000ff;">&quot;unknown@example.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    form.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;text&quot;</span>, <span style="color: #0000ff;">&quot;hello from HTTP&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    assertFalse<span style="color: #009900;">&#40;</span>app.<span style="color: #006633;">wasCalled</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    client.<span style="color: #006633;">post</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://localhost:9998/send&quot;</span>, form<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    assertTrue<span style="color: #009900;">&#40;</span>app.<span style="color: #006633;">wasCalled</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This probably needs a bit of explanation. The MessageHarness class we produced above is a Mojasef web application. Really, without any other configuration, base classes or nonsense. It&#8217;s just a &#8220;plain old Java object&#8221; (POJO). The job of the Mojasef code is to take an object of that class and make its methods available as HTTP URLs.</p>
<p>To serve it over HTTP we <em>could</em> use a MojasefServlet and run it in any Servlet Container, but for this test we want an ultra-light server which can be started and stopped in a test. So we use the InlineServer provided in the Mojasef jar. It&#8217;s a real HTTP server which you can use from a regular web browser, but it&#8217;s mainly designed for streamlined use in tests.</p>
<p>This server is configured to serve the MessageHarness application on port 9998. Having configured the server we start it in startUp and stop it in tearDown to ensure that nothing is left behind between tests.</p>
<p>The new test makes a HTTP request to the freshly started server, then checks (by calling the MessageHarness method we created earlier) that the test harness application was successfully called. This verifies that the server has been correctly started and called.</p>
<p>It&#8217;s still not really testing the message API. To do that we need more tests.</p>
<p>Now, we know from the introduction above that our resource should return a HTTP 404 (&#8220;not found&#8221;) error if we try to send to an unrecognised address.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> test404FromUnknownDestination<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    form.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;destination&quot;</span>, <span style="color: #0000ff;">&quot;unknown@example.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    form.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;text&quot;</span>, <span style="color: #0000ff;">&quot;hello from HTTP&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003399;">Document</span> result <span style="color: #339933;">=</span> client.<span style="color: #006633;">post</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://localhost:9998/send&quot;</span>, form<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;404&quot;</span>, result.<span style="color: #006633;">getHeader</span><span style="color: #009900;">&#40;</span>HTTPClient.<span style="color: #006633;">HTTP_RESPONSE_CODE</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Making this test work is pretty simple, especially as we have no other tests which say anything about the HTTP Response code. The only &#8220;cleverness&#8221; is that we now need to use some slightly smarter features of the Mojasef code.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.stringtree.finder.StringKeeper</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.stringtree.mojasef.HTTPConstants</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MessageHarness <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">boolean</span> called <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> wasCalled<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> called<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> send<span style="color: #009900;">&#40;</span>StringKeeper context<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    called <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    context.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span>HTTPConstants.<span style="color: #006633;">RESPONSE_CODE</span>, <span style="color: #0000ff;">&quot;404&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Mojasef will try a variety of ways to call a public method. We have seen the basic one &#8211; a method with no parameters mapped directly to a URL. This is another one &#8211; a  method taking a &#8220;context&#8221; as an argument. This context will be pre-loaded with any POST or URL parameters, as well as any request headers and plenty of other stuff which is not of interest right now. This context also provides a way of setting information to be sent back to the client.</p>
<p>Now, our application code is passing all its tests, but it does so by returning a &#8220;404&#8243; error code for all requests. This is not really desirable behaviour, so we need another test:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> test200FromKnownDestination<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    form.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;destination&quot;</span>, <span style="color: #0000ff;">&quot;known@example.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    form.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;text&quot;</span>, <span style="color: #0000ff;">&quot;hello from HTTP&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003399;">Document</span> result <span style="color: #339933;">=</span> client.<span style="color: #006633;">post</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://localhost:9998/send&quot;</span>, form<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;200&quot;</span>, result.<span style="color: #006633;">getHeader</span><span style="color: #009900;">&#40;</span>HTTPClient.<span style="color: #006633;">HTTP_RESPONSE_CODE</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>This test fails, so we need to modify the application to add some understanding of the supplied form data.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.stringtree.finder.StringKeeper</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.stringtree.mojasef.HTTPConstants</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MessageHarness <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">boolean</span> called <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> wasCalled<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> called<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> send<span style="color: #009900;">&#40;</span>StringKeeper context<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    called <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #003399;">String</span> destination <span style="color: #339933;">=</span> context.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;destination&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;known@example.com&quot;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>destination<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        context.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span>HTTPConstants.<span style="color: #006633;">RESPONSE_CODE</span>, <span style="color: #0000ff;">&quot;200&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
        context.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span>HTTPConstants.<span style="color: #006633;">RESPONSE_CODE</span>, <span style="color: #0000ff;">&quot;404&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now we reach an interesting point in the development process. It is perfectly feasible to continue in this vein, step-by-step bringing the application into existence. However, even the streamlined InlineServer still needs to set itself up, bind and unbind ports, deal with network traffic and so on. This is considerably slower than a regular method call, and as more tests are added the test case will continue to slow down.</p>
<p>The advantages of the Mojasef approach to web applications really begin to pay off at this point. The tests we already have prove the basics of HTTP Communication are working, so further tests do not really need to bother with HTTP, <em>provided the tests are testing exactly the same code</em>. Luckily (as pointed out earlier) a Mojasef application is just a regular Java class, which needs no modification to be tested using regular JUnit tests. Here are the same tests as above, but implemented as simple method calls:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.stringtree.finder.StringKeeper</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.stringtree.mojasef.HTTPConstants</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.stringtree.mojasef.HTTPConstants</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MessageProcessingTest <span style="color: #000000; font-weight: bold;">extends</span> junit.<span style="color: #006633;">framework</span>.<span style="color: #006633;">TestCase</span> <span style="color: #009900;">&#123;</span>
  StringKeeper context<span style="color: #339933;">;</span>
  MessageHarness app<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setUp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    context <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MapStringKeeper<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    app <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MessageHarness<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> test404FromUnknownDestination<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    context.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;destination&quot;</span>, <span style="color: #0000ff;">&quot;unknown@example.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    context.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;text&quot;</span>, <span style="color: #0000ff;">&quot;hello from HTTP&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    app.<span style="color: #006633;">send</span><span style="color: #009900;">&#40;</span>context<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;404&quot;</span>, context.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>HTTPConstants.<span style="color: #006633;">RESPONSE_CODE</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> test200FromKnownDestination<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    context.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;destination&quot;</span>, <span style="color: #0000ff;">&quot;known@example.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    context.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;text&quot;</span>, <span style="color: #0000ff;">&quot;hello from HTTP&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    app.<span style="color: #006633;">send</span><span style="color: #009900;">&#40;</span>context<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;200&quot;</span>, context.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>HTTPConstants.<span style="color: #006633;">RESPONSE_CODE</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>I shall stop there, leaving the development of the rest of the application to interested readers.</p>
<p>From the above steps, I hope you can see that the normal process of Test-Driven Development is quite possible for both web applications, and web-application clients. When using a framework which gets all the fiddly stuff out of the way it can even be as simple, quick and productive as in-process development.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.punchbarrel.com/2009/01/07/test-driven-development-of-http-and-rest-interfaces-with-mojasef/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JSON Schema Proposal</title>
		<link>http://blog.punchbarrel.com/2008/11/02/json-schema-proposal/</link>
		<comments>http://blog.punchbarrel.com/2008/11/02/json-schema-proposal/#comments</comments>
		<pubDate>Sun, 02 Nov 2008 00:49:10 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[stringtree]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[schema]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://blog.punchbarrel.com/?p=750</guid>
		<description><![CDATA[What a great idea! a schema definition for JSON, in JSON. I&#8217;m really tempted to build a validator for this format using my Stringtree JSON code. JSON Schema Proposal]]></description>
			<content:encoded><![CDATA[<p>What a great idea! a schema definition for JSON, in JSON. I&#8217;m really tempted to build a validator for this format using my Stringtree JSON code.</p>
<p><a href="http://json-schema.org/">JSON Schema Proposal</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.punchbarrel.com/2008/11/02/json-schema-proposal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A kind of answer to &#8220;Is it time for Java 5?&#8221;</title>
		<link>http://blog.punchbarrel.com/2008/10/01/a-kind-of-answer-to-is-it-time-for-java-5/</link>
		<comments>http://blog.punchbarrel.com/2008/10/01/a-kind-of-answer-to-is-it-time-for-java-5/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 13:24:43 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[stringtree]]></category>
		<category><![CDATA[eosl]]></category>
		<category><![CDATA[java 1.4]]></category>
		<category><![CDATA[java 5]]></category>

		<guid isPermaLink="false">http://blog.punchbarrel.com/?p=577</guid>
		<description><![CDATA[A week or two ago I wrote asking Is it time for Java 5?. I got a few answers, but nothing definitive. Today, however, I stumbled upon a blog post from Alex Miller which helped me decide. Apparently, Java 1.4 will officially reach its end of service life (EOSL) at the end of October 2008. [...]]]></description>
			<content:encoded><![CDATA[<p>A week or two ago I wrote asking <a href="http://blog.punchbarrel.com/2008/09/21/is-it-time-for-java-5/">Is it time for Java 5?</a>. I got a few answers, but nothing definitive. Today, however, I stumbled upon a <a href="http://tech.puredanger.com/2008/10/01/ripjdk-14/">blog post</a> from <a href="http://tech.puredanger.com/">Alex Miller</a> which helped me decide.</p>
<p>Apparently, Java 1.4 will officially reach its end of service life (EOSL) at the end of October 2008. That of itself does not imply that nobody will continue to use it, but it does help third-party providers such as myself decide when to stop active support.</p>
<p>So, this is my decision. Some time after the start of November I will make a branch of the final Java 1.4-compatible version of all my public projects. Any future changes will no longer guarantee Java 1.4 support.</p>
<p>This does not imply, of course, that all my public code will suddenly be rewritten; dripping with annotations and generics and so on. The process will be incremental and progressive. The main point is that I will no longer be ensuring Java 1.4 compatibility in future releases.</p>
<p>As an aside &#8211; if you <strong>are</strong> still using Java 1.4 and would like to suggest a change to any of my software, please ensure that you get in touch in time for me to include it before November!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.punchbarrel.com/2008/10/01/a-kind-of-answer-to-is-it-time-for-java-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Is it time for Java 5?</title>
		<link>http://blog.punchbarrel.com/2008/09/21/is-it-time-for-java-5/</link>
		<comments>http://blog.punchbarrel.com/2008/09/21/is-it-time-for-java-5/#comments</comments>
		<pubDate>Sun, 21 Sep 2008 00:18:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[stringtree]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[java 1.4]]></category>
		<category><![CDATA[java 5]]></category>

		<guid isPermaLink="false">http://blog.punchbarrel.com/2008/09/21/is-it-time-for-java-5/</guid>
		<description><![CDATA[A major goal of the Stringtree software project has always been to be as compatible as possible with all the software people are using for their Java development. Naturally that also includes whatever Java version is being used. For a long time I interpreted this goal as implying that all Stringtree code should run on [...]]]></description>
			<content:encoded><![CDATA[<p>A major goal of the Stringtree software project has always been to be as compatible as possible with all the software people are using for their Java development. Naturally that also includes whatever Java version is being used.</p>
<p>For a long time I interpreted this goal as implying that all Stringtree code should run on all Java versions from Java 1.2 onwards. Java 1.4, however, introduced some compelling new features including built-in regular-expression handling. For a few years I still tried to ensure that most code was still 1.2-compatible (for example by using Ant to swap in a third-party regular-expression library while building a jar file), while also providing a Java 1.4 version. Eventually, use of Java versions prior to 1.4 declined enough that I felt comfortable removing the complicated pre-1.4 version.</p>
<p>For the last few years I have been very careful to keep all my Stringtree code compatible with all versions of Java from 1.4 upwards. Now, however, the pressure is building again to move over to Java 5. In my day-to-day coding I develop with Java 5 and make increasing use of Java 5 features such as the enhanced for loop, the Iterable interface, enums, generics, autoboxing, varargs and so on. It would be very nice to be able to update the Stringtree codebase to use these features too.</p>
<p>Occasionally a Java 5-specific detail has crept in to a Stringtree library, and I have soon received comments or emails pointing this out. I haven&#8217;t noticed this for a while, which might indicate either that I have been especially careful, or that I there are no longer any/many people developing with Stringtree code who are still limited to Java 1.4.</p>
<p>If you are reading this and you still require Java 1.4 support, please let me know. Likewise, if you have thrown off the shackles of 1.4 within the last year or so or are desperately hoping for a Java 5 Stringtree that would be good to know too.</p>
<p>Is it time for Java 5 yet?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.punchbarrel.com/2008/09/21/is-it-time-for-java-5/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Slight Improvement to Stringtree XML Parser</title>
		<link>http://blog.punchbarrel.com/2008/01/31/slight-improvement-to-stringtree-xml-parser/</link>
		<comments>http://blog.punchbarrel.com/2008/01/31/slight-improvement-to-stringtree-xml-parser/#comments</comments>
		<pubDate>Thu, 31 Jan 2008 14:09:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[stringtree]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.punchbarrel.com/2008/09/05/slight-improvement-to-stringtree-xml-parser/</guid>
		<description><![CDATA[Someone just pointed out that the light-weight XML parser included in Stringtree did not handle explicit CDATA blocks. The version in SVN now has provisional support for this. If you need a simple and fast parser for textual data, then this should be all you need. For XML documents containing opaque binary data in a [...]]]></description>
			<content:encoded><![CDATA[<p>Someone just pointed out that the light-weight <a href="http://stringtree.svn.sourceforge.net/svnroot/stringtree/trunk/src/delivery/java/org/stringtree/xml/XMLReader.java">XML parser</a> included in Stringtree did not handle explicit CDATA blocks. The version in SVN now has provisional support for this.</p>
<p>If you need a simple and fast parser for textual data, then this should be all you need. For XML documents containing opaque binary data in a CDATA block, this may not be ideal. Currently CDATA blocks are loaded as String objects, and this can lead to incorrect data for bytes which do not represent valid characters in the current character set.</p>
<p>I am currently planning for the next version of the Stringtree XMLReader to offer the option of extracting a CDATA block as an unprocessed byte array.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.punchbarrel.com/2008/01/31/slight-improvement-to-stringtree-xml-parser/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Simple HTTP Client &#8211; Part 1 (Overview)</title>
		<link>http://blog.punchbarrel.com/2008/01/07/a-simple-http-client-part-1-overview/</link>
		<comments>http://blog.punchbarrel.com/2008/01/07/a-simple-http-client-part-1-overview/#comments</comments>
		<pubDate>Mon, 07 Jan 2008 14:09:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[stringtree]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[HTTPClient]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://711520859</guid>
		<description><![CDATA[This post is the first of a series describing the use and implementation of the Stringtree HTTP Client. Recently I have been working with systems which talk to each other using REST/HTTP. Providing services and resources is pretty simple using Mojasef, but accessing such resources and consuming such services (in client code and in tests) [...]]]></description>
			<content:encoded><![CDATA[<p><i>This post is the first of a series describing the use and implementation of the Stringtree HTTP Client.</i></p>
<p>Recently I have been working with systems which talk to each other using REST/HTTP. Providing services and resources is pretty simple using <a href="http://mojasef.stringtree.org/">Mojasef</a>, but accessing such resources and consuming such services (in client code and in tests) has always seemed a bit more clumsy than it should be. I tried Apache HTTPClient and HttpUnit, but both seemed cumbersome for simple tasks, and bring in several hundred KB or more of dependencies, which can really bloat a small client application. I&#8217;m sure there are others, but I got bored with looking, and instead wrote my own simple HTTP Client which does the things I need without dragging in tons of extra stuff.</p>
<p>The Stringtree HTTP Client consists of just four classes, with no dependencies other than the standard Java APIs:</p>
<ul>
<li><a href="https://stringtree.svn.sourceforge.net/svnroot/stringtree/trunk/src/delivery/java/org/stringtree/http/HTTPClient.java">org.stringtree.http.HTTPClient</a></li>
<li><a href="https://stringtree.svn.sourceforge.net/svnroot/stringtree/trunk/src/delivery/java/org/stringtree/http/Form.java">org.stringtree.http.Form</a></li>
<li><a href="https://stringtree.svn.sourceforge.net/svnroot/stringtree/trunk/src/delivery/java/org/stringtree/http/Document.java">org.stringtree.http.Document</a></li>
<li><a href="https://stringtree.svn.sourceforge.net/svnroot/stringtree/trunk/src/delivery/java/org/stringtree/http/NameValue.java">org.stringtree.http.NameValue</a></li>
</ul>
<p>The point of these classes is to allow simple construction and calling of all valid HTTP requests, including the ability to set and read headers and cookies, simulate the submission of an HTML form, and support both textual and binary content data.</p>
<p>As a very simple example, consider the following code which issues a GET request to a specified URL:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">HTTPClient client <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HTTPClient<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003399;">Document</span> response <span style="color: #339933;">=</span> client.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://localhost:8080/?a=b&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;response content type=&quot;</span> <span style="color: #339933;">+</span> response.<span style="color: #006633;">getHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Content-Type&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;response content=&quot;</span> <span style="color: #339933;">+</span> response.<span style="color: #006633;">getContentAsString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The above code example shows basic usage of the Stringtree HTTP Client. In more general terms, usage is as follows:</p>
<ol>
<li>Create an object of the HTTPClient class.</li>
<li>Set any long-lived settings, such as cookies or a user-agent.</li>
<li>Call one of the request methods with appropriate parameters.</li>
<li>Read returned headers and content as required from the returned <tt>Document</tt> object.</li>
<li>Repeat from (3) for each new request.</li>
</ol>
<p>A slightly more complex example using a POST request to submit an HTML form might look like:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">HTTPClient client <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HTTPClient<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Mozilla/5.0 (example)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
client.<span style="color: #006633;">setCookie</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;username&quot;</span>, <span style="color: #0000ff;">&quot;Frank&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Form form <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Form<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
form.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;name&quot;</span>, <span style="color: #0000ff;">&quot;Widget&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
form.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;category&quot;</span>, <span style="color: #0000ff;">&quot;thing&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003399;">Document</span> response <span style="color: #339933;">=</span> client.<span style="color: #006633;">post</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://localhost:8080/update&quot;</span>, form<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">boolean</span> ok <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;200&quot;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>response.<span style="color: #006633;">getHeader</span><span style="color: #009900;">&#40;</span>HTTPClient.<span style="color: #006633;">HTTP_RESPONSE_CODE</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>All the request methods return an <tt>org.stringtree.http.Document</tt> object. This object represents the structure of an HTTP request or response: a collection of name/value headers (which may contain duplicate names), and a block of &#8220;content&#8221; which may be considered as text or as a sequence of bytes. The HTTPClient code does make one simplifying concession; as seen in the above POST example the HTTP response code is added as a pseudo-header with the name &#8220;http.response.code&#8221;.</p>
<p>This should be enough to get started playing with the Stringtree HTTP Client. In the next post I will discuss the possibilities for creating and configuring an HTTPClient object in full detail.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.punchbarrel.com/2008/01/07/a-simple-http-client-part-1-overview/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Stringtree Maven Repository</title>
		<link>http://blog.punchbarrel.com/2008/01/07/stringtree-maven-repository/</link>
		<comments>http://blog.punchbarrel.com/2008/01/07/stringtree-maven-repository/#comments</comments>
		<pubDate>Mon, 07 Jan 2008 14:09:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[stringtree]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://1602481442</guid>
		<description><![CDATA[I have experimented with Maven a few times, but never been particularly impressed. Recently, however, one of my users has been bugging me to make the Stringtree and Mojasef classes and sources available in a Maven-style repository, for easier integration with Maven (or Maven-like) build tools and workflows. So I have done it. The current [...]]]></description>
			<content:encoded><![CDATA[<p>I have experimented with <a href="http://maven.apache.org/">Maven</a> a few times, but never been particularly impressed. </p>
<p>Recently, however, <a href="http://www.realsolve.co.uk/site/home.php">one of my users</a> has been bugging me to make the Stringtree and Mojasef classes and sources available in a Maven-style repository, for easier integration with Maven (or Maven-like) build tools and workflows. So I have done it. The current versions of key Stringtree and Mojasef files are now available from the <a href="http://stringtree.org/repository/">Stringtree repository</a> at the following URLs:</p>
<ul>
<li><a href="http://stringtree.org/repository/org/stringtree/stringtree/2.0.10/stringtree-2.0.10-sources.jar">http://stringtree.org/repository/org/stringtree/stringtree/2.0.10/stringtree-2.0.10-sources.jar</a></li>
<li><a href="http://stringtree.org/repository/org/stringtree/stringtree/2.0.10/stringtree-2.0.10.jar">http://stringtree.org/repository/org/stringtree/stringtree/2.0.10/stringtree-2.0.10.jar</a></li>
<li><a href="http://stringtree.org/repository/org/stringtree/stringtree/2.0.10/stringtree-httpclient-2.0.10.jar">http://stringtree.org/repository/org/stringtree/stringtree/2.0.10/stringtree-httpclient-2.0.10.jar</a></li>
<li><a href="http://stringtree.org/repository/org/stringtree/stringtree/2.0.10/stringtree-json-2.0.10.jar">http://stringtree.org/repository/org/stringtree/stringtree/2.0.10/stringtree-json-2.0.10.jar</a></li>
<li><a href="http://stringtree.org/repository/org/stringtree/mojasef/2.0.b1/mojasef-2.0.b1-sources.jar">http://stringtree.org/repository/org/stringtree/mojasef/2.0.b1/mojasef-2.0.b1-sources.jar</a></li>
<li><a href="http://stringtree.org/repository/org/stringtree/mojasef/2.0.b1/mojasef-2.0.b1-withdependencies-sources.jar">http://stringtree.org/repository/org/stringtree/mojasef/2.0.b1/mojasef-2.0.b1-withdependencies-sources.jar</a></li>
<li><a href="http://stringtree.org/repository/org/stringtree/mojasef/2.0.b1/mojasef-2.0.b1-withdependencies.jar">http://stringtree.org/repository/org/stringtree/mojasef/2.0.b1/mojasef-2.0.b1-withdependencies.jar</a></li>
<li><a href="http://stringtree.org/repository/org/stringtree/mojasef/2.0.b1/mojasef-2.0.b1.jar">http://stringtree.org/repository/org/stringtree/mojasef/2.0.b1/mojasef-2.0.b1.jar</a></li>
</ul>
<p>The Stringtree and Mojasef build scripts now include a &#8220;publish&#8221; target which uploads such artefacts to appropriate places in the repository, so future versions should continue to be available.</p>
<p>This is the first time I have done this, so I would welcome comments from any readers who actually use Maven (or buildr, or anything else which supports this repository format). In particular, I am interested in opinions on whether it is OK to simply replace artefacts with the same names and locations for minor tweaks and bug-fixes, or whether even the smallest change should result in the generation and upload of a new version with a new name and location.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.punchbarrel.com/2008/01/07/stringtree-maven-repository/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 3.087 seconds -->
