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

<channel>
	<title>let x=x &#187; web</title>
	<atom:link href="http://www.crazymcphee.net/x/tag/web/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.crazymcphee.net/x</link>
	<description>programming idiom and methodology</description>
	<lastBuildDate>Fri, 27 Jan 2012 09:36:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Fairfax media &#8211; incompetent boobs</title>
		<link>http://www.crazymcphee.net/x/2012/01/03/fairfax-media-incompetent-boobs/</link>
		<comments>http://www.crazymcphee.net/x/2012/01/03/fairfax-media-incompetent-boobs/#comments</comments>
		<pubDate>Tue, 03 Jan 2012 06:50:47 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[rants]]></category>
		<category><![CDATA[reviews]]></category>
		<category><![CDATA[brisbanetimes]]></category>
		<category><![CDATA[fairfax]]></category>
		<category><![CDATA[i'm taking up drinking as a hobby instead of programming]]></category>
		<category><![CDATA[lol]]></category>
		<category><![CDATA[management]]></category>
		<category><![CDATA[newspapers]]></category>
		<category><![CDATA[poorly attempted humour]]></category>
		<category><![CDATA[qantas take note]]></category>
		<category><![CDATA[smh]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[websites]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=733</guid>
		<description><![CDATA[Well I logged into the Fairfax site BrisbaneTimes.com.au this morning for my dose of occasional local newspaper media (the Brisbane Times is really a web-only copy of the SMH with some local content). Wanted to comment on an article; it seemed they changed their login system and my old login didn&#8217;t work. That&#8217;s OK, I [...]]]></description>
			<content:encoded><![CDATA[<p>Well I logged into the Fairfax site BrisbaneTimes.com.au this morning for my dose of occasional local newspaper media (the Brisbane Times is really a web-only copy of the SMH with some local content). Wanted to comment on an article; it seemed they changed their login system and my old login didn&#8217;t work.</p>
<p>That&#8217;s OK, I went to use the Facebook connect login instead. This appeared to work for a second, then reported;</p>
<blockquote><p>The page you were looking for doesn&#8217;t exist.</p>
<p>You may have mistyped the address or the page may have moved.</p></blockquote>
<p>But it must have worked; I got an email from &#8216;support@fairfaxmedia.com.au&#8217; welcoming me on my successful registration. In part this email said:</p>
<blockquote><p>If you have any questions or need any assistance please do not hesitate to contact us at support@fairfaxmedia.com.au.</p></blockquote>
<p>However, time to go go to work, nothing to do about it for the moment so put it aside; maybe they&#8217;ll organically fix their problem during the day.</p>
<p>Later today, clicked on the login link to login and comment. Same problem, a 404. OK, let&#8217;s try emailing that support address &#8211; after all, they <em>invited</em> me &#8220;not to hesitate&#8221; and I already hesitated 7 or 8 hours. What do you think happens?</p>
<blockquote><pre>Delivery has failed to these recipients or distribution lists:

support@fairfaxmedia.com.au
The recipient's e-mail address was not found in the recipient's e-mail system. Microsoft
Exchange will not try to redeliver this message for you. Please check the e-mail address and
try resending this message, or provide the following diagnostic text to your system
administrator.

Sent by Microsoft Exchange Server 2007

Diagnostic information for administrators:

Generating server: ffx.jfh.com.au

support@fairfaxmedia.com.au
#550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
</pre>
</blockquote>
<p>Yeah, so that&#8217;s a <em>smashing</em> success, then.</p>
<p>(NB. jfh.com.au probably is John Fairfax Holdings, the parent company, it&#8217;s registered to FAIRFAX DIGITAL HOLDINGS, so the error above is an internal configuration error in their email system &#8211; they are advertising an email address that is non-functional!)</p>
<p>No wonder Fairfax is gurgling down the drain. Their newspapers are increasingly shit, their websites full of &#8220;OMG THE BEWBZ!1!&#8221; and cheap political sensationalism &#8230; now their website is  hardly functional and apparently their unpaid work experience h4x0r hasn&#8217;t noticed yet. What a bunch of idiots.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2012/01/03/fairfax-media-incompetent-boobs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>blog link: world–</title>
		<link>http://www.crazymcphee.net/x/2011/10/14/blog-link-world%e2%80%93/</link>
		<comments>http://www.crazymcphee.net/x/2011/10/14/blog-link-world%e2%80%93/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 09:28:34 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[infrastructure and frameworks]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[craftsmanship]]></category>
		<category><![CDATA[unix]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/2011/10/14/blog-link-world%e2%80%93/</guid>
		<description><![CDATA[world– by Robert Merkel at Larvatus Prodeo. Published October 14, 2011 at 09:02AM The technology world has just lost another giant, though one without the towering public persona of Steve Jobs. If you’re not actually a programmer, you’ve probably never heard of Dennis Ritchie. But the vast majority of software you use was built using [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://larvatusprodeo.net/2011/10/14/world/">world–</a> by Robert Merkel at <a href="http://larvatusprodeo.net">Larvatus Prodeo</a>. Published October 14, 2011 at 09:02AM</p>
<blockquote><p>The technology world has just lost another giant, though one without the towering public persona of Steve Jobs.</p>
<p>If you’re not actually a programmer, you’ve probably never heard of <a href="http://www.washingtonpost.com/blogs/blogpost/post/dennis-ritchie-father-of-c-programming-language-and-unix-dies-at-70/2011/10/13/gIQADGNbhL_blog.html">Dennis Ritchie</a>. But the vast majority of software you use was built using a tool that he originally designed, and the rest by tools that very liberally sample from his.</p>
<p>The “native language” that the central processor in a computer understands is an ornery beast. For one thing, back in the 1970s every two-bit computer company (if you’ll pardon the techy pun) had its own native language; these days, there still remain two very common ones, and dozens of less common examples out there. More importantly, it’s almost incomprehensible, even to most programmers. Take this little snippet, part of the preliminaries to a very simple program that just prints the message “hello, world” to the screen:</p>
<pre>_start:
        mov    eax, 4
        mov    ebx, 1
        mov    ecx, str
        mov    edx, str_len
        int    80h</pre>
<p>Writing long and complicated bits of software with such unhelpful notation is extremely slow and error-prone.</p>
<p>“High-level” languages, that allowed the logic of software to be expressed in more compact and readable notation, had existed since the 1950s; <a href="http://en.wikipedia.org/wiki/Grace_Hopper">Grace Hopper</a> was responsible for one of the first. Over time, more and more of the scientific and business software run on the large computers of the era was written in FORTRAN, COBOL, and other high-level langages. However, the “operating systems”, the software plumbing that joined those applications to the hardware, was invariably written in the machine language of specific systems.</p>
<p>In the late 1960s, Ritchie, working with Ken Thompson at Bell Laboratories, hacked together their own little operating system for an obsolete computer nobody was making use of. It was small, but it worked, and was one of the first practical systems to support “timesharing” – the ability for multiple users to run multiple programs simultaneously and interactively. Fairly early on, they had another brainwave; they would rewrite as much of the system – which became known as Unix – as possible in a high-level programming language, to speed development. But first, they needed a suitable high-level language. The resulting language, an evolution of earlier languages entitled BCPL and B, was called “C”.</p>
<p>Both C and Unix were raging successes, partly because of their inherent strengths. The use of C allowed Unix to be “ported” to many different computer systems, a process that continues today as its spiritual successor Linux, written in C, runs on everything from IBM mainframes (and the amphormous “Googleplex” of Google’s servers which, reportedly, draw 240 megawatts of power), to virtually every smartphone on the planet (the iPhone’s operating system is not Linux, but it is also a derivation of Unix and substantial parts are written in C). They also had the good fortune, as with the Internet and World Wide Web which owes so much to both, that they gradually escaped the crush of intellectual property law to become part of the intellectual commons of the field.</p>
<p>Almost as important was the elegance and economy that Ritchie, along with Brian Kernighan, brought to teaching the language. Their textbook <a href="http://en.wikipedia.org/wiki/The_C_Programming_Language">The C Programming Language</a> remains the best programming language textbook ever written, in my view, and the one that I still strongly recommend to my students.</p>
<p>Much of the Windows operating system, and Mac OS X, are implemented in C. Those parts that aren’t, are implemented in computer languages directly derived from it – C++ and Objective-C. Most of the software that runs on those systems is also written in C or its successor languages. And perhaps the most pervasive “new” high-level language of the last 20 years – Java – retains so much of C’s “look and feel” that it often takes a second glance to tell which language a piece of code is written in.</p>
<p>Neither C nor Unix were by any means perfect. While some of its design faults have been eliminated in its successors others remain, and will likely continue to bamboozle neophyte (and, all too often, experienced) programmers, for generations to come. But there was so much he and his colleagues got right. Fate did play its part, but there are very good reasons that generations of software developers not yet born will express themselves in notations largely based on Ritchie’s.</p>
<p>RIP, dmr.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2011/10/14/blog-link-world%e2%80%93/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dennis Ritchie: The Shoulders Steve Jobs Stood On &#124; Wired Enterprise &#124; Wired.com</title>
		<link>http://www.crazymcphee.net/x/2011/10/14/dennis-ritchie-the-shoulders-steve-jobs-stood-on-wired-enterprise-wired-com/</link>
		<comments>http://www.crazymcphee.net/x/2011/10/14/dennis-ritchie-the-shoulders-steve-jobs-stood-on-wired-enterprise-wired-com/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 09:28:02 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[infrastructure and frameworks]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[unix]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=662</guid>
		<description><![CDATA[“Jobs’ genius is that he builds these products that people really like to use because he has taste and can build things that people really find compelling. Ritchie built things that technologists were able to use to build core infrastructure that people don’t necessarily see much anymore, but they use everyday.” via Dennis Ritchie: The [...]]]></description>
			<content:encoded><![CDATA[<p>“Jobs’ genius is that he builds these products that people really like to use because he has taste and can build things that people really find compelling. Ritchie built things that technologists were able to use to build core infrastructure that people don’t necessarily see much anymore, but they use everyday.”</p>
<p>via <a href="http://www.wired.com/wiredenterprise/2011/10/thedennisritchieeffect">Dennis Ritchie: The Shoulders Steve Jobs Stood On | Wired Enterprise | Wired.com</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2011/10/14/dennis-ritchie-the-shoulders-steve-jobs-stood-on-wired-enterprise-wired-com/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>if this then that</title>
		<link>http://www.crazymcphee.net/x/2011/09/22/if-this-then-that/</link>
		<comments>http://www.crazymcphee.net/x/2011/09/22/if-this-then-that/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 07:14:02 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[apps]]></category>
		<category><![CDATA[rants]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[ifttt]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[social media]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=623</guid>
		<description><![CDATA[I have recently been using &#8220;if this then that&#8221; to integrate my Google Reader with this blog and other places, like Facebook, Flickr, Twitter, and tumblr (I have a Classics-related tumblr). It&#8217;s a great way to do simple integration between these services but one annoyance is that it lacks any way to discriminate actions. For [...]]]></description>
			<content:encoded><![CDATA[<p>I have recently been using &#8220;<a href="http://ifttt.com/">if this then that</a>&#8221; to integrate my Google Reader with this blog and other places, like Facebook, Flickr, Twitter, and <a href="http://monumentum.tumblr.com/">tumblr</a> (I have a Classics-related tumblr). It&#8217;s a great way to do simple integration between these services but one annoyance is that it lacks any way to discriminate actions. For example to separate out the Programming stuff from the Classics material in Google Reader, I have to &#8220;like&#8221; the Technical posts and &#8220;share&#8221; the Classics ones, as that&#8217;s the only way to separate the two (the input events &#8220;like&#8221; and &#8220;share&#8221; on Google Reader being separate events). There&#8217;s also <a href="http://blog.jonudell.net/2011/09/19/i-want-to-be-the-customer-not-the-product/">this</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2011/09/22/if-this-then-that/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tapestry 5 web framework</title>
		<link>http://www.crazymcphee.net/x/2009/08/26/tapestry-5-web-framework/</link>
		<comments>http://www.crazymcphee.net/x/2009/08/26/tapestry-5-web-framework/#comments</comments>
		<pubDate>Wed, 26 Aug 2009 12:09:18 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[infrastructure and frameworks]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[tapestry]]></category>
		<category><![CDATA[tapestry5]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[web framework]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=443</guid>
		<description><![CDATA[Lately I&#8217;ve been writing a Tapestry 5 based web application. I&#8217;ve used it before for a smaller application but this is the first time I&#8217;ve used it on a larger project. In a number of ways it is a very powerful framework to write web applications. The basics of Tapestry is that it is a [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I&#8217;ve been writing a <a href="http://tapestry.apache.org/tapestry5/" target="_blank">Tapestry 5</a> based web application. I&#8217;ve used it before for a smaller application but this is the first time I&#8217;ve used it on a larger project. In a number of ways it is a very powerful framework to write web applications.</p>
<p>The basics of Tapestry is that it is a component-based web framework. Just about everything, including web pages, are components. Components may contain other components. The way it works is very simple and quite elegant, once you get used to it and weaned off the big-XML-file style of configuring a web application.</p>
<p>When you start, you have two main Java packages that are created for you (if you use the maven archetype, otherwise you will create these packages yourself). If your package root is say &#8220;net.crazymcphee.webapp&#8221;, then your two packages are &#8220;net.crazymcphee.webapp.pages&#8221; and &#8220;net.crazymcphee.webapp.components&#8221;. To configure a Tapestry 5 project with maven <a href="http://tapestry.apache.org/tapestry5/quickstart/">use this command</a> and answer the prompts:</p>
<pre>mvn archetype:generate \</pre>
<pre>    -DarchetypeCatalog=http://tapestry.formos.com/maven-snapshot-repository</pre>
<p>Don&#8217;t use the one in the <a href="http://tapestry.apache.org/tapestry5/tutorial1/first.html">tutorial</a> as it will not work! This is an excellent illustration of the first and most serious problem that Tapestry 5 has: the documentation not only has massive lacunas, it is also sometimes wrong and not updated.</p>
<p>Now, any class that you create in the &#8220;pages&#8221; package will automatically become a page in your application. But these classes need not be very complex at all. For example:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.crazymcphee.webapp.pages</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.Collections</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.List</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.tapestry5.annotations.Persist</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.tapestry5.annotations.Property</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.tapestry5.ioc.annotations.Inject</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">net.crazymcphee.webapp.model.Person</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">net.crazymcphee.webapp.services.PersonService</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> Persons <span style="color: #009900;">&#123;</span>
&nbsp;
    @Inject
    <span style="color: #000000; font-weight: bold;">private</span> PersonService personService<span style="color: #339933;">;</span>
    @Property
    @Persist
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">List</span> persons<span style="color: #339933;">;</span>
    @Property
    @Persist
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> searchTerm<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003399;">Object</span> onSubmitFromSearch<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        persons <span style="color: #339933;">=</span> personService.<span style="color: #006633;">findPersons</span><span style="color: #009900;">&#40;</span>searchTerm<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #003399;">Object</span> onSubmitFromClear<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        persons <span style="color: #339933;">=</span> <span style="color: #003399;">Collections</span>.<span style="color: #006633;">EMPTY_LIST</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>You can see that this class doesn&#8217;t extend any infrastructure classes and has quite a simple structure. This is a fully functional page with two actions &#8211; one populates a list, the other clears it.</p>
<p>Now, to explain just a little here; PersonService is injected by Tapestry, but you need to configure in your AppModule which implementation you want to use. You can also use it with Spring as your IOC container but the one that comes with Tapestry is perfectly good enough for most applications.</p>
<p>The List, persons, and the searchTerm parameters are marked as @Property (so we don&#8217;t need to add getters and setters) and also @Persist so that the variables are preserved from request to request.</p>
<p>The methods &#8220;onSubmitFromSearch&#8221; and &#8220;onSubmitFromClear&#8221; are using a convention &#8211; &#8220;onSubmit&#8221; will also work, but assuming (as is true in this case) that we may have multiple forms on the one page, each method will only be fired from the &#8220;search&#8221; form in one instance, and the &#8220;clear&#8221; form in the other. These names are not special, it&#8217;s just (as you&#8217;ll see below) the forms will have these two names. They could be &#8220;Bill&#8221; and &#8220;Ben&#8221; in which case the methods would be &#8220;onSubmitFromBill&#8221; and &#8220;onSubmitFromBen&#8221;.</p>
<p>You will also note that these methods return the same page instance, which tells Tapestry to re-render the same page, but if you wanted to forward onto another page, you would add a instance variable, mark it with an @InjectPage annotation, and return that instance variable (after initialising it in your &#8220;onSubmit&#8221; method) instead of just returning &#8220;this&#8221;.</p>
<p>This page Persons, is available at {application-context-path}/persons. But there is one other part of the puzzle &#8211; the actual view. As mentioned, Tapestry uses convention over configuration and in this case, the convention is that the Page markup must be named the same: Persons.tml. Here is the matching tml file for the class above;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">html</span><span style="color: #000000;"> </span><span style="color: #7f007f;">t:type</span><span style="color: #000000;">=</span>&#8220;layout&#8221;<span style="color: #000000;"> </span><span style="color: #7f007f;">title</span><span style="color: #000000;">=</span>&#8220;Peoples I Might Know&#8221;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #7f007f;"><span style="color: #000000;"> </span>t:sidebarTitle<span style="color: #000000;">=</span><span style="color: #2a00ff;">&#8220;Current Time&#8221;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #000000;"> </span><span style="color: #7f007f;">xmlns:t</span><span style="color: #000000;">=</span>&#8220;http://tapestry.apache.org/schema/tapestry_5_1_0.xsd&#8221;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #000000;"> </span><span style="color: #7f007f;">xmlns:p</span><span style="color: #000000;">=</span>&#8220;tapestry:parameter&#8221;<span style="color: #008080;">&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #3f5fbf;">&lt;!&#8211; Most of the page content, including &lt;head&gt;, &lt;body&gt;, etc. tags, comes from Layout.tml &#8211;&gt;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; min-height: 14.0px;">
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; min-height: 14.0px;">
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">t:form</span><span style="color: #000000;"> </span><span style="color: #7f007f;">t:id</span><span style="color: #000000;">=</span>&#8220;search&#8221;<span style="color: #008080;">&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #000000;"> </span><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">t:textfield</span><span style="color: #000000;"> </span><span style="color: #7f007f;">t:id</span><span style="color: #000000;">=</span>&#8220;searchTerm&#8221;<span style="color: #000000;"> </span><span style="color: #7f007f;">validate</span><span style="color: #000000;">=</span>&#8220;required&#8221;<span style="color: #000000;"> </span><span style="color: #7f007f;">size</span><span style="color: #000000;">=</span>&#8220;20&#8243;<span style="color: #008080;">/&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #000000;"> </span><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">t:submit</span><span style="color: #000000;"> </span><span style="color: #7f007f;">t:id</span><span style="color: #000000;">=</span>&#8220;searchPeople&#8221;<span style="color: #000000;"> </span><span style="color: #7f007f;">value</span><span style="color: #000000;">=</span>&#8220;search&#8221;<span style="color: #008080;">/&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #3f7f7f;"><span style="color: #008080;">&lt;/</span>t:form<span style="color: #008080;">&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; min-height: 14.0px;">
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">t:grid</span><span style="color: #000000;"> </span><span style="color: #7f007f;">source</span><span style="color: #000000;">=</span>&#8220;persons&#8221;<span style="color: #008080;">/&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; min-height: 14.0px;">
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">t:form</span><span style="color: #000000;"> </span><span style="color: #7f007f;">t:id</span><span style="color: #000000;">=</span>&#8220;clear&#8221;<span style="color: #008080;">&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #000000;"> </span><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">t:submit</span><span style="color: #000000;"> </span><span style="color: #7f007f;">t:id</span><span style="color: #000000;">=</span>&#8220;clearPeople&#8221;<span style="color: #000000;"> </span><span style="color: #7f007f;">value</span><span style="color: #000000;">=</span>&#8220;clear&#8221;<span style="color: #008080;">/&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #3f7f7f;"><span style="color: #008080;">&lt;/</span>t:form<span style="color: #008080;">&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; min-height: 14.0px;">
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #3f7f7f;"><span style="color: #008080;">&lt;/</span>html<span style="color: #008080;">&gt;</span></p>
<p>Yes, it&#8217;s that bloody simple. The first form fires the &#8220;onSubmitFromSearch&#8221; method (with a little bit of validation, done in javascript) and the second method clears the list. In-between, there is this <span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">t:grid</span><span style="color: #000000;"> </span><span style="color: #7f007f;">source</span><span style="color: #000000;">=</span>&#8220;persons&#8221;<span style="color: #008080;">/&gt; <span style="color: #000000;">business, which, if the &#8216;persons&#8217; variable in the page class is populated, will show a list of its contents! </span></span></p>
<p>To test our app, we can use the command-line &#8216;mvn clean jetty:run&#8217;. When Jetty has run up, then we can point our browser at the web app: http://localhost:8080/sample-webapp/Persons, and with any luck we will see the following:</p>
<p><a href="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-1.png"><img style="border: 0px initial initial;" title="Initial View" src="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-1-300x171.png" alt="Initial View" width="300" height="171" /></a></p>
<p>Now, by default, Tapestry creates the web app to use the template design as shown above. Of course, you can make it look completely some other way &#8211; or even use a totally different template if you want. The page template is just a component that&#8217;s included.</p>
<p>So if you enter in a search term and click the search button, you&#8217;d expect to see a result like this:</p>
<p><a href="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-2.png"><img class="alignnone size-medium wp-image-452" title="Search Result" src="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-2-300x174.png" alt="Search Result" width="300" height="174" /></a></p>
<p>As you can see, the list is automatically populated with the details returned from the service method (in this particular instance, this are just a canned response, but normally of course they&#8217;d be the result of a database or a web service call of some type).</p>
<p>When you click the clear button, the list is cleared as you&#8217;d expect:</p>
<p><a href="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-3.png"><img class="alignnone size-medium wp-image-453" title="Clear button result" src="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-3-300x175.png" alt="Clear button result" width="300" height="175" /></a></p>
<p>Now, here&#8217;s a really powerful feature I find in Tapestry. Let&#8217;s say our automated acceptance tests assert that when the &#8216;Clear&#8217; button is pressed, the Search box as well as the persons list is cleared. What Tapestry allows us to to do, is keep Jetty running, edit the files in the IDE, and re-run the tests against the running app without restarting! We edit our method:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    <span style="color: #003399;">Object</span> onSubmitFromClear<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        persons <span style="color: #339933;">=</span> <span style="color: #003399;">Collections</span>.<span style="color: #006633;">EMPTY_LIST</span><span style="color: #339933;">;</span>
        searchTerm<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>In this case I&#8217;ve also added a bit of space around the clear button in the template as well:</p>
<p><a href="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-4.png"><img class="alignnone size-medium wp-image-454" title="Picture 4" src="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-4-300x175.png" alt="Picture 4" width="300" height="175" /></a></p>
<p>And now our failing test will pass.</p>
<p>Editing files like this in the running web app only works for Pages and I think Components. If I had to change the service or model classes I&#8217;d have to restart, but &#8220;mvn jetty:run&#8221; isn&#8217;t very a heavyweight process.</p>
<p>As I said above, Tapestry&#8217;s not perfect: it&#8217;s major flaw is the poor documentation. Convention-over-configuration is easy to grok &#8211; if you know the convention. If you don&#8217;t and the documentation doesn&#8217;t tell you, and you can&#8217;t find a sample of what you need, it can be very frustrating. There is an excellent user list though.</p>
<p>Its other major flaw may be the stability of the API. Tapestry 5 is different (and incompatible) from Tapestry 4 is different from Tapestry 3. But so far I&#8217;ve used it on a couple of projects and I&#8217;m really enjoying it. I really hate the oodles of XML boilerplate and massive amounts of configuration found in Spring and I find myself somewhat reluctant to use it unless I really have to. Tapestry solves for me a range of different problems and mostly it presents a very elegant way to create a componentised web application. You might like to give it a try.</p>
<p>Attached is the sample code used above. It took me about 10 minutes to write (far shorter than it took me to write this blog entry!) - <a href="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/sample-webapp.tar.gz">sample-webapp.tar bundle</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2009/08/26/tapestry-5-web-framework/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Google Wave is coming &#8230;</title>
		<link>http://www.crazymcphee.net/x/2009/05/30/google-wave-is-coming/</link>
		<comments>http://www.crazymcphee.net/x/2009/05/30/google-wave-is-coming/#comments</comments>
		<pubDate>Sat, 30 May 2009 05:45:40 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[infrastructure and frameworks]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=377</guid>
		<description><![CDATA[I don&#8217;t normally just blog technologies, but this is so incredible you have to see it, if you haven&#8217;t already. If you want to see the future of both email and social networks, check out Google Wave. It&#8217;s described as: &#8230; a product that helps users communicate and collaborate on the web. A &#8220;wave&#8221; is [...]]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t normally just blog technologies, but this is so incredible you have to see it, if you haven&#8217;t already. If you want to see the future of both email and social networks, check out <a href="http://wave.google.com/">Google Wave</a>. It&#8217;s <a href="http://code.google.com/apis/wave/">described</a> as:</p>
<blockquote><p>&#8230; a product that helps users communicate and collaborate on the web.  A &#8220;wave&#8221; is equal parts conversation and document, where users can almost  instantly communicate and work together with richly formatted text, photos, videos,  maps, and more. Google Wave is also a platform with a rich set of open APIs that allow  developers to embed waves in other web services and to build extensions that work  inside waves.</p></blockquote>
<p>In the video from Google IO that I embed below, it&#8217;s described as &#8216;email if it would have been invented now&#8217; instead of 50 years ago. It&#8217;s hard to put the experience into words: it&#8217;s like threaded email, a bulletin board or forum, and social networking sites like Facebook or Twitter. Although it is only in developer preview, there are several APIs and an open-source protocol to facilitate Wave servers and clients not necessarily run by Google itself.</p>
<p>The only downside: Google is concentrating on adding sandbox accounts to the developer preview mostly for the people who were lucky enough to be at Google IO, which is a pity. Apart from the general site and the Google Code site linked above, there is also a <a href="http://googlewavedev.blogspot.com/2009/05/introducing-google-wave-apis-what-can.html">blog</a> and a <a href="http://twitter.com/Wave_Google">twitter</a> account (not sure if this last one is official but it looks like it is, not other dodgy links or anything). <strong>Update</strong>: also here&#8217;s the <a href="http://www.waveprotocol.org/draft-protocol-spec">draft protocol specification</a>, the <a href="http://groups.google.com/group/wave-protocol">protocol mailing list</a> and the <a href="http://groups.google.com/group/google-wave-api">API mailing list</a>.</p>
<p>Anyway I think it&#8217;s a big, big, huge, game-changer in all sorts of internet and web-enabled interface areas (not just email + bbs + social media, it does things like wiki, version control, document production, bug tracking, concurrent editing, etc). Maybe even remote pair programming with real-time collaboration. It&#8217;s the sort of thing that could kill <em>MS Office</em>, not just email or social networks.. It&#8217;s also been built with Google Web Toolkit and runs on devices like the iPhone <em>through the browser</em>. No iPhone app necessary.</p>
<p>Video embedded below; it&#8217;s very long (1hr 20min) but worth it.</p>
<p><object width="560" height="340" data="http://www.youtube.com/v/v_UyVmITiYQ&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/v_UyVmITiYQ&amp;hl=en&amp;fs=1" /><param name="allowfullscreen" value="true" /></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2009/05/30/google-wave-is-coming/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

