<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Timothy Perrett's Blog</title>
 <link href="http://timperrett.com/atom.xml" rel="self"/>
 <link href="http://timperrett.com"/>
 <updated>2012-05-18T18:30:44+01:00</updated>
 <id>http://timperrett.com</id>
 <author>
   <name>Timothy Perrett</name>
   <email>timothy@getintheloop.eu</email>
 </author>

 
 <entry>
   <title>An introduction to simpler concurrency abstractions</title>
   <link href="http://timperrett.com/2012/04/27/introduction-to-simpler-concurrency-abstractions"/>
   <updated>2012-04-27T10:00:00+01:00</updated>
   <id>hhttp://timperrett.com/2012/04/27/introduction-to-simpler-concurrency-abstractions</id>
   <content type="html">&lt;p&gt;No matter what programming language you use to create &amp;#8221;&amp;#8221;the next big thing™&amp;#8221;, when it comes to running your code, there will – eventually – be a &lt;a href='http://en.wikipedia.org/wiki/Thread_(computing'&gt;thread&lt;/a&gt;) that has to execute and compute the result of your program. You may be wondering why you should even care about this threading lark? Well, modern computing hardware is typically not sporting faster clock speeds, but instead features multiple cores, or physical processors. If you have a single threaded program, then you cannot make use of the abundant power that modern hardware makes available; surplus cores simply sit idle and unused. For desktop computers this is less of an issue, but for server based applications, having wasted resources that you already paid for is quite an issue.&lt;/p&gt;

&lt;p&gt;A common scenario that you are likely familiar with – either implicitly or explicitly – is for your program to run on a single thread. In this situation the program executes &lt;a href='http://en.wikipedia.org/wiki/Imperative_programming'&gt;imperatively&lt;/a&gt;. For readers familiar with C or a scripting language like PHP or Ruby, this generally means the code runs top to bottom. Consider this trivial example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// create a variable
var foo = 0

// loop and increment the var with each iteration
def doSomething = 
  for(i &amp;lt;- 1 to 10){ 
    foo += 1 
  }

// check the value of foo
foo 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This kind of code, irrespective of the exact syntax, should be familiar to anyone who&amp;#8217;s ever used a mainstream programming language. When this program is run with a single thread, the result will, as one might expect, be an integer value of 10. Seemingly straightforward.&lt;/p&gt;

&lt;p&gt;Now, reconsider what would happen if you ran this same program on two concurrently executing threads that shared the same memory space. If you&amp;#8217;ve never done any multi-threaded programming, the answer to this question may not be obvious: as each thread runs its own counting loop, both thread A and thread B will be setting the value of the &lt;code&gt;foo&lt;/code&gt; variable. This will have some wacky side-effects in that one thread will constantly be pulling the rug out from under the others feet. This is not constructive for either thread.&lt;/p&gt;

&lt;p&gt;This rather unfortunate scenario has several &amp;#8220;solutions&amp;#8221; that are found in the majority of mainstream programming languages: one of these solutions is known as &lt;a href='http://en.wikipedia.org/wiki/Synchronization_(computer_science'&gt;synchronisation&lt;/a&gt;). As you might have guessed from the name, the two concurrently executing threads are synchronised so that only one thread updates the &lt;code&gt;foo&lt;/code&gt; variable at a time. In various programming languages, &lt;a href='http://en.wikipedia.org/wiki/Lock_(computer_science'&gt;locks&lt;/a&gt;) are often used as a synchronisation mechanism (along with derivatives like &lt;a href='http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Semaphore.html'&gt;Semaphores&lt;/a&gt; and &lt;a href='http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReentrantLock.html'&gt;Reentrant Locks&lt;/a&gt;). Whilst this article isn&amp;#8217;t long enough to go into the details of all these things (and its a deep subject!), the general concept is that when a thread needs a shared resource, it locks it for its exclusive use whilst it does its business. For all the while thread A is locking, thread B (or indeed, thread &lt;em&gt;n&lt;/em&gt;) is &amp;#8220;blocked&amp;#8221;, that is to say thread B is waiting on thread A and cannot do any work during that time. This gets awkward. Quickly.&lt;/p&gt;

&lt;p&gt;Hopefully this gives you a high-level appreciation for the issues associated in writing concurrent software. Even in a small application, concurrent operations could quickly become a practical nightmare (and often do), let alone in a large-scale distributed application that has both inter-process and inter-machine concurrency concerns. Writing software that makes effective and correct use of these traditional concurrency tools is very, very tricky.&lt;/p&gt;

&lt;h2 id='time_for_a_rethink'&gt;Time for a re-think.&lt;/h2&gt;

&lt;p&gt;As it turns out, some &lt;a href='http://en.wikipedia.org/wiki/Carl_Hewitt'&gt;clever folks&lt;/a&gt; realised back in the mid-sixties that manual threading and locking was a poor level of abstraction for writing concurrent software, and with that, invented the &lt;a href='http://en.wikipedia.org/wiki/Actor_model'&gt;actor model&lt;/a&gt;. Actors essentially allow the developer to reason about concurrent operations without the need for explicit locking or thread management. In fact, Actors were largely popularised by the &lt;a href='http://www.erlang.org/'&gt;Erlang&lt;/a&gt; programming language in the mid-eighties, where Erlang actors allowed telecoms companies such as Ericsson to build highly fault-tolerant, concurrent systems, that achieve extreme levels of availability – famously achieving &amp;#8220;nine nines&amp;#8221;: 99.9999999% annual uptime. In fact, Erlang is still highly popular in the TelCo sector even today, and many of your phone calls, SMS and &lt;a href='https://www.facebook.com/note.php?note_id=51412338919&amp;amp;id=9445547199'&gt;Facebook chat IMs&lt;/a&gt; all use Erlang actors as they wind their way across the interweb.&lt;/p&gt;

&lt;p&gt;So what &lt;em&gt;is&lt;/em&gt; the actor model? Well, primarily actors are a mechanism for encapsulating both state and behaviour into a single, consolidated item. Each actor within an application can only see its own state, and the only way to communicate with other actors is to send immutable &amp;#8220;messages&amp;#8221;. Unlike the earlier example in the introduction that involved shared state (the &lt;code&gt;foo&lt;/code&gt; variable), and resulted in blocking synchronisation between threads, actors are inherently non-blocking. They are free to send messages to other actors asynchronously and continue working on something else - each actor is entirely independent.&lt;/p&gt;

&lt;p&gt;In terms of the underlying actor implementation, actors have what is known as a &amp;#8220;mailbox&amp;#8221;. In the same way that a postman places letters through a physical mailbox, those letters collect on top of each other one by one, with the oldest letter received being at the bottom of the pile. Actors operate a similar mechanism: when an actor instance receives a message in its mailbox, if its not doing anything else it will action the message, but if its currently busy, the message just sits there until the actor gets to it. Likewise, if an actor has no messages in its mailbox, it will consume a very small amount of system resources, and won&amp;#8217;t block any applications threads: these qualities make actors a much easier abstraction to deal with and lend themselves to writing concurrent (and often distributed) software.&lt;/p&gt;

&lt;h2 id='actors_by_example'&gt;Actors by example&lt;/h2&gt;

&lt;p&gt;Enough chatter, let&amp;#8217;s look at an example of using actors. The samples below make use of a toolkit called &lt;a href='http://akka.io/'&gt;Akka&lt;/a&gt;, which is an actor and concurrency toolkit for both &lt;a href='http://scala-lang.org'&gt;Scala&lt;/a&gt;, and the wider polyglot JVM ecosystem. I&amp;#8217;ll be using Scala here, which is a hybrid-functional programming language. In short that means that values are immutable, and applications are typically constructed from small building blocks (functions). Scala also sports a range of language features that allow for concise, accurate programming not available in other languages. However, the principals of these samples can be easily replicated both in imperative languages like C# or Java, and also in languages such as Erlang.&lt;/p&gt;

&lt;p&gt;The most basic actor implementation one could make with Akka would look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import akka.actor._

class MyActor extends Actor {
  def receive = {
    case i: Int =&gt; println(&quot;received an integer!&quot;)
    case _      =&gt; println(&quot;received unknown message&quot;)
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This receive method (technically a &lt;a href='http://suereth.blogspot.co.uk/2008/11/using-partial-functions-and-pattern.html'&gt;partial function&lt;/a&gt;) defines the actors behaviour. That is to say, the actions the actor will take upon receipt of different messages. With the receiving behaviour defined, lets send this actor a message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import akka.actor._

// boot the actor system
val system = ActorSystem(&quot;MySystem&quot;)
val sample = system.actorOf(Props[MyActor])

// send the actor message asynchronously 
sample ! 1234

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Besides the bootstrapping, the &lt;code&gt;!&lt;/code&gt; method (called &amp;#8220;bang&amp;#8221;) is used to indicate a fire and forget (async) message send to &lt;code&gt;sample&lt;/code&gt; actor instance, which, as you saw from the earlier code listing will output a message to the console. Clearly there are more interesting things to do than print messages to the console window, but you get the idea. At no point did the developer have to specify any concrete details about threading, locking or other finite details. Akka allows you fine control over thread allocation if you want it, but relatively default settings will see you through to about 20 million messages a second, with Akka being able to reach &lt;a href='http://letitcrash.com/post/20397701710/50-million-messages-per-second-on-a-single-machine'&gt;50 million messages a second&lt;/a&gt; with some light configuration. This is staggering performance for a single commodity server. With all that being said, this example is of course very trivial, so lets talk about what else actors (and Akka) can do…&lt;/p&gt;

&lt;p&gt;It turns out that the conceptual model of actors is a very convenient fit for a range of problems commonly found in business, and Akka ships with a range of tools that make solving these problems in a robust, and correct way nice and simple. Whilst this blog post is too short to talk about all of Akka&amp;#8217;s features, one that is no doubt of interest to most readers is fault tolerance.&lt;/p&gt;

&lt;h2 id='supervisor_hierarchies'&gt;Supervisor Hierarchies&lt;/h2&gt;

&lt;p&gt;Think about the way many people write programs: how many times have you written a call to an external system, or to the database, and just assumed that it would work? Such practices are widespread, and Akka is entirely based around the opposite idea: failure is embraced, and assumed to happen. With this frame of reference one can design systems that can recover from general faults gracefully, rather than having no sensible provision for error. One of the main strategies for providing such functionality is something known as &lt;a href='http://www.erlang.org/doc/design_principles/sup_princ.html#5'&gt;Supervisor Hierarchies&lt;/a&gt;. As the name suggests, actors can be &amp;#8220;supervised&amp;#8221; by another actor that takes action in the case of failure. There are a couple of different strategies in Akka that facilitate this structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;All for one&lt;/strong&gt;: If the supervisor is monitoring several actors, all of those actors under the supervisor are restarted in the event that &lt;em&gt;one&lt;/em&gt; has a failure.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;One for one&lt;/strong&gt;: If the supervisor is monitoring multiple actors, when one actor has a failure, it will be restarted in isolation, and the other actors will be unawares that the failure occurred.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simple enough. Let&amp;#8217;s see supervision in action:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import akka.actor.Actor

class Example extends Actor {
  import akka.actor.OneForOneStrategy
  import akka.actor.SupervisorStrategy._
  import akka.util.duration._ 
  
  override val supervisorStrategy = OneForOneStrategy(
    maxNrOfRetries = 10, withinTimeRange = 1 minute){
      case _: NullPointerException =&gt; Resume
      case _: Exception =&gt; Restart
    }
  
  def receive = {
    case msg =&gt; ....
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see from the listing that the structure of the actor is exactly the same as the trivial example earlier – its just augmented with a customisation of the &lt;code&gt;supervisionStratagy&lt;/code&gt;. This customisation allows you to specify different behaviour upon different errors arising. This is exceedingly convenient, and very easy to implement.&lt;/p&gt;

&lt;h2 id='conclusion'&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;The actor model is a simple abstraction that facilities easier development of robust, concurrent software. This article only scratches the surface of what&amp;#8217;s available, but there is a lot of cutting edge work being done right now in the area of concurrency and distributed systems. If this article has peaked your interest, there has never been a better time to get your hands dirty and try something new!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>HTML5 Event Sources with Scala Spray</title>
   <link href="http://timperrett.com/2012/03/17/html5-sse-with-scala-spray"/>
   <updated>2012-03-17T10:00:00+00:00</updated>
   <id>hhttp://timperrett.com/2012/03/17/html5-sse-with-scala-spray</id>
   <content type="html">&lt;p&gt;With the onset of HTML5 modern browsers (read: everyone but IE) implemented the W3C&amp;#8217;s &lt;a href='http://dev.w3.org/html5/eventsource/'&gt;Server-Sent Events&lt;/a&gt; feature. This essentially allows you to push events from server to client without any additional hacks like &lt;a href='http://en.wikipedia.org/wiki/Push_technology#Long_polling'&gt;long polling&lt;/a&gt;, or additional protocols like &lt;a href='http://dev.w3.org/html5/websockets/'&gt;Web Sockets&lt;/a&gt;. This is exceedingly neat as it allows you to do stream-events with a very tiny API and minimal effort on that part of the developer.&lt;/p&gt;

&lt;p&gt;Recently i&amp;#8217;ve been doing a fair bit with the &lt;a href='https://github.com/spray/spray'&gt;Scala Spray&lt;/a&gt; toolkit when building HTTP services, so I thought i&amp;#8217;d take it for a spin and see how trivial it would be to implement SSE. Turns out it was pretty simple. Here&amp;#8217;s a demo:&lt;/p&gt;
&lt;embed src='http://blip.tv/play/AYLv%2BG8A?p=1' height='320' allowscriptaccess='always' width='100%' wmode='transparent' type='application/x-shockwave-flash' allowfullscreen='true' /&gt;
&lt;p&gt;As mentioned in the demo video, most of the SSE tutorials you&amp;#8217;ll find online don&amp;#8217;t talk about streaming events, they just talk about having an event source HTTP resource for which the browser will consume events. The massive omission here is that if the server just closes the connection like any regular request, then you essentially have to wait for the &lt;code&gt;retry&lt;/code&gt; period to pass before the browser will then automatically reconnect. This is not really that great as it just gives you a more convenient API for polling (how 90s!). On the one hand, if you have a low volume of events, or a bit of lag between updates doesn&amp;#8217;t hurt then it may not be an issue, but in the main i&amp;#8217;d imagine that most people wanting a stream of events would want exactly that, a &lt;em&gt;stream&lt;/em&gt;. This is achieved by using chunking the response server side, and the content flushed to the client with the SSE&amp;#8217;s mandatory &amp;#8220;data:&amp;#8221; prefix will then be operated on, giving you a handy stream of data. Of course, you&amp;#8217;ll have to close that connection at some point, but if you set the retry latency to a low value then you&amp;#8217;ll just move from stream to stream with very little lag (as per the example video).&lt;/p&gt;

&lt;p&gt;In the broad sense, this kind of approach is useful in a wide set of circumstances to improve the user experience. I&amp;#8217;ve rambled on about this &lt;a href='http://vimeo.com/28769180'&gt;before&lt;/a&gt;, but now with SSE there is a generic way of achieving it without needing a framework or platform that explicitly makes comet-style programming easy: its broadly accessible for all toolkits.&lt;/p&gt;

&lt;p&gt;The code for the example application I demoed in the video can be found &lt;a href='https://github.com/timperrett/spray-html5-sse'&gt;on github&lt;/a&gt;. Enjoy.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Using dust.js with Scala SBT</title>
   <link href="http://timperrett.com/2011/12/26/using-dust-js-with-scala-sbt"/>
   <updated>2011-12-26T19:54:59+00:00</updated>
   <id>hhttp://timperrett.com/2011/12/26/using-dust-js-with-scala-sbt</id>
   <content type="html">&lt;p&gt;If you&amp;#8217;ve been living under a rock for the past few weeks you might have missed LinkedIn &lt;a href='http://engineering.linkedin.com/frontend/leaving-jsps-dust-moving-linkedin-dustjs-client-side-templates'&gt;bloging&lt;/a&gt; about their usage of &lt;a href='http://akdubya.github.com/dustjs'&gt;dust.js&lt;/a&gt;. This idea of client-side templating is certainly a very interesting one, and something that is in all likelihood very useful for many large-scale applications currently in production. dust.js is quite nice in that it has no dependencies on any javascript library such as JQuery or YUI. This is really rather handy is it means no prescription on your style of implementation.&lt;/p&gt;

&lt;p&gt;However, whilst the dust.js documentation has a wide range of examples demonstrating how to use the templating engine, what it does not have is any examples of how one might actually wrap it up and use it. So, with that I wanted to just write up a quick post to explain some of the things that might not be immediately obvious. Before getting to the meat of the article, it&amp;#8217;s worth bearing in mind some terminology:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Template&lt;/strong&gt;: The source dust.js template&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Compiled template&lt;/strong&gt;: A pre-compiled version of the template; essentially some generated JavaScript that is created at build-time (it&amp;#8217;s also possible to create the JavaScript at runtime, but this is heavily discouraged)&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Context&lt;/strong&gt;: Each template can only be rendered with a context. More regularly we can think of this as the data that populates the template variables&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, the developers writes a source template which is then compiled to JavaScript at build time and then rendered at runtime with a given context; which is likely a dynamic JSON payload.&lt;/p&gt;

&lt;p&gt;When I first go going with dust.js I was unsure how to handle this build-time compilation. Frankly, the support for everything that isn&amp;#8217;t JavaScript or &lt;a href='http://nodejs.org/'&gt;Node&lt;/a&gt; was (and is still mostly) non-existent. This was problematic as I certainly didn&amp;#8217;t want to be compiling templates on each and every request for a given HTML page. With that, I set about writing an &lt;a href='https://github.com/timperrett/sbt-dustjs'&gt;SBT plugin for dust.js template compilation&lt;/a&gt;. This then allows you to have SBT build the dust.js templates into JavaScript that you can simply reference directly from your HTML (more on this later). The plugin itself takes templates it finds in &lt;code&gt;src/main/dust&lt;/code&gt; and compiles them to the resource managed target whenever you invoke the &lt;code&gt;dust&lt;/code&gt; task from the SBT shell. It&amp;#8217;s also super easy to redirect the compilation output to the webapp directory during development so that you can simply use the local Jetty server to tryout your app:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(resourceManaged in (Compile, DustKeys.dust)) &amp;lt;&amp;lt;= (
      sourceDirectory in Compile){
    _ / &amp;quot;webapp&amp;quot; / &amp;quot;js&amp;quot; / &amp;quot;view&amp;quot;
}  &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But I digress. For more information about the plugin, see it&amp;#8217;s &lt;a href='https://github.com/timperrett/sbt-dustjs'&gt;README file in the github repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After making my own tooling for SBT to work with dust.js, I then got to thinking about how one would actually wrap the dust.js rendering system. Curiously, the examples I found online suggest making an AJAX call to fetch the context, or template data. This strikes me as quite sub-optimal as it would mean creating the following requests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fetching the general html for the page in the first instance&lt;/li&gt;

&lt;li&gt;another request for the dust.js runtime&lt;/li&gt;

&lt;li&gt;another request for the dust template&lt;/li&gt;

&lt;li&gt;and then another for the context data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All that, just to render one template and add unnecessary lag to the page load whilst the ancillary request for context data takes place (after the initial page load has already completed!). For general page rendering, this seems somewhat bizarre. That is to say, requesting context data via AJAX for say, a single page application could well be a reasonable use-case, but for general pages that render &amp;#8220;in full&amp;#8221;, it seems silly.&lt;/p&gt;

&lt;p&gt;Assuming you&amp;#8217;re just rendering regular page content, we can make the separation between things one would want to load and cache locally in the browser, and things that need to be dynamic. For the most part, the context is the only thing you&amp;#8217;d want to be dynamic and the more general plumbing code for rendering would probably be reusable throughout your rendering call sites. Consider a simple sample:&lt;/p&gt;

&lt;p&gt;The dust template (lets call it home.dust in src/main/dust):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div&amp;gt;
  &amp;lt;h2&amp;gt;Hey {name}&amp;lt;/h2&amp;gt;
&amp;lt;/div&amp;gt;  &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This template will then be compiled to home.js and placed in the resource managed output location (as per your build config). The other thing to probably think about is if had several pre-compiled template files needed on a given page it would make sense to merge and minify them into a single JS file. Alternatively, if you were building a single-page application it might be nice to use a client-side loading framework like &lt;a href='http://labjs.com/'&gt;LABjs&lt;/a&gt; to pull in the template files lazily (i.e. as you needed them). Getting back tot eh example, and considering the aforementioned, lets assume a HTML page that loads the DOM skeleton and the static libraries needed for rendering:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Strict//EN&amp;quot;
  &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&amp;quot;&amp;gt;
&amp;lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot; xml:lang=&amp;quot;en&amp;quot; lang=&amp;quot;en&amp;quot;&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot;/&amp;gt;
  &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;js/dust.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;js/view/home.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;h1&amp;gt;Home&amp;lt;/h1&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, as it stands this page would display the heading &amp;#8220;Home&amp;#8221; and load the dust library along with the compiled template; otherwise it is essentially static. In order to render the dust template one would have to add something like the following to the page &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
//&amp;lt;![CDATA[
dust.render(&amp;quot;home&amp;quot;, { name: &amp;quot;Fred&amp;quot; }, function(err, out) {
  document.getElementById(&amp;#39;whatever&amp;#39;).innerHTML = out;
});
//]]&amp;gt;
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This simple bit of JS would render the content into the element with the &amp;#8220;whatever&amp;#8221; ID attribute. Now then, this will work, and prove the concept for sure. What it does not do however is provide a dynamic context, which almost certainly most users would want to do. In this way, I can see why people might see that it made sense to make an AJAX request to a pure JSON backend service to get the context dynamically, but as above, this would be a bit slow and cumbersome. Instead, I think it would probably make more sense to dynamically deliver a call to a rendering function with the desired context. Let&amp;#8217;s qualify that: when the page loads, the template has been loaded and so has the dust library, so all that is actually required is have a call site that starts the rendering. I think this need can quite nicely be served by a server-side helper function. In essence, when the page is loaded, the server generates a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag. Here&amp;#8217;s an example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;body&amp;gt;
  ...
  &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/view/home&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which in turn would deliver something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;draw(&amp;quot;home&amp;quot;, { name: &amp;quot;Whatever&amp;quot; });&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That is, where the &lt;code&gt;draw&lt;/code&gt; function wraps the dust rendering system. This is just an example though as the point is that this could be any kind of JavaScript. For instance, it could be a backbone.js view or something along those lines: you deliver the rendering code along with the context. This at least seems more optimal than making a fuckton of JavaScript requests for context objects as other blogs suggest.&lt;/p&gt;

&lt;p&gt;In the next post i&amp;#8217;ll be showing you how to combine all the latest hipster web programming tools like &lt;a href='http://akdubya.github.com/dustjs/'&gt;dust.js&lt;/a&gt;, &lt;a href='http://coffeescript.org/'&gt;CoffeeScript&lt;/a&gt; and &lt;a href='http://lesscss.org/'&gt;Less&lt;/a&gt; with a Scala backend using &lt;a href='http://unfiltered.databinder.net/'&gt;Unfiltered&lt;/a&gt; to deliver the dynamic template contexts.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Year in Photos, 2011</title>
   <link href="http://timperrett.com/2011/12/17/the-year-in-photos-2011"/>
   <updated>2011-12-17T20:55:19+00:00</updated>
   <id>hhttp://timperrett.com/2011/12/17/the-year-in-photos-2011</id>
   <content type="html">&lt;p&gt;&lt;em&gt;This is a fairly personal post, so i&amp;#8217;m sorry if you are a regular reader of the Scala articles here - those will resume from the next post!&lt;/em&gt;&lt;/p&gt;

&lt;h3 id='the_years_events'&gt;The Years Events&lt;/h3&gt;

&lt;p&gt;As is becoming customary, I like to try and review the year nearly past as we look forward to the delights of the next. This blog is the second in a yearly series to make a conscious effort to note what the year was made up of and recall those awesome memories made.&lt;/p&gt;

&lt;h3 id='alpe_dhuez_france'&gt;Alpe d&amp;#8217;huez, France&lt;/h3&gt;

&lt;p&gt;Most years I try to get some skiing in with friends, and this year we&amp;#8217;d decided to go to France rather than my beloved Italy. Whilst the snow could have been better, we had a great time. I took this picture at the top of the highest gondola lift…&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2011/12/1c.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='bathoniean_sunsets'&gt;Bathoniean Sunsets&lt;/h3&gt;

&lt;p&gt;I&amp;#8217;m fortunate to live in a beautiful area of the UK, and spring time is quite idyllic here. As the winter thaw gives way to things growing and spouting, the sun once again starts to bathe the evenings with glorious sunsets. This is one such evening looking out over the garden.&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2011/12/2.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='qconn_london_scala_community_dinner'&gt;QConn London, Scala Community Dinner&lt;/h3&gt;

&lt;p&gt;March saw QConn return to London for a whole week and bring with it a heard of geeks from all over the globe. Many of my friends were visiting for the conference and with that decided that it would be a good idea to get the Scala folks together for some food, wine and all-round good times. Having people like &lt;a href='twitter.com/jstrachan'&gt;James&lt;/a&gt; and &lt;a href='twitter.com/debasishg'&gt;Debasish&lt;/a&gt; was awesome fun. Can&amp;#8217;t wait to do something similar next year during Scala days. James, we&amp;#8217;re still waiting for &amp;#8220;scala minus minus&amp;#8221; ;-)&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2011/12/3.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='california_route_1_pacific_highway'&gt;California Route 1: Pacific Highway&lt;/h3&gt;

&lt;p&gt;For anyone who&amp;#8217;s been reading this blog over the past years, you may recall that last year I was stranded in mainland Europe during the volcano eruption whilst attending ScalaDays 2010. After rounding up a bunch of stranded folks for dinner, I ended up meeting &lt;a href='http://twitter.com/jteigen'&gt;Jon-Anders&lt;/a&gt; - making a long story short, we became good friends and one day decided that what we should do is drive the length of the pacific highway in a convertible Mustang. After a hastily organised flight to america we were all set. What ensued was an utterly hilarious time away where we had arranged nothing in advance and just took things as they came. From huge trees in Redwood country…&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2011/12/4a.jpg' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;&amp;#8230;to the winding roads and stunning coastline of BigSur and southern california:&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2011/12/4f.jpg' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;The trip was a complete riot and finishing it off with spending time at Xerox PARC was a real high for me. It was literally like walking the halls of technology fame.&lt;/p&gt;

&lt;h3 id='early_summer_thistles'&gt;Early Summer Thistles&lt;/h3&gt;

&lt;p&gt;Getting back from Cali was somewhat of a come down, but I often go for hikes in and around where I live and was out one day and noticed a small set of thistles just growing on this open exposed hill face. Pretty nice, especially with the city backdrop.&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2011/12/5.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='canada_upstate_new_york_and_niagara_falls'&gt;Canada, Up-state New York and Niagara Falls.&lt;/h3&gt;

&lt;p&gt;In summer I was sent to Canada for a meeting (technically just across the boarder in Upstate New York) but this was a pretty awesome experience. Having booked a &amp;#8220;Small European Saloon Car&amp;#8221; before traveling, me and my colleague were surprised to be presented with a 4.0 litre land cruiser. Clearly &amp;#8220;small&amp;#8221; has some definition in Canada that i&amp;#8217;m not familiar with. Anyway… it was fun to drive around in a &lt;del&gt;tank&lt;/del&gt; truck for a few days and enjoy the delights of Toronto and New York scenery:&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2011/12/6b.jpg' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2011/12/6.jpg' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;Of course, being in the area it only made sense to swing by Niagara falls on the way back to the airport. It was my first time here and damn, it&amp;#8217;s far, far bigger than you might imagine. It really is a stunning natural spectacle.&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2011/12/niagra.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='end_of_summer_harvest_time'&gt;End of Summer: Harvest Time&lt;/h3&gt;

&lt;p&gt;Back in England for the end of the summer is yet another lovely time. The UK was drenched in sunshine for the last few days (weeks?) of August which meant all the farms nearby were busy making the most harvesting their crops and preparing the land for winter. Being out on a walk I picked up this picture just after the field had been harvested:&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2011/12/harvest-time.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='javazone_and_mit_arctic'&gt;JavaZone and M.I.T Arctic&lt;/h3&gt;

&lt;p&gt;Come September it was time once again for the most awesome conference of the yearly calendar: &lt;a href='javazone.no'&gt;JavaZone&lt;/a&gt;! I love this conference; its always well organised, has great talks and really wicked parties. This year was no exception to that rule and proved to again be most excellent. This year we were also joined by some of our &lt;a href='http://twitter.com/rit'&gt;american&lt;/a&gt; &lt;a href='twitter.com/djspiewak'&gt;friends&lt;/a&gt;, which just added to the delight. Following the conference, some of us head north from Oslo to the M.I.T Arctic lab for a few days of geekery and walking in the tundra. This was a really special highlight of the year and felt like a somewhat magical trip for everyone. Here&amp;#8217;s a small sample of what we got up too (not all pictures taken by me, credits where credit appropriate):&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2011/12/8d.jpg' alt='' /&gt; &lt;em&gt;(photo credit: Andreas Røe)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2011/12/mit-cabins.jpg' alt='' /&gt; &lt;em&gt;(photo credit: Andreas Røe)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And don&amp;#8217;t forget the somewhat successful fishing in the fjords!!&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2011/12/IMG_1074.jpg' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;It really was an amazing trip. If you&amp;#8217;ve never visited Norway, you should, its a stunning country.&lt;/p&gt;

&lt;h3 id='lift_in_action_goes_to_production'&gt;Lift in Action goes to production&lt;/h3&gt;

&lt;p&gt;So we&amp;#8217;re nearly at the end of the year, so I should really mention Lift in Action going to print. This was a huge, huge milestone for me personally and concluded a two year unit of work. I should also mention that during the writing of this blog post I had originally neglected to even mention the book and that a friend had to remind me to mention it… I&amp;#8217;m sure the psychologists would have something to say about that, but anyway!&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2011/12/lift-in-action-complete.jpg' alt='' /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Documenting the Difficulties of Documentation</title>
   <link href="http://timperrett.com/2011/12/11/documenting-the-difficulties-of-documentation"/>
   <updated>2011-12-11T20:11:50+00:00</updated>
   <id>hhttp://timperrett.com/2011/12/11/documenting-the-difficulties-of-documentation</id>
   <content type="html">&lt;p&gt;Over the years i&amp;#8217;ve been involved in a wide-range of diverse open source projects. Some large. Some small. Some very obscure. But every single one has at one point or another, had a &amp;#8220;problem&amp;#8221; with documentation. Many of you reading this will no doubt have had a similar experience at some point in your programming career. Perhaps you were a project creator wondering how best to communicate the inherent awesome of something you&amp;#8217;ve just created, or perhaps you were that eager n00b trying to get to grips with some new technology you came across on &lt;a href='https://github.com/'&gt;github&lt;/a&gt; - in either case, you have to create or consume &amp;#8220;documentation&amp;#8221;.&lt;/p&gt;

&lt;p&gt;Now then, before we go any further I do have somewhat of a problem with the overloaded meaning of the term &amp;#8220;documentation&amp;#8221;. The widely accepted definition of documentation is the following:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Doc&amp;#183;u&amp;#183;men&amp;#183;ta&amp;#183;tion&lt;/strong&gt; &lt;em&gt;noun&lt;/em&gt; - Material that provides official information or evidence or that serves as a record.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Evidence that serves as a record? That sounds awfully vague doesn&amp;#8217;t it. I&amp;#8217;d like to suggest that this is, to all intent purposes, &lt;em&gt;too&lt;/em&gt; vague. More specifically it is often an ambiguous umbrella term for what people are actually referring too. It&amp;#8217;s this ambiguity that causes all manner of problems for software projects and their (would-be)users.&lt;/p&gt;

&lt;h3 id='disambiguating_documentation_components'&gt;Disambiguating Documentation Components&lt;/h3&gt;

&lt;p&gt;There are many excellent projects in the Scala ecosystem, and many suffer this apparent &amp;#8220;lack of documentation&amp;#8221;. Curiously though, each project seems to suffer this affliction in its own specific way… at least, this is often what you might witness on the mailing-list of any project you might care to pick at random. Most projects have some thread or other in the archives of their mailing lists where someone has complained about their documentation, or distinct lack of whatever it is they were looking for.&lt;/p&gt;

&lt;p&gt;With this in mind, i&amp;#8217;d like to now illustrate what I think are the key aspects of the wider &amp;#8220;documentation problem&amp;#8221;, and disambiguate their respective intentions.&lt;/p&gt;

&lt;h3 id='tutorials_and_introductions'&gt;Tutorials and Introductions&lt;/h3&gt;

&lt;p&gt;The first thrust of documentation i&amp;#8217;d like to define is that all-important introductory material people will need when coming to your project in the first instance. This is quite probably the most difficult type of text to write, particularly if the subject matter is highly technical in nature. It&amp;#8217;s typically difficult for the following three reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Assumptions&lt;/strong&gt; - Assuming the reader fully understands a topic, line of code, operator or anything else must be one of the most common issues. In introductory texts and tutorials its highly likely that the reader will not be in possession of the implicit knowledge that&amp;#8217;s relevant to properly grok the topic at hand.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Accessibility&lt;/strong&gt; - &amp;#8220;Joe Developer&amp;#8221; can initially be easily scared by large words, complex-sounding terms that originate from academic theories, and terse writing styles. It is so vitally important that your tutorials and introduction texts are &lt;em&gt;accessible&lt;/em&gt;. For the most part this may well mean that you have to sweep over some of the finer details, or forego some more abstract possibilities in order to effectively get the point across to newcomers. Ironically, it is often this simplification or frivolity with the facts that programmers struggle with when taking up the pen (ok - keyboard, but you know what I mean).&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Authorship&lt;/strong&gt; - Writing is hard. Be honest with yourself and recognise that you may not be any good at it. During the writing of Lift in Action I had to throw away a whole bunch of manuscript which was either too technical or just plain rubbish. Having a professional team of editors who could help me (re)learn about writing was really key… but i&amp;#8217;m aware that this is hardly practical for the common case. The fact is that most of us have not written long documents since high-school or college, and it is &lt;em&gt;incredibly difficult&lt;/em&gt;. Don&amp;#8217;t forget this when writing your project introduction and tutorials - if you can&amp;#8217;t do it the proper justice it deserves, then embrace the fact that us humans all have different skills and find someone who can plug the required gaps. Having your texts reviewed honestly by your peers is also another useful strategy to ensure what you&amp;#8217;re writing is actually any good.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='examples_and_explanations'&gt;Examples and Explanations&lt;/h3&gt;

&lt;p&gt;The second branch of the documentation umbrella is somewhat of an extension to the first, but I decided to make it separate because its use-case feels distinctly different. With this in mind i&amp;#8217;ll add the caveat that yes, examples often form parts of tutorials (and later, references), but in and of themselves you wouldn&amp;#8217;t use verbose introductory-style writing &lt;em&gt;within&lt;/em&gt; an example. In my mind at least, the primary difference is that example/explanatory documentation is tightly coupled with the code to which it relates. That is to say that the text is more often than not sitting next to the code itself in the comments, which usually means there are certain conventions to follow with regard to syntax and so forth (e.g. ScalaDoc, Wiki markup etc). Critically though, the tone of voice in the explanatory text when compared to that of the introductory &amp;amp; tutorial manuscripts is much shorter, more concise and really focusing on the line-by-line, blow-by-blow goings on of the code. More generally, its reasonable to suggest that examples are about illustrating concepts, and this is where the writing style really differentiates itself from the other branches listed in this article.&lt;/p&gt;

&lt;p&gt;Finally, if you&amp;#8217;re going to go to the trouble of writing examples and explanations, &lt;em&gt;make sure the code actually works&lt;/em&gt;! Nothing is more frustrating to find an example that simply does not do what it should because the code either doesn&amp;#8217;t compile or doesn&amp;#8217;t run correctly.&lt;/p&gt;

&lt;h3 id='reference_materials'&gt;Reference materials&lt;/h3&gt;

&lt;p&gt;Reference material is your last line of defence before forcing users to delve into the source code. Consider the type of person might be using a reference, or what their goal might be? I&amp;#8217;d propose that when someone is looking at a reference, they know what they are looking for: they need something specific. It&amp;#8217;s probably also fair to assume that before arriving at the reference they will have read tutorials and examples, so there is a degree of implied understanding. Reference materials are usually heavy on details and light on fluffy writing style, which allows the author to be far more technical, and satisfy the aforementioned need for presenting the exact facts.&lt;/p&gt;

&lt;p&gt;Unlike the other aspects of documentation writing, references can have the tendency to become quite large; even for mid-sized projects. With this in mind you should take care to refactor the organisation and layout of the reference with each major change and strives for a reference that is logically ordered and consistent throughout. If your reference is massive, then you should seriously consider having a decent search function in addition to a logical layout.&lt;/p&gt;

&lt;h3 id='source_code'&gt;Source Code&lt;/h3&gt;

&lt;p&gt;Your last line of documentation defence is the source code. That might seem odd, as i&amp;#8217;m not talking about comments or ScalaDoc (or similar in your language of choice). I&amp;#8217;m talking about types (sorry dynamically typed people!). Type annotations can be extremely useful when reading code and concisely communicating the result or intention of a particular item. With Scala for example, consider these two lines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// actual code irrelevant
val foo = whatever.map(...).flatMap(...).foldLeft(...).map(...)
val foo: Option[Int] = whatever.map(...).flatMap(...).foldLeft(...).map(...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Having the simple type annotation frees me from having to mull over the code in order to understand its result; its right there in the type annotation. When moving code between teams, or people, having the ability to simple scan complex blocks of code and understand it is a huge win (IMHO). Sure, make use of type inference where the value is obvious (e.g. simple assignment etc), but where you think something might not be directly understood explicitly annotating can serve as effective documentation.&lt;/p&gt;

&lt;p&gt;&amp;#8230;In any case, writing readable and well documented code could easily be the subject of a whole other blog post (or indeed, &lt;a href='http://infoscience.epfl.ch/record/138586/files/dubochet2009coco.pdf?version=2'&gt;academic paper&lt;/a&gt;), so we&amp;#8217;ll put a pin in that subject and move swiftly along…&lt;/p&gt;

&lt;p&gt;In my mind at least, when your general users complain about documentation, they are typically complaining about one of first three branches of this documentation umbrella.&lt;/p&gt;

&lt;h3 id='isnt_all_this_a_lot_of_work'&gt;Isn&amp;#8217;t all this a lot of work?&lt;/h3&gt;

&lt;p&gt;I won&amp;#8217;t lie to you, good reader: this will take a lot of time and dedication to do. To do it &lt;em&gt;well&lt;/em&gt;, will take more time and a fuckton more effort. However, if you want your software or project to be used by people other than yourself, then it is imperative the documentation is well structured, and exhibiting some - if not most - of the traits in this article. It&amp;#8217;s also important that you realise that it will, in all likelihood, be &amp;#8220;expensive&amp;#8221; in terms of time; this is nearly unavoidable, but it will make your project more approachable and more usable.&lt;/p&gt;

&lt;p&gt;Interestingly one thing that you often see are projects that try to distill the documentation effort by promoting community authorship, which when considering what a social activity programming has become in recent times, does not seem like such a crazy idea. The reality however is somewhat different to the ideal: people are often keen to submit bugs and patches, but those same keen people are still typically reluctant to contribute documentation. One could speculate that writing documentation was too tedious, or that perhaps it was not as fun as doing the coding and people didn&amp;#8217;t want to spend time in that area… the reason is actually irrelevant, as the result is always the same: without a small core of dedicated people who write, maintain and constantly improve that wiki &lt;em&gt;the whole documentation effort will fail&lt;/em&gt;. To qualify that, i&amp;#8217;m not saying that community-powered documentation &lt;em&gt;never&lt;/em&gt; works, as that clearly isn&amp;#8217;t the case. I am however suggesting that by-and-large for most communities it simply does not operate effectively, and this has an overall negative impact on the project as a whole.&lt;/p&gt;

&lt;h3 id='whos_doing_it_right'&gt;Who&amp;#8217;s doing it right?&lt;/h3&gt;

&lt;p&gt;I&amp;#8217;m not going to gratify this article with pointing out projects that are &amp;#8220;doing it wrong&amp;#8221;, as frankly most projects are making a hash of their documentation; irrespective of language or community. I do however want to highlight a couple of projects that are setting an excellent example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Akka&lt;/strong&gt; - The Akka team are making a superb job of documenting their project, even with extensive changes to the codebase they are very effective when it comes to ensuring the docs are up-to-date and covering all new or refactored features. The documentation is nearly exclusively maintained by the core team of programmers.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;strong&gt;JQuery&lt;/strong&gt; - Very different to Akka, and in a different community, JQuery has been very effective in delivering core reference materials that allow (and encourage) the wider community to write tutorials, introductions and other helpful articles. JQuery also makes extensive use of illustrative examples, and its good documentation is probably one of the reasons for its apparent ubiquity on the web today.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both of these projects exhibit dedication on the part of the coders, who are typically the ones authoring the core reference materials and bulk of the ancillary texts. Learn from these projects and others like them. We can all do a better job of documenting our projects, myself included. Say no to undocumented projects, and the next time you&amp;#8217;re throwing something on github, take the time to write some documentation… even if its a long README people will thank you for it.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Lift in Action Finally Completed</title>
   <link href="http://timperrett.com/2011/11/06/lift-in-action-finally-completed"/>
   <updated>2011-11-06T17:10:14+00:00</updated>
   <id>hhttp://timperrett.com/2011/11/06/lift-in-action-finally-completed</id>
   <content type="html">&lt;p&gt;So here we are. The end finally happened. Lift in Action was sent to print last week, representing the conclusion of 20 months of work. Without doubt this has been one of the largest and most difficult projects i&amp;#8217;ve ever undertaken. With this in mind I wanted to thank everyone who read the MEAP edition, contributed fixes, asked questions, issued pull requests and everyone who generally helped me with the project! Without your input the book wouldn&amp;#8217;t be what it is, and I hope that it serves to be a useful reference for learning and making the most of Lift.&lt;/p&gt;

&lt;p&gt;The print copies should be coming out in a week or so and depending where you purchased, your copy should be arriving in the coming weeks.&lt;/p&gt;

&lt;p&gt;Thanks again for all the support and kind words during the writing; i&amp;#8217;m now looking forward to getting my life back! :-D&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Using Apache Shiro with Lift</title>
   <link href="http://timperrett.com/2011/08/23/using-apache-shiro-with-lift"/>
   <updated>2011-08-23T15:42:24+01:00</updated>
   <id>hhttp://timperrett.com/2011/08/23/using-apache-shiro-with-lift</id>
   <content type="html">&lt;p&gt;As it stands, Lift only has its proto* traits for user management, and that system has its limitations and you will ultimately end up replacing it in any non-trivial application as your needs change and you need to grow. Whilst this is what those traits are designed for (quick start, short haul), you typically end up rolling your own system for users etc when using Lift, and this can often be somewhat cumbersome or not particularly easy to do well. As this whole user management piece is so often requested, I figured that i&amp;#8217;d write a plugin library for Lift.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://shiro.apache.org/'&gt;Apache Shiro&lt;/a&gt; is a Java security framework (formally known as JSecurity) and it comes with a fairly abstract set of classes for building systems that have the familiar users, roles and permissions setup. Pretty much most applications these days have some notion of users, customers or some other subject that you care about and might want to conduct access control around. This is exactly what Shiro is designed for, and it ships with out of the box inter-operation with ActiveDirectory and other such repositories commonly found in the enterprise space for managing user data.&lt;/p&gt;

&lt;p&gt;Part of the reason that other security frameworks never really took to Lift (or vice-versa) is that Lift has its own mech for managing resource ACLs and it never made sense to separate that into a different servlet filter and somehow munge that together: its not 1990. Fortunately Shiro was fairly easy to integrate with Lift in such a way that it allows you to simply augment your existing SiteMap setup, template markup and even dispatch resources. Currently this integration project is in early stages, and you can find the source code here: &lt;a href='https://github.com/timperrett/lift-shiro'&gt;github.com/timperrett/lift-shiro&lt;/a&gt;&lt;/p&gt;

&lt;h3 id='example'&gt;Example&lt;/h3&gt;

&lt;p&gt;Here&amp;#8217;s a quick walkthrough of the various ways you can use the integration within your project. Firstly, lets assume you only want to display a section of content to authenticated users:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;lift:has_role name=&amp;quot;admin&amp;quot;&amp;gt;
  &amp;lt;p&amp;gt;This content is only available for admins&amp;lt;/p&amp;gt;
&amp;lt;/lift:has_role&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are a range of authentication snippets that allow you to define who sees what within your templates, checkout the documentation for more on that. Nextup, what if you want to block access to an page entirely if the user is not authenticated? Just add the following to your SiteMap:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;...
Menu(&amp;quot;Home&amp;quot;) / &amp;quot;index&amp;quot; &amp;gt;&amp;gt; RequireAuthentication
...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By default &lt;code&gt;RequireAuthentication&lt;/code&gt; will redirect unauthenticated users back to the URL defined in &lt;code&gt;Shiro.loginURL&lt;/code&gt;. Likewise, you can specify whole resources to require a particular role or permission:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;...
Menu(&amp;quot;Role Test&amp;quot;) / &amp;quot;restricted&amp;quot; &amp;gt;&amp;gt; RequireAuthentication &amp;gt;&amp;gt; HasRole(&amp;quot;admin&amp;quot;)
...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Clearly the SiteMap functionality is implemented as &lt;code&gt;LocParam&lt;/code&gt;, so you can implement them within your own Loc types, or simply use them declaratively within the regular SiteMap usage.&lt;/p&gt;

&lt;p&gt;This whole integration project wraps the Shiro types, so you only need to configure shiro.ini in the root of your classpath and enter the appropriate realm information as per the regular Shiro documentation, then away you go: password files&amp;#8230; active directory&amp;#8230; whatever you want.&lt;/p&gt;

&lt;p&gt;As above, this project is still early stage, but it does indeed work. I&amp;#8217;m currently looking for feedback, so if you have some thoughts or things that would be cool to see, then please checkout the project on Github and fork away.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>System Scripting with Scala</title>
   <link href="http://timperrett.com/2011/08/01/system-scripting-with-scala"/>
   <updated>2011-08-01T14:46:07+01:00</updated>
   <id>hhttp://timperrett.com/2011/08/01/system-scripting-with-scala</id>
   <content type="html">&lt;p&gt;For the longest time I have used Ruby as my pocket knife for system scripting&amp;#8230; you know, just knocking up small little executable files that run helpful tasks or automate yawnful processes. I like Ruby for this kind of thing and it works. Recently a coworker in marketing wanted some automation for something relatively simple and instead of using Ruby I thought i&amp;#8217;d just knock it together with Scala and in doing so I came across a neat little thing with the Scala scripting support.&lt;/p&gt;

&lt;p&gt;Assuming you have Scala installed, you can execute bash statements and pass them directly to your Scala code. This can be pretty handy as there are certain things that are particularly annoying to do from Scala (and more broadly with Java) like finding out where exactly you are executing too on the file system. Often if you use the good ol&amp;#8217; protection domain trick it will give you a location in /var/tmp, as opposed to the &lt;strong&gt;real&lt;/strong&gt; location of the script. Consider the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh
SCRIPT=&amp;quot;$(cd &amp;quot;${0%/*}&amp;quot; 2&amp;gt;/dev/null; echo &amp;quot;$PWD&amp;quot;/&amp;quot;${0##*/}&amp;quot;)&amp;quot;
DIR=`dirname &amp;quot;${SCRIPT}&amp;quot;}`
exec scala $0 $DIR $SCRIPT
::!#

import java.io.File

object App {
  def main(args: Array[String]): Unit = {
    val Array(directory,script) = args.map(new File(_).getAbsolutePath)
    println(&amp;quot;Executing &amp;#39;%s&amp;#39; in directory &amp;#39;%s&amp;#39;&amp;quot;.format(script, directory))
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice the base code between &lt;code&gt;#!/bin/sh&lt;/code&gt; and &lt;code&gt;::!#&lt;/code&gt;. This allows you to execute bash script (or whatever script you want) before evaluating this file as a Scala script. This can be pretty handy for certain tasks when doing system scripting :-)&lt;/p&gt;

&lt;p&gt;Assume you saved this file as &amp;#8220;thing&amp;#8221;, you can then execute it like any other script: &lt;code&gt;./thing&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Enjoy.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Using SOAP with Scala</title>
   <link href="http://timperrett.com/2011/07/26/using-soap-with-scala"/>
   <updated>2011-07-26T13:44:14+01:00</updated>
   <id>hhttp://timperrett.com/2011/07/26/using-soap-with-scala</id>
   <content type="html">&lt;p&gt;It seems I have inadvertently become &amp;#8220;that guy who does SOAP with Scala&amp;#8221;. Given this illustrious position it seemed prudent to get around to putting up an article that explains how to use the SOAP support now present in &amp;#8220;Scalaxb&amp;#8221;:http://scalaxb.org/.&lt;/p&gt;

&lt;p&gt;Scalaxb is a nice tool for working with XSD Schema from Scala, and recently WSDL support was added. In short this means that you can use native Scala types (such as Option&lt;span&gt;T&lt;/span&gt;) for interacting with SOAP methods.&lt;/p&gt;

&lt;h3 id='prerequisites'&gt;Prerequisites&lt;/h3&gt;

&lt;p&gt;Before you get going, its necessary to install Scalaxb, which itself requires &amp;#8220;Conscript&amp;#8221;:https://github.com/n8han/conscript/, so install that first. With ConScript in place, install Scalaxb by running:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cs eed3si9n/scalaxb&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will install Scalaxb and make it available on your $PATH. You can verify this by running the &lt;code&gt;scalaxb&lt;/code&gt; command.&lt;/p&gt;

&lt;h3 id='generating_contracts'&gt;Generating Contracts&lt;/h3&gt;

&lt;p&gt;With Scalaxb installed and your WSDL to hand, you can run something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scalaxb -p eu.getintheloop.sample \ 
        -d src/main/scala \
        src/main/wsdl/weather.wsdl&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will generate a range of .scala files pertaining to the WSDL contract you passed as the last argument to the scalaxb tool. In addition this sample includes the &lt;code&gt;-p&lt;/code&gt; to specify your own package and also the &lt;code&gt;-d&lt;/code&gt; argument to place the output files into my Scala source directory. In this particular case, I&amp;#8217;m using &amp;#8220;this SOAP endpoint&amp;#8221;:http://www.deeptraining.com/webservices/weather.asmx?wsdl, and you can freely do so too for the sake of this example.&lt;/p&gt;

&lt;h3 id='understanding_generated_classes'&gt;Understanding Generated Classes&lt;/h3&gt;

&lt;p&gt;Scalaxb generates three separate components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;SOAP protocol classes&lt;/em&gt;: These are the ancillary classes that are used to operate the SOAP protocol for things like the message envelope.&lt;/li&gt;

&lt;li&gt;&lt;em&gt;Default transport implementation&lt;/em&gt;: The HTTP driver to actually POST the SOAP message to the endpoint URI. This default implementation is based on the blocking HTTP &amp;#8220;Scala Dispatch&amp;#8221;:http://dispatch.databinder.net/Dispatch.html&lt;/li&gt;

&lt;li&gt;&lt;em&gt;Your service contracts&lt;/em&gt;: This is the only service specific part of the generated files. These relate to your specific service whilst the other two parts are completely decoupled and reusable over implementations / services you might have.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enough talking, lets look at some code.&lt;/p&gt;

&lt;h3 id='usage'&gt;Usage&lt;/h3&gt;

&lt;p&gt;The Scalaxb SOAP mechanism makes heavy use of the cake pattern, and thus allows you to mix and match different components as your situation dictates. Here&amp;#8217;s the default usage pattern:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;package eu.getintheloop.sample

import scalaxb._

object Main {
  def main(args: Array[String]){
    
    val remote = new WeatherSoap12s 
       with SoapClients 
       with DispatchHttpClients {}
    
    println {
      remote.service.getWeather(Some(&amp;quot;New York&amp;quot;))
    }
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note specifically that by combining the weather service contracts with the SOAP protocol classes and the transport implementation, the result is a working driver from which you can directly call the SOAP methods.&lt;/p&gt;

&lt;p&gt;The result of the service call itself is a &lt;code&gt;Either[Fault[_], Option[T]]&lt;/code&gt;, so if you want to get at the actual value you can just simply &lt;code&gt;fold&lt;/code&gt; on the Either.&lt;/p&gt;

&lt;h3 id='suggestions_for_customisation'&gt;Suggestions for Customisation&lt;/h3&gt;

&lt;p&gt;If you have multiple services to interact with then it can be nice to cake together all your service implementations so that you just have a single client that lazily loads the appropriate service classes as needed. Additionally, you could also replace the transport implementation with something asynchronous and based on futures&amp;#8230; that also is fun.&lt;/p&gt;

&lt;p&gt;The sample code for this example can be found at: &amp;#8220;https://github.com/timperrett/scalaxb-soap-example&amp;#8221;:https://github.com/timperrett/scalaxb-soap-example&lt;/p&gt;

&lt;p&gt;Enjoy.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Running SproutCore from within Lift</title>
   <link href="http://timperrett.com/2011/05/25/running-sproutcore-from-within-lift"/>
   <updated>2011-05-25T09:13:21+01:00</updated>
   <id>hhttp://timperrett.com/2011/05/25/running-sproutcore-from-within-lift</id>
   <content type="html">&lt;p&gt;If you want to run &amp;#8220;SproutCore&amp;#8221;:http://sproutcore.com from within your Lift application there are a couple of configurations you need to ensure you apply within your Boot.scala in order to actually make it work as you might anticipate.&lt;/p&gt;

&lt;p&gt;Firstly you need to ensure you set the HTML parser to use HTML5 and not XHTML, otherwise your templates will explode in extraordinary fashion when using the built template file as created by SproutCore build tools:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;LiftRules.htmlProperties.default.set((r: Req) =&amp;gt; 
  new Html5Properties(r.userAgent))
&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With that in place you need to do the equivalent of implementing a symlink for those setups that use the filesystem (a la PHP, Rails etc). Within Lift this is accomplished by using a stateless rewrite:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;LiftRules.statelessRewrite.append {
  case RewriteRequest(ParsePath(&amp;quot;index&amp;quot; :: Nil, &amp;quot;&amp;quot;, true, false),_,_) =&amp;gt; {
       RewriteResponse(&amp;quot;static&amp;quot; :: &amp;quot;todos&amp;quot; :: &amp;quot;en&amp;quot; :: &amp;quot;1.0&amp;quot; :: &amp;quot;index&amp;quot; :: Nil)
  }
}
&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This code tells Lift to rewrite the root path (/) to /static/todos/en//index template. Also be sure to implement your SiteMap so that only / is accessible and not the full (direct) SproutCore template path. If I do much more stuff with SproutCore I may well end up making an SBT plugin that automatically builds the updated JS files and copies them to your src/main/webapp path&amp;#8230; not sure yet, we&amp;#8217;ll see. Eitherway, the rewriting is certainly a good candidate for stuffing into a LocParam and making it reusable based upon some project configuration. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;Menu(&amp;quot;Home&amp;quot;) / &amp;quot;index&amp;quot; &amp;lt;&amp;lt; UsesSproutCore &amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For more information like this checkout my book on Lift launching this quarter on Manning Publications.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>SBT gets CloudBees support (and fast deploys!)</title>
   <link href="http://timperrett.com/2011/04/19/sbt-gets-cloudbees-support-and-fast-deploys"/>
   <updated>2011-04-19T10:33:13+01:00</updated>
   <id>hhttp://timperrett.com/2011/04/19/sbt-gets-cloudbees-support-and-fast-deploys</id>
   <content type="html">&lt;p&gt;About 18 months ago a company came out of nowhere called Stax Networks who were offering the ability to host JVM-based applications in the cloud, for FREE. This was too awesome not to look into and I subsequently made a plugin for SBT that automatically deployed your WAR files with a simple command.&lt;/p&gt;

&lt;p&gt;Stax themselves were recently taken over by &amp;#8220;CloudBees&amp;#8221;:http://www.cloudbees.com and from what I can see the service has done nothing but become more awesome since that has happened. Now that take over is bedding in, the API has changed somewhat so I thought i&amp;#8217;d rewrite my Stax plugin to work with CloudBees instead and take advantage of the ability to delta WAR files and only publish the updates.&lt;/p&gt;

&lt;h3 id='speedy_deploys'&gt;Speedy Deploys&lt;/h3&gt;

&lt;p&gt;The way this works is the build tool creates a WAR file like it would do normally, but as this is usually fairly large it can be exceedingly annoying to have to keep waiting for the deployment to take place. Rather than wait, the build tool calculates the difference between the deployed artefact and the one you just created, and subsequently only deploys the difference (or delta): essentially reducing your deploy time from 15 mins or more to a few seconds.&lt;/p&gt;

&lt;h3 id='gimmeh_it'&gt;Gimmeh It&lt;/h3&gt;

&lt;p&gt;In order to get started with using the SBT plugin, you will of course need a CloudBees account and upon registering you need to grab the key and secret from grandcentral.cloudbees.com, which should look something like: &lt;img src='https://github.com/timperrett/sbt-cloudbees-plugin/raw/master/notes/img/beehive-keys.jpg' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;These values represent the API Key and API Secret that CloudBees will use to verify your deployment rights. Once you have these two values, you can do one of two things in order to have them recognised by the SBT:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Enter them when the plugin prompts you; this will be on everytime you run a deployment to the cloud so is potentially a little sub-optiomal.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Create the properties file $HOME/.bees/bees.config so that you only need to define them once per computer. This properties file needs to be a key-value pair which should look something like this:&lt;/p&gt;

&lt;p&gt;bees.api.key=XXXXXXXXXX bees.api.secret=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX=&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whichever route you choose to specify that information, you then only need to define the plugin information in any given project. Specifically, in the Plugins.scala file define the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import sbt._
  class Plugins(info: ProjectInfo) extends PluginDefinition(info) {
    lazy val cloudbees = &amp;quot;eu.getintheloop&amp;quot; % &amp;quot;sbt-cloudbees-plugin&amp;quot; % &amp;quot;0.2.7&amp;quot;
    lazy val sonatypeRepo = &amp;quot;sonatype.repo&amp;quot; 
      at &amp;quot;https://oss.sonatype.org/content/groups/public&amp;quot;
  }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add the plugin to your SBT project like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  import sbt._
  class YourProject(info: ProjectInfo) extends DefaultWebProject(info) 
    with bees.RunCloudPlugin {
    ....
    override def beesUsername = Some(&amp;quot;youruser&amp;quot;)
    override def beesApplicationId = Some(&amp;quot;whatever&amp;quot;)
  }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Again, if you would prefer to enter these values when you deploy your application then you can of course just enter the appropriate values when prompted. Now your all configured and good to go, there are two commands you can run with this plugin:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get a list of your configured applications: &lt;code&gt;bees-applist&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;Deploy your application &lt;code&gt;bees-deploy&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Upon running &lt;code&gt;bees-deploy&lt;/code&gt; for the first time there will of course be a wait whilst the first version is deployed, but all your subsequent deployments should be much, much quicker. CloudBees is a rather awesome service and i&amp;#8217;d highly recommend checking it out for fast, easy deployment of your JVM web applications.&lt;/p&gt;

&lt;p&gt;Find the source code for the CloudBees SBT plugin &lt;a href='https://github.com/timperrett/sbt-cloudbees-plugin'&gt;here&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Color: You Are Your Device</title>
   <link href="http://timperrett.com/2011/04/18/color-you-are-your-device"/>
   <updated>2011-04-18T14:23:53+01:00</updated>
   <id>hhttp://timperrett.com/2011/04/18/color-you-are-your-device</id>
   <content type="html">&lt;p&gt;If you&amp;#8217;ve been living in a cave for the past months, you may not have seen &amp;#8220;Colour&amp;#8221;:http://www.color.com/. These guys &amp;#8220;raised $41m in investment&amp;#8221;:http://www.businessinsider.com/color-deal-2011-3 which in and of itself is seriously impressive. After that hit the headlines, I decided that just like everyone else i&amp;#8217;d grab me a chilled bottle of tech koolade and try it out.&lt;/p&gt;

&lt;p&gt;Now, I want to say here that my first impression of Colour was, well, underwhelming. When you&amp;#8217;re alone, its useless. However, when you&amp;#8217;re at an event, or gig, or somewhere else with a number of other people it was actually pretty awesome. Being able to collect a whole set of photos and events from a range of vantage points was quite awesome&amp;#8230; It&amp;#8217;s like event snaps, but on steroids because you automatically have everyone else&amp;#8217;s.&lt;/p&gt;

&lt;p&gt;There is however a rather huge &amp;#8220;but&amp;#8221; that has just reared its ugly head today. Colour identifies &lt;em&gt;devices&lt;/em&gt; not &lt;em&gt;people&lt;/em&gt;. This small but subtle difference is somewhat of a killer for Colour. Case in point: At the weekend I dropped my iPhone 4 by accident and totally destroyed the screen&amp;#8230; this meant I had to get a replacement, which I did this morning. Upon reloading Colour from my backup, I no longer have all the pictures and groups from my old device because it thinks i&amp;#8217;m someone &amp;#8220;new&amp;#8221;.&lt;/p&gt;

&lt;p&gt;Guys, really, $41m and you cant make a login? I actually really liked the app, but having it not come with you when you change device is just such a killer. People these days have a really high turn over of mobile devices, so it simply doesn&amp;#8217;t make sense to bind to the device&amp;#8230; the service is meant to be about people and the photos they take, so perhaps it would be a super great idea to stop using the device ID as a route to identify people.&lt;/p&gt;

&lt;p&gt;It generally feels like this could have been a really cool app, but its just lacking in some key areas.&lt;/p&gt;

&lt;p&gt;End rant.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Using Type Classes for Lift Snippet Binding</title>
   <link href="http://timperrett.com/2011/04/11/using-type-classes-for-lift-snippet-binding"/>
   <updated>2011-04-11T14:56:59+01:00</updated>
   <id>hhttp://timperrett.com/2011/04/11/using-type-classes-for-lift-snippet-binding</id>
   <content type="html">&lt;p&gt;Back in 2009 I was inspired by &amp;#8220;this article&amp;#8221;:http://logji.blogspot.com/2009/10/composable-bindings-in-lift-part-ii.html by &amp;#8220;Kris Nuttycombe&amp;#8221;:https://profiles.google.com/kris.nuttycombe/about which demonstrated how to use implicit conversions to declare composable, reusable Lift snippet bindings.&lt;/p&gt;

&lt;p&gt;At the time that article was written, Scala was still in the 2.7.x series and Lift only had the bind() helpers. As I write this today, Lift has its new CSS-style transformers and the Scala language has moved on quite considerably - especially with regard to the handling of implicits. With this in mind I wanted to show how one could make a similar setup but by leveraging Scala context bounds and Lift&amp;#8217;s CSS-style transformers.&lt;/p&gt;

&lt;h3 id='use_case'&gt;Use Case&lt;/h3&gt;

&lt;p&gt;Consider that you were building a system that displayed products. It&amp;#8217;s quite feasible that everywhere you wanted to display said product a same or similar binding would be required. A classic point in case is the product listing vs the checkout; the latter would only require a few of the product aspects to be displayed but there would be enough commonality with the listing usage as to not want to repeat yourself.&lt;/p&gt;

&lt;p&gt;For the sake of this article Product will be represented like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;case class Product(name: String, price: Long)
&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='binding'&gt;Binding&lt;/h3&gt;

&lt;p&gt;In order to make something implicitly bindable, that is to let the compiler know when it should apply the in-scope binding we need to make a bit of infrastructure to facility this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;import net.liftweb.util.CssSel

object Bindings {
  class Bind[T](what: T){
    def bind(implicit bind: DataBinding[T]) = bind(what)
  }
  type DataBinding[T] = T =&amp;gt; CssSel
  implicit def asCssSelector[T](in : T): Bind[T] = new Bind[T](in)
}&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here the Bindings object contains a converter class call Bind&lt;span&gt;T&lt;/span&gt; whos method bind takes an implicit parameter of DataBinding&lt;span&gt;T&lt;/span&gt;. In more lay terms, given T (ultimately, Product type) apply an implicit conversion from T =&amp;gt; CssSel, where CssSel is the internal Lift type for CSS transformers. Finally, the asCssSelector method does the actual conversion to a Bind&lt;span&gt;T&lt;/span&gt; instance just like any regular implicit conversion.&lt;/p&gt;

&lt;p&gt;So all that remains is to implement a binding for Product and show how you can use that in your snippet classes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;import Bindings._
import net.liftweb.util.Helpers._

object ProductBinding extends DataBinding[Product]{
  def apply(product: Product) = 
    &amp;quot;.name&amp;quot; #&amp;gt; product.name
}

class MySnippet {
  private implicit val binder = ProductBinding
  
  def render: CssSel = 
    Product(&amp;quot;whatever&amp;quot;, 1234L).bind
}&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this example, ProductBinding defines the generic binding that one requires for Product usage within the system. In your code, this would certainly be a lot more fully featured, but for the sake of example it just binds the name. Within the MySnippet class one can then simply call &lt;code&gt;Product(&amp;quot;whatever&amp;quot;, 1234L).bind&lt;/code&gt; and thats all that needs doing. In order to put the implicit binding in-scope, the ProductBinding singleton is just assigned to a value. This could have just as easily been held somewhere else in a common binding object and then imported to save the clutter, but here it is explicitly defined for the snippet.&lt;/p&gt;

&lt;p&gt;There is an alternative syntax which you might prefer for the snippet implementation that uses context bounds like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;def render[Product : Bind] = 
  Product(&amp;quot;whatever&amp;quot;, 1234L).bind
&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Importantly, with both implementation styles not that you can also add snippet-specific additions to the generic binding. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;def render: CssSel = 
    Product(&amp;quot;whatever&amp;quot;, 1234L).bind &amp;amp; 
    &amp;quot;.thing&amp;quot; #&amp;gt; &amp;quot;example&amp;quot;
&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hopefully you found this useful. For more information like this, please pick up a copy of &amp;#8220;Lift in Action&amp;#8221;:http://affiliate.manning.com/idevaffiliate.php?id=1138_235&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>HTTP Dispatch Guards in Lift using PartialFunction</title>
   <link href="http://timperrett.com/2011/02/23/http-dispatch-guards-using-partial-function"/>
   <updated>2011-02-23T13:06:46+00:00</updated>
   <id>hhttp://timperrett.com/2011/02/23/http-dispatch-guards-using-partial-function</id>
   <content type="html">&lt;p&gt;There are many little known features within the Lift code base and one that i&amp;#8217;ve been meaning to blog about for quite some time is the ability ot use partial functions as guards for HTTP dispatch.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s assume that your system requires some state to be set, like a session variable to ensure the user has logged in before they can access other parts of the service. The following example shows you you can implement a simple partial function to act as a guard.&lt;/p&gt;

&lt;h3 id='whats_the_goal'&gt;What&amp;#8217;s the goal?&lt;/h3&gt;

&lt;p&gt;The aim is to be able to define your services like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;LiftRules.dispatch.append(withAuthentication guard Service)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This gives you a fairly readable API that even with little knowledge of the underlying API you can see that you must have an authenticated session. In this super simple case, I&amp;#8217;ll just implement authentication as a Boolean in a SessionVar, but you get the point.&lt;/p&gt;

&lt;h3 id='the_service'&gt;The Service&lt;/h3&gt;

&lt;p&gt;Consider this service definition:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import net.liftweb.http.rest.RestHelper
import net.liftweb.http.{PlainTextResponse}

object Service extends RestHelper { 
  serve {
    case &amp;quot;protected&amp;quot; :: Nil Get _ =&amp;gt; 
      PlainTextResponse(&amp;quot;Ohh, secret&amp;quot;)
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is a super simple service using HTTP dispatch in Lift. Let&amp;#8217;s then define the dummy &amp;#8220;login&amp;#8221; url. In practice this would actually be some kind of bonified authentication but for this example it will suffice.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import net.liftweb.http.rest.RestHelper
import net.liftweb.http.{SessionVar,OkResponse}

object Security extends RestHelper {
  serve {
    case &amp;quot;login&amp;quot; :: Nil Get _ =&amp;gt; 
      LoggedIn(true)
      OkResponse()
  }
}

object LoggedIn extends SessionVar(false)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, simply hitting the URL /login will set the session to be logged in. Completely useless for production, but it serves my means here.&lt;/p&gt;

&lt;h3 id='the_boot_configuration'&gt;The Boot Configuration&lt;/h3&gt;

&lt;p&gt;Finally, now you have the services setup its time to write it all together within the Boot class.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import net.liftweb.http.{LiftRules,Req}
import net.liftweb.util.Helpers._ 
import sample.lib.{Security,Service,LoggedIn}

class Boot {
  def boot {
    val withAuthentication: PartialFunction[Req, Unit] = { 
      case _ if LoggedIn.is =&amp;gt; 
    }
    
    LiftRules.dispatch.append(Security)
    LiftRules.dispatch.append(withAuthentication guard Service)
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The key here is the import of Helpers._ to provide the implicit functions to enable guard to be called on the withAuthentication partial function, and the withAuthentication value simply passes all cases to an if statement that accesses the value of the SessionVar. Pretty simple, eh?&lt;/p&gt;

&lt;p&gt;Enjoy. All the code for this sample can be found &amp;#8220;here&amp;#8221;:https://github.com/timperrett/lift-dispatch-guard&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>A Long Road To The Final Chapter</title>
   <link href="http://timperrett.com/2011/02/13/a-long-road-to-the-final-chapter"/>
   <updated>2011-02-13T20:44:54+00:00</updated>
   <id>hhttp://timperrett.com/2011/02/13/a-long-road-to-the-final-chapter</id>
   <content type="html">&lt;p&gt;Today is a landmark. I&amp;#8217;ve been working on &amp;#8220;Lift in Action&amp;#8221;:http://manning.com/perrett/ for one year and one month, and finally, this evening, I&amp;#8217;ve reached the last chapter. The manuscript alone is currently sitting at around 120,000 words and represents the single largest body of work I have ever completed in my entire life. To that end felt the need to share this jubilant moment with you, dear reader.&lt;/p&gt;

&lt;p&gt;Chapter 6 is the only remaining part of the book and I have now started writing it! If you have bought the MEAP and and given feedback via the forum and emails, I thank you - your feedback thus far has been utterly invaluable. I have many corrections and revisions to include based on your comments and they are coming (promise!), so you should see them appear in the MEAP over the coming weeks accompanied by the as-yet unreleased chapters.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s been a seriously long road thus far but the end is finally in sight! Cheers to all my readers, friends and family for their support and contributions!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Memoization of Lift localeCalculator</title>
   <link href="http://timperrett.com/2011/01/30/memoization-of-lift-localecalculator"/>
   <updated>2011-01-30T17:53:10+00:00</updated>
   <id>hhttp://timperrett.com/2011/01/30/memoization-of-lift-localecalculator</id>
   <content type="html">&lt;p&gt;Within Lift each request has its locale calculated from scratch. Whilst this is fine with the default setting of reading from the accept headers on the incoming request, when you want to perhaps conduct something more complex you can inadvertently add quite an accidental overhead to the processing of each request. You can however ensure that the localeCalculator is only executed once by memoizing the value of the locale for the whole request cycle.&lt;/p&gt;

&lt;p&gt;The following code memoizes the locale computation into a variable that will exist for the full lifetime of a page request ensuring that you do not take the overhead of processing the locale a bunch of times.&lt;/p&gt;

&lt;p&gt;&lt;span&gt;gist id=803049&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;This is obviously a basic implementation that carries a smalloverhead, but the principal here is the same irrespective of what it is you are actually doing :-)&lt;/p&gt;

&lt;p&gt;Find great tips like this and more within &amp;#8220;Lift in Action&amp;#8221;:http://affiliate.manning.com/idevaffiliate.php?id=1138_235&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Year in Photos, 2010</title>
   <link href="http://timperrett.com/2010/12/28/the-year-in-photos-2010"/>
   <updated>2010-12-28T12:22:00+00:00</updated>
   <id>hhttp://timperrett.com/2010/12/28/the-year-in-photos-2010</id>
   <content type="html">&lt;p&gt;Wow, the 28th of December. This year has utterly flown by! What a year its been; i&amp;#8217;ve done a lot and experienced a whole set of new countries, met some awesome people at different conferences and generally had a great time! With this in mind, I thought I would just share some of my favourite moments from 2010 as we look forward to 2011.&lt;/p&gt;

&lt;h3 id='new_years_day_2010'&gt;New Years Day, 2010&lt;/h3&gt;

&lt;p&gt;The 2010 new years day was a crisp but cold day and I decided to go for a walk along the canal and managed to snap some great pictures of the bridges and people from the barges.&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2010/12/new-years-day-2010.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='livingo_italy'&gt;Livingo, Italy&lt;/h3&gt;

&lt;p&gt;In early January I went skiing with some friends to the beautiful mountain village of Livingo, Italy. I absolutely love Italy and this was one of my favourite shots from the holiday. Everyone is super friendly, the food is &lt;em&gt;amazing&lt;/em&gt; and the skiing is great. What more could you want?&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2010/12/livingo.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='sestiere_italy'&gt;Sestiere, Italy&lt;/h3&gt;

&lt;p&gt;After having been persuaded by my &amp;#8220;friend&amp;#8221;:http://twitter.com/#!/mikeedwards83 that going on another ski holiday would be a good idea, we ended up in the Olympic resort of Sestiere. Unfortunately I had a nasty accident on the first day and received a broken hand. Amazing scenery though!&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2010/12/sestiere-febuary.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='scala_days_switzerland'&gt;Scala Days, Switzerland&lt;/h3&gt;

&lt;p&gt;At long last Scala Days 2010 was upon us! This was easily one of the best conferences of 2010, anywhere. Really great people and going to EPFL was like a complete pilgrimage.&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2010/12/april-scaladays-stairs.jpg' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;As some of you may remember though, there was a the small matter of the icelandic volcano eruption which made flying impossible. An adventure then ensued as we all tried to get back to our mother countries by whatever means possible. For me that meant trains, hitchhiking and ferries! I took this one as we steamed away from France and I can tell you now, i&amp;#8217;ve never been more relieved to be on a ferry! It was a truly epic adventure.&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2010/12/april-scaladays-ferry.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='road_trip'&gt;Road Trip!&lt;/h3&gt;

&lt;p&gt;A friend of mine was getting married in June and his best man has the rather genius idea of doing a Top Gear-style rally up to the most northern point in the great british isles&amp;#8230; there was however a catch, we had to buy the most crappy car we could lay our hands on for no more than £300, drive up there and back, and then sell it. This was one of the most hilarious weekends of 2010 and with all the breakdowns and poor weather it was just awesome as we drove a car that was older than me 1500 miles over four days. Epic.&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2010/12/stag-do-john-o-groates.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='beautiful_june'&gt;Beautiful June&lt;/h3&gt;

&lt;p&gt;This time last year I moved into a new house that has the most amazing wildlife in the garden; all year round there are things growing or living there. Being a country boy at heart, this has been really enjoyable and I snapped this flower on a fine summers day in the garden.&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2010/12/june-my-garden.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='florence_italy'&gt;Florence, Italy&lt;/h3&gt;

&lt;p&gt;As the summer came, work was taking its toll and the need to visit Italy again was becoming irresistible. So, one Monday evening I booked a flight to florence the next day and just got on a plane and relaxed in the tuscan country side for a week of serious culture-vultur&amp;#8217;ing. Florence is an amazing city and if you ever get the chance to visit, either with a loved one, or solo, its amazing. I took this picture from piazza michelangelo, the highest lookout in Florence. The bridge in the scene is the famous Ponté Vechio. L&amp;#8217;amo Italia.&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2010/12/florence.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='hyderabad__mumbai_india'&gt;Hyderabad &amp;amp; Mumbai, India&lt;/h3&gt;

&lt;p&gt;&amp;#8220;Viktor&amp;#8221; and Sandra came to visit me in the summer, and that was just awesome. Whilst they were here work decided that it would be a great idea to send me to India the following week! I reluctantly accepted the assignment and started to arrange visas etc, as India was not somewhere that really appealed to me travel-wise. How wrong could I have been&amp;#8230; India was &lt;em&gt;AMAZING&lt;/em&gt;. Every single corner of every view you could take is crammed with vibrant colour and people with smiling faces. Its a truly humbling country and a must-visit place for any westerner. The two pictures below are from some time spent sight-seeing; this first one is Charminar, an ancient lookout post.&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2010/12/india1.jpg' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;The second one here was a moment captured at the top of Golconda Fort; these two lovers had been looking out over the landscape for ages; and what a view it is looking down on the ~7million inhabitants of Hyderabad.&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2010/12/india2.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='israel'&gt;Israel&lt;/h3&gt;

&lt;p&gt;As November came, I was once again sent to Israel to work on a research project. This trip was specifically memorable thanks to &amp;#8220;Gal&amp;#8221;:http://twitter.com/#!/gktheelder and &amp;#8220;Erik&amp;#8221;:http://twitter.com/#!/erikzaadi. This view was taken over the Herzliya beach early evening. Israel is awesome!&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2010/12/november-israel.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='snowpocalypse'&gt;Snowpocalypse!&lt;/h3&gt;

&lt;p&gt;With December came snow. Lots and lots of snow! This picture was taken about a week ago, and reminds me why I love living in the UK. Its like a winter wonderland!!&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2010/12/december.jpg' alt='' /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Distributing Critical State With ContainerVar</title>
   <link href="http://timperrett.com/2010/12/10/distributing-critical-state-with-containervar"/>
   <updated>2010-12-10T09:31:15+00:00</updated>
   <id>hhttp://timperrett.com/2010/12/10/distributing-critical-state-with-containervar</id>
   <content type="html">&lt;p&gt;Lift 2.2 brings a lot of new features to Lift, and one of them is ContainerVar. I previously blogged about it but did not have time then to make a screencast or sample. Now I have done both :-)&lt;/p&gt;
&lt;embed src='http://blip.tv/play/AYKTnCoC?p=1' height='320' allowscriptaccess='always' width='100%' wmode='transparent' type='application/x-shockwave-flash' allowfullscreen='true' /&gt;
&lt;p&gt;This and many more techniques are discussed in my book, &amp;#8220;Lift in Action&amp;#8221;:http://affiliate.manning.com/idevaffiliate.php?id=1138_235.&lt;/p&gt;

&lt;p&gt;Find source code here: &lt;a href='https://github.com/timperrett/lift-terracotta-example'&gt;https://github.com/timperrett/lift-terracotta-example&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Implicit REST Services with Lift</title>
   <link href="http://timperrett.com/2010/11/23/implicit-rest-services-with-lift"/>
   <updated>2010-11-23T17:53:20+00:00</updated>
   <id>hhttp://timperrett.com/2010/11/23/implicit-rest-services-with-lift</id>
   <content type="html">&lt;p&gt;Do you ever have those days, when you wake up and become unhappy with the &amp;#8220;code you wrote last year&amp;#8221;:http://blog.getintheloop.eu/2010/03/29/multi-format-rest-services-with-lift/ ? Today was one of those days (technically speaking it was yesterday, as I went to bed thinking this, but still). There simply must be a better way. So, im going to blame this post on &amp;#8220;Ross&amp;#8221;:http://twitter.com/dridus and &amp;#8220;Jon-Anders&amp;#8221;:http://twitter.com/jteigen . Those two are truly to blame for my interest in type-classes and compiler voodoo&amp;#8230; anyway, I digress&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;em&gt;DISCLAIMER&lt;/em&gt;: The following post makes heavy use of Scala implicit conversions and type system foo. Its not big, or clever, &lt;em&gt;but it is fun&lt;/em&gt;. Before someone points it out, yes, there is a far simpler route to implement something similar. This was ultimately an experiment :-)&lt;/em&gt;&lt;/p&gt;

&lt;h3 id='the_goal'&gt;The Goal&lt;/h3&gt;

&lt;p&gt;I write a lot of services. These services do a lot of different things and more often than not need to be published in a bunch of formats. In this way, its often easy to end up with one of two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accidental complexity&lt;/li&gt;

&lt;li&gt;Code duplication or blurred lines between logic process and media representation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this post i&amp;#8217;m going to show you &lt;em&gt;&lt;em&gt;one possible method&lt;/em&gt;&lt;/em&gt; of avoiding the second problem, but, subjectively, the first problem may seem better or worse depending on your familiarity with the Scala type system.&lt;/p&gt;

&lt;h3 id='plan_of_attack'&gt;Plan of Attack&lt;/h3&gt;

&lt;p&gt;Ok, so how are we going to do this? Well, as you may or may not know, Scala has this awesomeness called &amp;#8220;implicit conversions&amp;#8221;:http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-6 - these can be used to get the compiler to convert type A to type B when it only has A, but requires B. This is useful because the Scala compiler will use the appropriate implicit conversion that it finds within the given lexical scope; essentially meaning that you can &amp;#8220;inject&amp;#8221; different behaviour at different points during compile time. With this in mind, its a concept that matches quite closes to multi-format services. That is, I have type A from my logic or domain process and I need type B for the representation and delivery of a service.&lt;/p&gt;

&lt;p&gt;We will be making a very small sample application that&lt;/p&gt;

&lt;h3 id='the_book_store'&gt;The Book Store&lt;/h3&gt;

&lt;p&gt;Before we get into the utter type-madness, let us define the basic domain classes we&amp;#8217;ll be using:&lt;/p&gt;

&lt;p&gt;&lt;span&gt;gist id=712032&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;I think you&amp;#8217;ll agree this is super basic. Basically its just a fake bookstore that has a super limited stock of only Harry potter and Scala books. Strange, but true. Anyway&amp;#8230;&lt;/p&gt;

&lt;h3 id='define_the_service_types'&gt;Define the Service Types&lt;/h3&gt;

&lt;p&gt;We&amp;#8217;ll need some traits to glue this stuff together and provide the right syntax. &lt;code&gt;ReturnAs[A, B]&lt;/code&gt; - This structure is basically used to mediate each format from its input to its output; in and of itself it does not do a lot. The companion object here is actually where the good stuff is: the implicit method &lt;code&gt;f2ReturnAs&lt;/code&gt; takes a function &lt;code&gt;A =&amp;gt; B&lt;/code&gt; and converts it to a ReturnAs type. This is going to be handy when it comes to writing the implementation as we&amp;#8217;ll be able to say &lt;code&gt;Book =&amp;gt; LiftResponse&lt;/code&gt; etc.&lt;/p&gt;

&lt;p&gt;The next structure is the &lt;code&gt;Return[A]&lt;/code&gt; type and its nested type &lt;code&gt;As[B]&lt;/code&gt;. The Return type will be used as an explicit helper within the service implementations, so the API would be Return() via the companion object apply method. In addition to the single parameter, this method also has an implicit parameter of: &lt;code&gt;implicit f: ReturnAs[A, B]&lt;/code&gt; which will be made available to use from within the implementation call via &amp;#8220;Scala context bounds&amp;#8221;:http://stackoverflow.com/questions/2982276/what-is-a-context-bound-in-scala. This context bound will be expanded to plain type parameter T, together with an implicit parameter so that we can &amp;#8220;recapture&amp;#8221; the correct return type within the implementation.&lt;/p&gt;

&lt;p&gt;&lt;span&gt;gist id=712060&lt;/span&gt;&lt;/p&gt;

&lt;h3 id='format_conversions'&gt;Format Conversions&lt;/h3&gt;

&lt;p&gt;With the plumbing in place, one needs to actually provide implementation of the various A =&amp;gt; B type conversions. In this exceedingly small sample, im only going to be working with List&lt;span&gt;Book&lt;/span&gt;, so to keep this sample as simple as possible these are the implicit conversions for making an XML and plain text service:&lt;/p&gt;

&lt;p&gt;&lt;span&gt;gist id=712162&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;I wont labour the details too much here as this is pretty standard LiftResponse stuff that you can find in my other articles. That being said, there is an interesting point of note, and that is the type signatures:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Return[List[Book]]#As[XmlResponse]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here we use a type projection to specify the return type - this is pretty sick I think you&amp;#8217;ll agree.&lt;/p&gt;

&lt;h3 id='service_implementation'&gt;Service Implementation&lt;/h3&gt;

&lt;p&gt;With the media type conversions in place, the only thing that is actually left is within the service creation element is the writing of the method implementations.&lt;/p&gt;

&lt;p&gt;&lt;span&gt;gist id=712152&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;So this is important. This is where we use the context bound that we talked about earlier comes into play in expanding to a type parameter and an implicit parameter which allows us to write these rather nice looking methods wrapped in a the Return objects apply method without needing to specify any specific types.&lt;/p&gt;

&lt;h3 id='http_wireup'&gt;HTTP wire-up&lt;/h3&gt;

&lt;p&gt;Last but certainly not least is writing this awesomeness up into the HTTP implementation. To do that we are simply going to use Lift&amp;#8217;s REST DSL that needs a return type that is some subtype of LiftResponse. Of course, here we have those so we get a rather nice looking implementation:&lt;/p&gt;

&lt;p&gt;&lt;span&gt;gist id=712177&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;To test this out, all you need to do is visit /bookshop/books to get the text representation and /bookshop/books.xml to get the XML version. Hope you&amp;#8217;ve enjoyed this article, you can find full source available to &lt;a href='https://github.com/timperrett/implicit-rest'&gt;download from here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Find more information like this within my book, &lt;a href='http://affiliate.manning.com/idevaffiliate.php?id=1138_235'&gt;Lift in Action&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Meet Lift’s ContainerVar</title>
   <link href="http://timperrett.com/2010/11/18/meet-lifts-containerva"/>
   <updated>2010-11-18T21:41:46+00:00</updated>
   <id>hhttp://timperrett.com/2010/11/18/meet-lifts-containerva</id>
   <content type="html">&lt;p&gt;For those of you who have been following or working with Lift for sometime, you will know that our implementation of sessions provides a strongly-typed variable holder, but had a limitation in that it was not serializable across application servers using familiar scaling technologies like Terracotta. This is completely fine for the vast majority of use cases and having the extra type-safety and flexibility that SessionVar brings is valuable.&lt;/p&gt;

&lt;p&gt;However, there are situations and organizations that require scaling via their existing Java infrastructure and up until now Lift was unable to service that. Well, that is no longer the case as Lift has a new variable buddy called ContainerVar to sit alongside RequestVar, SessionVar and TransientRequestVar.&lt;/p&gt;

&lt;h3 id='whats_the_bobby'&gt;What&amp;#8217;s the bobby?&lt;/h3&gt;

&lt;p&gt;Firstly, its important to understand that ContainerVar is &lt;em&gt;not&lt;/em&gt; a replacement in any way-shape-or-form for SessionVar. It is an accompaniment to provide people who want to use a session store that is backed by the container. This does however come with several limitations in that you are then restricted to storing session data in strings, ints and so on that are moderately basic types which are serializable.&lt;/p&gt;

&lt;h3 id='hows_it_work'&gt;How&amp;#8217;s it work?&lt;/h3&gt;

&lt;p&gt;Glad you asked.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;object MySnippetCompanion {
  object mySessionVar extends ContainerVar[String](&amp;quot;hello&amp;quot;)
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, this is just like the other state variables within Lift. All the plumbing is abstracted away from you, so all you need to do is ensure your container sessions are configured correctly.&lt;/p&gt;

&lt;p&gt;I was hoping to make a sample application using &amp;#8220;HazzleCast&amp;#8221;:http://www.hazelcast.com/ or Terracotta but alas I need to get on with writing &amp;#8220;Lift in Action&amp;#8221;:http://manning.com/perrett/ so you good reader can learn more about the deep workings of Lift.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Distributed Data Networks with GaianDB</title>
   <link href="http://timperrett.com/2010/10/31/distributed-data-networks-with-gaiandb"/>
   <updated>2010-10-31T15:37:00+00:00</updated>
   <id>hhttp://timperrett.com/2010/10/31/distributed-data-networks-with-gaiandb</id>
   <content type="html">&lt;p&gt;This weekend has been a rather fascinating one. It was &lt;a href='http://bathcamp.org/'&gt;BathCamp 2010&lt;/a&gt; where I gave a couple of different talks on Scala and NoSQL and also listened to others talk about new and interesting tech. One of those talks was by &lt;a href='http://twitter.com/dalelane'&gt;Dale Lane&lt;/a&gt; from IBM about their AlphaWorks project &lt;a href='http://www.alphaworks.ibm.com/tech/gaiandb'&gt;GaianDB&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Firstly, &lt;a href='http://www.slideshare.net/dalelane/gaiandb-5611210'&gt;a very interesting talk by Dale&lt;/a&gt;. I have monitored the NoSQL space for the past 18 months with a close eye. The way in which we are building applications and the scale to which we as developers have to take said apps is really reaching new, dizzying heights - these are exciting times. With that said, GaianDB was a new one on me, and very out of left field.&lt;/p&gt;

&lt;h2 id='so_what_is_this_thing'&gt;So what is this thing?&lt;/h2&gt;

&lt;p&gt;Well, I must say that the &amp;#8220;DB&amp;#8221; part of the name feels a little wrong, as Gaian is essentially a way of treating lots of heterogeneous distributed data stores as one, coherent unit that can be queryered and accessed from any part of the &amp;#8220;network&amp;#8221;. IBM claim that Gaian was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;biologically inspired in that it strives to minimize network diameter and maximize connections to the most fit nodes. GaianDB advocates a flexible &amp;#8220;store locally, query anywhere&amp;#8221; (SLQA) paradigm.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This strikes me as pretty interesting for several reasons:&lt;/p&gt;

&lt;p&gt;1. Today is the age of the supposed &amp;#8220;cloud&amp;#8221; where centralised data storage and large scale applications rule. It takes a brave team to buck that trend and go for a strategy that is different.&lt;/p&gt;

&lt;p&gt;2. Being connected all the time, anywhere, with anything is, alas, still a dream. There are many business situations and organisations that are physically unable to be connected all the time perhaps because it simply is not practical for either cost or network performance reasons.&lt;/p&gt;

&lt;p&gt;3. Whilst technically possible to hold large volumes of data centrally, for a lot of telemetry-style applications this &lt;strong&gt;may&lt;/strong&gt; not actually be the best route.&lt;/p&gt;

&lt;p&gt;4. With more and more people/things becoming &amp;#8220;connected&amp;#8221;, having a system that can be both independent and collectively connected seems&amp;#8230; interesting.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s an example of Gaian nodes within a visualisation system:&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2010/10/31/gaian.png' alt='' /&gt;&lt;/p&gt;

&lt;h2 id='some_figures_from_ibm'&gt;Some Figures (from IBM)&lt;/h2&gt;

&lt;p&gt;Given 1000 Gaian network nodes, and one million rows of data the following was recorded:&lt;/p&gt;

&lt;p&gt;1. &lt;strong&gt;Query Time&lt;/strong&gt; - We are able to query all 1000 nodes in about 1/8 second. The results show that the query time grows logarithmically - in other words as you add more and more databases, the increase in query time slows down, providing excellent scaling. The way that a Gaian Network is grown from individual nodes automatically ensures this behaviour.&lt;/p&gt;

&lt;p&gt;2. &lt;strong&gt;Fetch Time&lt;/strong&gt; - We are able to fetch 1 million rows of data in under 5 seconds. The fetch time is proportional to the amount of data returned so that if you fetch twice the data it takes twice as long regardless of which of the 1000 nodes the data resides in. The Gaian Database actively pre-fetches the data from all the nodes to achieve this scalability&lt;/p&gt;

&lt;p&gt;3. &lt;strong&gt;Concurrent Queries&lt;/strong&gt; - I injected queries from up to 40 nodes at the same time, the Gaian Database showed that it could handle these queries robustly with a modest increase in the query time due to running out of available processor time on our test platform.&lt;/p&gt;

&lt;h2 id='tentative_conclusion'&gt;Tentative Conclusion&lt;/h2&gt;

&lt;p&gt;For some unbeknownst reason, I do find this sort of thing really interesting. I think there are a bunch of use cases where this type of workflow could be come useful - I mean, its essentially like skynet&amp;#8230; small pieces of tech that can comunicate to other pieces of near-by tech and also be commanded as a large whole. To that end, I&amp;#8217;ll be keeping an eye on this project to see how things evolve over time and pondering some other use cases for such a technology. Who knows, perhaps we&amp;#8217;ll see some kind of interactive advertising that merges RFID and smart telemetry over similar data networks to taylor customer experiences or something.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Using Lift’s AutoComplete Widget</title>
   <link href="http://timperrett.com/2010/10/13/using-lifts-autocomplete-widget"/>
   <updated>2010-10-13T20:08:00+01:00</updated>
   <id>hhttp://timperrett.com/2010/10/13/using-lifts-autocomplete-widget</id>
   <content type="html">&lt;p&gt;In this 5 min tutorial I am going to cover how to implement Lift&amp;#8217;s AutoComplete widget. I assume that you already have a Lift project setup with SBT.&lt;/p&gt;

&lt;h3 id='widget_dependency'&gt;Widget Dependency&lt;/h3&gt;

&lt;p&gt;First, add the widget dependency in your Project.scala:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;val widgets = &amp;quot;net.liftweb&amp;quot; %% &amp;quot;lift-widgets&amp;quot; % &amp;quot;2.1&amp;quot; &lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='configure_your_boot_class'&gt;Configure your Boot class&lt;/h3&gt;

&lt;p&gt;Widgets generally need to be wired into the ResourceServer in order to serve their CSS and JavaScript etc from the widgets JAR, to the client. This is, for the most part, done by calling &amp;#8220;init&amp;#8221; on the widget companion object.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  import net.liftweb.widgets.autocomplete.AutoComplete

  class Boot {
    def boot {
      ...
      AutoComplete.init
      ...
    }
  }&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='example_snippet'&gt;Example Snippet&lt;/h3&gt;

&lt;p&gt;In order to implement this snippet, simply do something along the lines of:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import scala.xml.NodeSeq
import net.liftweb.util.Helpers._
import net.liftweb.widgets.autocomplete.AutoComplete

class AutoCompleteSample {
  private val data = List(
    &amp;quot;Timothy&amp;quot;,&amp;quot;Derek&amp;quot;,&amp;quot;Ross&amp;quot;,&amp;quot;Tyler&amp;quot;,
    &amp;quot;Indrajit&amp;quot;,&amp;quot;Harry&amp;quot;,&amp;quot;Greg&amp;quot;,&amp;quot;Debby&amp;quot;)

  def sample(xhtml: NodeSeq): NodeSeq = 
    bind(&amp;quot;f&amp;quot;, xhtml, 
      &amp;quot;find_name&amp;quot; -&amp;gt; AutoComplete(&amp;quot;&amp;quot;, (current,limit) =&amp;gt;
        data.filter(_.toLowerCase.startsWith(current.toLowerCase)),
        value =&amp;gt; println(&amp;quot;Submitted: &amp;quot; + value))
    )
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This snippet simply calls the built in AutoComplete factory which ultimately returns a NodeSeq that is bound to the namespace &amp;#8220;f&amp;#8221; and the element &amp;#8220;find_name&amp;#8221;.&lt;/p&gt;

&lt;h3 id='markup'&gt;Markup&lt;/h3&gt;

&lt;p&gt;All that remains is to call that in your template with something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  &amp;lt;lift:auto_complete_sample.sample form=&amp;quot;post&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;Type a name here: &amp;lt;f:find_name&amp;gt;&amp;lt;/f:find_name&amp;gt;&amp;lt;/p&amp;gt;
  &amp;lt;/lift:auto_complete_sample.sample&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Enjoy&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Calling AppleScript from Scala</title>
   <link href="http://timperrett.com/2010/09/22/calling-applescript-from-scala"/>
   <updated>2010-09-22T12:28:00+01:00</updated>
   <id>hhttp://timperrett.com/2010/09/22/calling-applescript-from-scala</id>
   <content type="html">&lt;p&gt;It occoured to me today that it would be a doddle to control parts of OSX from the Scala REPL. Check this out below, the script itself simply says &amp;#8220;Hello World&amp;#8221; out loud but it would be easy to substitute in something more meaningful.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scala&amp;gt; import javax.script._
import javax.script._

scala&amp;gt; val script = &amp;quot;say \&amp;quot;Hello World\&amp;quot;&amp;quot; 
script: java.lang.String = say &amp;quot;Hello World&amp;quot; 

scala&amp;gt; val mgr = new ScriptEngineManager
mgr: javax.script.ScriptEngineManager = 
  javax.script.ScriptEngineManager@8094cc7

scala&amp;gt; val engine = mgr.getEngineByName(&amp;quot;AppleScript&amp;quot;)
engine: javax.script.ScriptEngine = 
  apple.applescript.AppleScriptEngine@16cc8a48

scala&amp;gt; val context = engine.getContext                
context: javax.script.ScriptContext =
   javax.script.SimpleScriptContext@2278e185

scala&amp;gt; val bindings = context.getBindings(ScriptContext.ENGINE_SCOPE)
bindings: javax.script.Bindings = 
  javax.script.SimpleBindings@65712a80

scala&amp;gt; engine.eval(script, context)
res0: java.lang.Object = null&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;#8217;s all there is too it. Scalatastic!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>JavaZone 2010: Adventures with Monads and Beer</title>
   <link href="http://timperrett.com/2010/09/10/javazone-2010-adventures-with-monads-and-beer"/>
   <updated>2010-09-10T09:51:00+01:00</updated>
   <id>hhttp://timperrett.com/2010/09/10/javazone-2010-adventures-with-monads-and-beer</id>
   <content type="html">&lt;p&gt;I have just arrived back from &lt;a href='http://jz10.java.no/'&gt;JavaZone&lt;/a&gt; and wow, what a great conference. Personally, I see this as being the best conference in Europe at the moment - the approach the organisers take to making zero profit and ploughing all the attendee&amp;#8217;s fees right back into the conference is simply awe-inspiring! There really is no where quite like it on the EU conference circuit&amp;#8230; for example, where else would you see a 3m high &lt;a href='http://kenai.com/projects/duke/pages/Home'&gt;Java Duke&lt;/a&gt; that when you hug it, subsequently vends free beer&amp;#8230; amazing.&lt;/p&gt;

&lt;h2 id='scala_in_the_nordics'&gt;Scala in the Nordics&lt;/h2&gt;

&lt;p&gt;Scala was very very well represented. This was my first time up in that part of the world and wow, what a community they have. Everyone is super smart and really interested in new technology; Scala in particular. On the second night of the conference the local &amp;#8220;ScalaBin&amp;#8221; held a meeting / pre-party and it was extremely well attended: much beer was consumed and some great conversations had.&lt;/p&gt;

&lt;h2 id='some_photos'&gt;Some Photos&lt;/h2&gt;

&lt;p&gt;Jonas Bon&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Native2Ascii plugin for SBT</title>
   <link href="http://timperrett.com/2010/08/18/native2ascii-plugin-for-sbt"/>
   <updated>2010-08-18T09:32:00+01:00</updated>
   <id>hhttp://timperrett.com/2010/08/18/native2ascii-plugin-for-sbt</id>
   <content type="html">&lt;p&gt;As I have been doing quite a lot of localisation work recently, I thought it prudent to port the native2ascii tool over to SBT so that I didn&amp;#8217;t constantly have to keep using it manually on the command line. If you are interested, you can grab the source code from &lt;a href='http://github.com/timperrett/sbt-native2ascii-plugin'&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If order to get started with the plugin add it to your Plugins.scala within your project:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  import sbt._
  class Plugins(info: ProjectInfo) extends PluginDefinition(info) {
    val n2a = &amp;quot;eu.getintheloop&amp;quot; % &amp;quot;sbt-native2ascii-plugin&amp;quot; % &amp;quot;0.1.0&amp;quot; 
  }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#8230;and then mix the Native2Ascii trait into your project:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;      class SampleProject(info: ProjectInfo) 
    extends DefaultWebProject(info) 
    with Native2AsciiPlugin {
    ...
  }
&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ensure you have all your localization .txt files in src/main/i18n and by default they will be translated into your application resources folder in src/main/resources.&lt;/p&gt;

&lt;p&gt;Then, from your SBT prompt just hit:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
  &amp;gt; native2ascii
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;All being well you should then see something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;      [info] == native2ascii ==
  [info] Encoding &amp;#39;.txt&amp;#39; to &amp;#39;.properties&amp;#39; file(s) in src/main/resources
  [info] Translation complete.
  [info] == native2ascii ==
&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>Scala: It’s Good for Your Health</title>
   <link href="http://timperrett.com/2010/07/15/scala-its-good-for-your-health"/>
   <updated>2010-07-15T18:36:00+01:00</updated>
   <id>hhttp://timperrett.com/2010/07/15/scala-its-good-for-your-health</id>
   <content type="html">&lt;p&gt;I was just stood in my kitchen washing the dishes and reflecting on the past four years coding Scala and being heavily involved with the community; seeing it grow and enjoying the relationships that have been forged through that time. I have learnt more during my time in this community than probably any other I have ever been involved with.&lt;/p&gt;

&lt;p&gt;To date, I am yet to encounter someone in the Scala and Lift communities who isn&amp;#8217;t above average intellectually and super friendly. Pretty much everyone, without exception, is very clever and this generates amazingly stimulating discussions, no matter what the topic. I have been exceedingly fortunate to work with the likes of &lt;a href='http://twitter.com/dpp'&gt;David&lt;/a&gt;, &lt;a href='http://twitter.com/mariusdanciu'&gt;Marius&lt;/a&gt;, &lt;a href='http://twitter.com/jboner'&gt;Jonas&lt;/a&gt; and &lt;a href='http://twitter.com/viktorklang'&gt;Viktor&lt;/a&gt; and have them provoke new ideas and create shared experiences with as we challenge our own thinking and continue to improve both Lift and Akka.&lt;/p&gt;

&lt;p&gt;Finally, I have been lucky enough to forge some great friendships that have ultimately been very rewarding. Moreover, it makes me wonder what my life might be like had I never gotten involved with Lift? The likelihood of making those same friendships would be slim, and I doubt I would be a published author either!&lt;/p&gt;

&lt;p&gt;All this makes me conclude that Scala has had a very, very positive impact on my life as a whole. So, if you are feeling under the weather? Perhaps you should take some Scala ;-)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Controlling Schemifier naming conventions with MapperRules</title>
   <link href="http://timperrett.com/2010/06/27/controlling-schemifier-naming-conventions-with-mapperrules"/>
   <updated>2010-06-27T16:27:00+01:00</updated>
   <id>hhttp://timperrett.com/2010/06/27/controlling-schemifier-naming-conventions-with-mapperrules</id>
   <content type="html">&lt;p&gt;I was recently asked how to stop Lift&amp;#8217;s Mapper from flattening the naming of columns during its &amp;#8220;schemification&amp;#8221; process. Well, there is a little known configuration object in the net.liftweb.mapper package called MapperRules.&lt;/p&gt;

&lt;p&gt;MapperRules contains a whole bunch of stuff that you can use to control the way that Mapper names stuff that it creates and how it will try and inspect your database. If you prefer (like me) to have columns and tables like first_name rather than firstname, then add the following to Boot.scala:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Boot {
  def boot {
    ...
    MapperRules.tableName =  (_,name) =&amp;gt; StringHelpers.snakify(name)
    MapperRules.columnName = (_,name) =&amp;gt; StringHelpers.snakify(name)
    ...  
  } 
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thats it!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Lift In Action – The comprehensive guide to Lift</title>
   <link href="http://timperrett.com/2010/06/23/lift-in-action-the-comprehensive-guide-to-lift"/>
   <updated>2010-06-23T19:41:00+01:00</updated>
   <id>hhttp://timperrett.com/2010/06/23/lift-in-action-the-comprehensive-guide-to-lift</id>
   <content type="html">&lt;p&gt;So I have been pretty lax of late with keeping this blog up to date. There is a very good reason for that, and that is I am currently working on a book about &lt;a href='http://liftweb.net/'&gt;Lift&lt;/a&gt; - If you haven&amp;#8217;t heard, &lt;a href='http://manning.com/perrett/'&gt;Lift In Action&lt;/a&gt; will be available on Manning Publications in Q1 of 2011 and is currently available as an eBook via the Manning website. Its generally eating a lot of my time right now so I haven&amp;#8217;t had a chance to post about all the cool new stuff that is making its way into Lift every week - hopefully I will soon get time to write about the awesome new Record persistence system that we are all very excited about as we are currently integrating the extremely awesome &lt;a href='http://squeryl.org/'&gt;Squeryl&lt;/a&gt; as a backend for dealing with RDBMS.&lt;/p&gt;

&lt;p&gt;By all means, go and checkout the book and let me know what you think as it develops in the &lt;a href='http://www.manning-sandbox.com/forum.jspa?forumID=660&amp;amp;start=0'&gt;author online forums&lt;/a&gt; and I will get back to you ASAP. Enjoy!&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2010/6/23/perrett_cover150.jpg' alt='' /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Inline Markup Validation with Lift</title>
   <link href="http://timperrett.com/2010/05/01/inline-markup-validation-with-lift"/>
   <updated>2010-05-01T15:22:00+01:00</updated>
   <id>hhttp://timperrett.com/2010/05/01/inline-markup-validation-with-lift</id>
   <content type="html">&lt;p&gt;Continuing with my series of articles about Lift, here&amp;#8217;s another hidden gem that not many people know about. Lift can automatically validate your markup so that any validation errors or warnings are high lighted to you as part of the development process. Pretty neat. Here&amp;#8217;s what you need to do to enable it:&lt;/p&gt;

&lt;h3 id='configure_boot'&gt;Configure Boot&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;  class Boot {
    def boot {
    ......   
      LiftRules.xhtmlValidator = Full(StrictXHTML1_0Validator)
    }
  }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Where of course you can replace &lt;code&gt; StrictXHTML1_0Validator&lt;/code&gt; with any one of:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  TransitionalXHTML1_0Validator
  StrictXHTML1_0Validator

  // or subclass:
  GenericValidtor
  // to provide your own custom implementation &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Find this and more great tips in my forthcoming book, &lt;a href='http://manning.com/perrett/'&gt;Lift in Action&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Understanding Lift’s Box[T] monad</title>
   <link href="http://timperrett.com/2010/04/16/understanding-lifts-boxt-monad"/>
   <updated>2010-04-16T09:26:00+01:00</updated>
   <id>hhttp://timperrett.com/2010/04/16/understanding-lifts-boxt-monad</id>
   <content type="html">&lt;p&gt;So im at Scala Days 2010 right now, and during dinner last night their seemed to be some misconceptions about what Lift&amp;#8217;s Box&lt;span&gt;T&lt;/span&gt; monad actually does and how it differs from Option&lt;span&gt;T&lt;/span&gt;. Now, im not computer scientist, so im not going to be discussing the algebraic validity of Box&lt;span&gt;T&lt;/span&gt;, not shall I be calling it a &amp;#8220;tri state option&amp;#8221;&amp;#8230;&lt;/p&gt;

&lt;h2 id='why_bother_boxing_values'&gt;Why bother boxing values?&lt;/h2&gt;

&lt;p&gt;Have you ever thrown a NullPointerException? Frankly, I don&amp;#8217;t know any developers that haven&amp;#8217;t had this happen to them at some point because of something they hadn&amp;#8217;t considered during development&amp;#8230; in short, a NPE is something that was caused by an unexpected series of events causing your application to explode in a variety of ways. This is not good.&lt;/p&gt;

&lt;p&gt;Consider a scenario where I want to do something with a value returned from a database; its not uncommon to see programs where one assumes the database query got the correct result, then do some operation on it. Well, news flash, its highly plausible that the database query might not go as you had expected and return some other result&amp;#8230;.&lt;/p&gt;

&lt;p&gt;&amp;#8230;Boxes to the rescue! As the name might suggest, a Box is something that you can put stuff in, take stuff out of, and also find empty. Much as you would do with a real life box. Lets illustrate with a simple example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    import net.liftweb.common.{Box,Full,Empty,Failure,ParamFailure}

scala&amp;gt; val x: Box[String] = Empty
x: net.liftweb.common.Box[String] = Empty

scala&amp;gt; val y = Full(&amp;quot;Thing&amp;quot;)
y: net.liftweb.common.Full[java.lang.String] = Full(Thing)

&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We have two simple examples here that assign new boxes to vals, and as you can see, &lt;code&gt;x&lt;/code&gt; is assigned as a &lt;code&gt;Box[String]&lt;/code&gt;, yet its actual value is Empty which is a sub type of Box. The second assignment to &lt;code&gt;y&lt;/code&gt; has the same type signature, but this time it is &amp;#8220;Full&amp;#8221; with a value; in this instance &amp;#8220;Thing&amp;#8221;.&lt;/p&gt;

&lt;h2 id='what_about_exceptions'&gt;What about exceptions?&lt;/h2&gt;

&lt;p&gt;Lift has a helper method in &lt;code&gt;net.liftweb.util.Helpers&lt;/code&gt; called &amp;#8220;tryo&amp;#8221; that is a specilized control structure so that if you can execute code in a block that returns a Box&amp;#8217;ed value irrespective of what you did in the block and how its execution went. If your using Lift webkit then you already have access to these utility methods, however if you just want to stay light and are not using webkit then the definition of tryo looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;      def tryo[T](
      ignore: List[Class[_]], 
      onError: Box[Throwable =&amp;gt; Unit])
      (f: =&amp;gt; T): Box[T] = {
    try {
      Full(f)
    } catch {
      case c if ignore.exists(_.isAssignableFrom(c.getClass)) =&amp;gt; 
        onError.foreach(_(c)); Empty
      case c if (ignore == null || ignore.isEmpty) =&amp;gt; 
        onError.foreach(_(c)); Failure(c.getMessage, Full(c), Empty)
    }
  }
&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are some other overloads for syntax sugar, but essentially it lets you do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;      tryo {
    // your code here
  }

&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So lets assume we had some remote API to invoke, and it could not connect, or blow up in some way you hadn&amp;#8217;t planned, what would happy given a tryo block / wrap? Consider:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    scala&amp;gt; tryo(&amp;quot;www&amp;quot;.toInt) 
res4: net.liftweb.common.Box[Int] = Failure(
  For input string: &amp;quot;www&amp;quot;,
  Full(java.lang.NumberFormatException: For input string: &amp;quot;www&amp;quot;),
  Empty)

&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As &amp;#8220;www&amp;#8221; isnt an Int, it unsurprisingly cannot be converted to one, so it blows up with java.lang.NumberFormatException. However, using tryo (boxed values) we are left with a special Box subtype called Failure. This lets us handle the error in a concise way rather than needing to check all the possible outcomes or worry about some awful try-catch block.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scala&amp;gt; tryo(&amp;quot;www&amp;quot;.toInt) openOr 1234                       
res7: Int = 1234

scala&amp;gt; tryo(&amp;quot;www&amp;quot;.toInt).map(_.toString).openOr(&amp;quot;Invalid Strings&amp;quot;)
res8: java.lang.String = Invalid Strings

scala&amp;gt; for(x &amp;lt;- tryo(&amp;quot;www&amp;quot;.toInt)) yield x
res11: net.liftweb.common.Box[Int] = Failure(
  For input string: &amp;quot;www&amp;quot;,
  Full(java.lang.NumberFormatException: For input string: &amp;quot;www&amp;quot;),
  Empty)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So you can see there several ways to interact with Box, Full and Failure subtypes, providing defaults inline and mapping the results etc.&lt;/p&gt;

&lt;h3 id='handling_empty_values'&gt;Handling empty values?&lt;/h3&gt;

&lt;p&gt;But what if we need more information or the value we are looking for isnt a failure, its just the value is Empty (or None for scala Option)? For example, lets assume we were looking for a request parameter to a REST API or similar&amp;#8230; rather than throwing a HTTP 500 error with no reason, it would be nice to give the user a much more granular reason. Consider getting a request paramater using Lift&amp;#8217;s S.param method.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scala&amp;gt; S.param(&amp;quot;id&amp;quot;) ?~ &amp;quot;You must supply an ID parameter&amp;quot; 
res17: net.liftweb.common.Failure = 
Failure(You must supply an ID parameter,Empty,Empty)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;?~&lt;/code&gt; method allows you to supply an error message and convert the Empty into a Failure. This is an incredibly helpful paradigm when used with for comprehensions.&lt;/p&gt;

&lt;h3 id='chaining_boxes'&gt;Chaining boxes&lt;/h3&gt;

&lt;p&gt;Lets assume that we have a situation where by we could recive a value from several places, or we need to &amp;#8220;fall through&amp;#8221; to a specific result based on trying several values in a sequence&amp;#8230; Box supports this by way of the &amp;#8220;or&amp;#8221; operand.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scala&amp;gt; val x = Empty
x: net.liftweb.common.Empty.type = Empty

scala&amp;gt; val y = tryo(&amp;quot;qqq&amp;quot;.toInt) 
y: net.liftweb.common.Box[Int] = 
  Failure(For input string: &amp;quot;qqq&amp;quot;,
  Full(java.lang.NumberFormatException: For input string: &amp;quot;qqq&amp;quot;),
  Empty)

scala&amp;gt; x or y or Full(&amp;quot;Default&amp;quot;)
res18: net.liftweb.common.Box[Any] = Full(Default)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Box has a bunch of features I haven&amp;#8217;t covered here, but I hope this helps you understand the rational of this specialised option-esq type.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Asynchronous REST Services with Lift</title>
   <link href="http://timperrett.com/2010/04/02/asynchronous-rest-services-with-lift"/>
   <updated>2010-04-02T09:55:00+01:00</updated>
   <id>hhttp://timperrett.com/2010/04/02/asynchronous-rest-services-with-lift</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; REST and many other topics discussed within my upcomming book Lift in Action, more information will shortly be published on &lt;a href='http://manning.com'&gt;manning.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one is hot off the press - Lift 2.0-SNAPSHOT now has the ability to do notification style service workflows - essentially comet for REST.&lt;/p&gt;

&lt;p&gt;So how does this work? Well, following on from my other post on REST services with Lift we are still using a &lt;code&gt;DispatchPF&lt;/code&gt; to setup the service, but we now use the statefull dispatcher &lt;code&gt;LiftRules.dispatch&lt;/code&gt; rather than &lt;code&gt;statelessDispatchTable&lt;/code&gt; and from inside our resource definition we call &lt;code&gt;S.respondAsync&lt;/code&gt;. Here&amp;#8217;s a complete example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  LiftRules.dispatch.append {
    case Req(&amp;quot;example&amp;quot; :: rest, _, _) =&amp;gt; {
      S.respondAsync {
        Thread.sleep(20000) // some computation here
        Full(XmlResponse(&amp;lt;async&amp;gt;response&amp;lt;/async&amp;gt;))
      }
    }
  }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The call to S.respondAsync executes the function you pass to it on another thread and if the container you are using supports suspend / resume idiom Lift will pass control to the container and no threads are blocked during its execution; just return a Box&lt;span&gt;LiftResponse&lt;/span&gt; like normal and Lift will handle notification to listening clients. Sweet.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Multi-format REST services with Lift</title>
   <link href="http://timperrett.com/2010/03/29/multi-format-rest-services-with-lift"/>
   <updated>2010-03-29T17:00:00+01:00</updated>
   <id>hhttp://timperrett.com/2010/03/29/multi-format-rest-services-with-lift</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This subject is discussed in much greater detail within my upcomming book Lift in Action, more information will shortly be published on &lt;a href='http://manning.com'&gt;manning.com&lt;/a&gt;&lt;/p&gt;

&lt;h3 id='the_goal'&gt;The Goal&lt;/h3&gt;

&lt;p&gt;So what are we actually trying to achieve here? We&amp;#8217;ll use the twitter.com API as an example as its a good illustration in this instance. Consider the following URLs:&lt;/p&gt;

&lt;p&gt;&lt;a href='http://api.twitter.com/users/timperrett.xml'&gt;http://api.twitter.com/users/timperrett.xml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;p&gt;&lt;a href='http://api.twitter.com/users/timperrett.json'&gt;http://api.twitter.com/users/timperrett.json&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Its the exact same content, but just presented in different formats. This is very nice, and also very helpful as often you might be in a situation where you need to syndicate a single API from multiple devices or platforms where toolkits may be limited. For example, working with JSON is a lot easier from Java script than it is XML (the latter is of course possible its just more verbose). In the examples above, Twitter are using the format component of the URL following the &amp;#8221;.&amp;#8221; to determine the content type the user wants - this is of course one route, and some services may want to add the additional stipulation of a specified accepts and content-type headers in the requests so the server is sure its serving the right content.&lt;/p&gt;

&lt;p&gt;The interesting problem here is that if you have the same content, you really only want one point of access for the logic. You simply dont want to be maintaining two set of logic - only the actual code that handles differences in presentation should alter between calls right?&lt;/p&gt;

&lt;h3 id='implementation_pattern'&gt;Implementation Pattern&lt;/h3&gt;

&lt;p&gt;Typically, when I want to create web services in my Lift application I break out my dispatchers into separate objects related to their concerns. This way it keeps things nice and tidy. So, in our example, i&amp;#8217;ll be wiring up the following services:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  LiftRules.statelessDispatchTable.append {
    case Req(&amp;quot;apps&amp;quot; :: Nil, &amp;quot;json&amp;quot;, GetRequest) =&amp;gt; 
      ApplicationServices.json.list
    case Req(&amp;quot;apps&amp;quot; :: Nil, &amp;quot;xml&amp;quot;, GetRequest) =&amp;gt; 
      ApplicationServices.xml.list
  }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For those not familiar with Lift&amp;#8217;s dispatching mechanism this will expose the following URLs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;/apps.json&lt;/li&gt;

&lt;li&gt;/apps.xml&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All pretty simple so far. As you can see from the code listing above, I have broken my application services out into a singleton object called ApplicationServices which has fields for each content type im going to be presenting. Without further ado lets take a look at the definition of the apps listing service:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;object ApplicationServices extends Loggable {
  .....
  protected def _list(mediaAction: List[String] =&amp;gt; LiftResponse) =
    () =&amp;gt; tryo(mediaAction(Applications.list.map(_.name)))
  .....
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ok so this is pretty cool. Im using function passing to let each subsequent definition define how it builds the LiftResponse sub-type; in this instance that&amp;#8217;ll be JsonResponse for JSON and XmlResponse for XML.&lt;/p&gt;

&lt;h3 id='json_listing'&gt;JSON Listing&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;def list = _list((apps) =&amp;gt; 
  JsonResponse(compact(JsonAST.render((&amp;quot;applications&amp;quot; -&amp;gt; apps)))))&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='xml_listing'&gt;XML Listing&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;def list = _list((apps) =&amp;gt; XmlResponse({
  &amp;lt;applications&amp;gt;
    {apps.map(a =&amp;gt; &amp;lt;application name={a} /&amp;gt;)}
  &amp;lt;/applications&amp;gt;
}))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So you can see that each presentation version is only dealing with how it needs to create the response&amp;#8230; its not re-computing the list of applications or such.&lt;/p&gt;

&lt;h3 id='syntax_sugar'&gt;Syntax Sugar&lt;/h3&gt;

&lt;p&gt;Within the overall definition I define the formats as inner-objects and assign them to public fields in order to achieve the nice ApplicationServices.xml.list notation:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;object ApplicationServices extends Loggable {
  val json = Json
  val xml = Xml

  protected def _list(mediaAction: List[String] =&amp;gt; LiftResponse) =
    () =&amp;gt; tryo(mediaAction(Applications.list.map(_.name)))

  object Json {
    // definitions here
  }

  object Xml {
    // definitions here
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='round_up'&gt;Round Up&lt;/h3&gt;

&lt;p&gt;Thats pretty much all there is too it. You can leverage Scala&amp;#8217;s extremely powerful features to create your web services and keep code LOC to a minimum. Over and out.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Gracefully handling 404s with Lift</title>
   <link href="http://timperrett.com/2010/02/21/gracefully-handling-404s-with-lift"/>
   <updated>2010-02-21T14:07:00+00:00</updated>
   <id>hhttp://timperrett.com/2010/02/21/gracefully-handling-404s-with-lift</id>
   <content type="html">&lt;p&gt;In my continuing effort to improve the wider knowledge of Lift, here&amp;#8217;s another great nugget that shows you how to provide a 404 handler powered from a Lift template&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Boot {
  def boot {
    // ...other stuff...

    LiftRules.uriNotFound.prepend(NamedPF(&amp;quot;404handler&amp;quot;){
      case (req,failure) =&amp;gt; 
       NotFoundAsTemplate(ParsePath(List(&amp;quot;404&amp;quot;),&amp;quot;html&amp;quot;,false,false))
    })

  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And I have a 404.html file in the ./webapp/404.html with the contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;lift:surround with=&amp;quot;default&amp;quot; at=&amp;quot;content&amp;quot;&amp;gt;
  &amp;lt;h2&amp;gt;Ooops!&amp;lt;/h2&amp;gt;
  &amp;lt;p&amp;gt;Wow, we totally couldn&amp;#39;t find your page. Sorry about that.&amp;lt;/p&amp;gt;
&amp;lt;/lift:surround&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then whenever a user browses to a URL that is not supported by your application, you can give them a friendly (and nicely designed) webpage rather than some technical message about 404s.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The only cavet is not to use the &lt;code&gt;&amp;lt;lift:menu /&amp;gt;&lt;/code&gt; snippet within your 404 template because Lift is unable to calculate the SiteMap when its a URL that is not accounted for within that scheme.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt; The above note is now redundant because of commit by Marius on issue 376&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Using Jetty 7 continuations to power Lift comet support</title>
   <link href="http://timperrett.com/2010/02/18/using-jetty-7-continuations-to-power-lift-comet-support"/>
   <updated>2010-02-18T17:07:00+00:00</updated>
   <id>hhttp://timperrett.com/2010/02/18/using-jetty-7-continuations-to-power-lift-comet-support</id>
   <content type="html">&lt;p&gt;Recently, Marius added an abstraction layer within Lift so that we could support different comet implementations over different servlet containers. Out of the box, we provide two both Jetty 6 and Jetty 7 APIs. This API is however not very well documented so I thought I would just write a short post on how to use it. In your Boot.scala file you need to put something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import net.liftweb.http._
import provider.servlet.containers.Jetty7AsyncProvider

class Boot {
  def boot {
    // ...other stuff here...

    LiftRules.servletAsyncProvider = (req) =&amp;gt; 
        new Jetty7AsyncProvider(req)

  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thats pretty much all you need to do in order to swap comet implementations! If you want to use something else, like Resin etc, all you need to is write the correct provider and away you go.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Consistent hashing and encryption between Lift and .NET</title>
   <link href="http://timperrett.com/2009/11/11/consistent-hashing-and-encryption-between-lift-and-net"/>
   <updated>2009-11-11T14:50:00+00:00</updated>
   <id>hhttp://timperrett.com/2009/11/11/consistent-hashing-and-encryption-between-lift-and-net</id>
   <content type="html">&lt;p&gt;Its quite often that I need to pass tokens between Scala (Java also) and .NET - this instantly provides a whole raft of issues because of how the algorithms are built under the hood in the respective platforms. This short post details how you can generate consistent base64 hashes over both platforms (this can be helpful for security purposes etc)&lt;/p&gt;

&lt;h3 id='the_scala_way'&gt;The Scala way:&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;  val input = &amp;quot;sample&amp;quot; 
  val encoding = &amp;quot;UTF-8&amp;quot; 

  base64Encode(
    hexDigest(
      input.getBytes(encoding)
    ).getBytes(encoding)
  )&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='the_net_way'&gt;The .NET way&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;  using System.Security.Cryptography;

  string input = &amp;quot;sample&amp;quot;;

  SHA1CryptoServiceProvider shaHasher = 
       new SHA1CryptoServiceProvider();
  byte[] data = shaHasher.ComputeHash(
    Encoding.UTF8.GetBytes(input)
  );

  StringBuilder sBuilder = new StringBuilder();
  for (int i = 0; i &amp;lt; data.Length; i++){
    sBuilder.Append(data[i].ToString(&amp;quot;x2&amp;quot;));
  }

  string hash = sBuilder.ToString();

  Convert.ToBase64String(
    Encoding.UTF8.GetBytes(hash)
  );&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt; After I posted this code originally, it was pointed out that it would be good / helpful to show encryption as well as hashing; so here goes:&lt;/p&gt;

&lt;h3 id='the_scala_way'&gt;The Scala way:&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;  val key: Array[Byte] = &amp;quot;qwehfjgtufkgurifghfkdjfg&amp;quot;.getBytes(&amp;quot;UTF-8&amp;quot;)
  tripleDESEncrypt(&amp;quot;sample&amp;quot;, key)&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='the_net_way'&gt;The .NET way:&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;  using System.Security.Cryptography;

  string key = &amp;quot;qwehfjgtufkgurifghfkdjfg&amp;quot;;
  string toEnc = &amp;quot;sample&amp;quot;;

  TripleDESCryptoServiceProvider DES = 
       new TripleDESCryptoServiceProvider();

  byte[] bytKey = Encoding.UTF8.GetBytes(key);

  DES.Mode = CipherMode.ECB;
  DES.Key = bytKey;
  DES.Padding = PaddingMode.PKCS7;

  ICryptoTransform DESEncrypt = DES.CreateEncryptor();

  byte[] buffer = Encoding.UTF8.GetBytes(toEnc);

  string base64string = Convert.ToBase64String(
    DESEncrypt.TransformFinalBlock(buffer, 0, buffer.Length)
  );

  Response.Write(base64string);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Maybe this will help someone avoid the pain I have endured with this! lol.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Conversational Marketing with Scala and Lift</title>
   <link href="http://timperrett.com/2009/10/16/conversational-marketing-with-scala-and-lift"/>
   <updated>2009-10-16T17:10:00+01:00</updated>
   <id>hhttp://timperrett.com/2009/10/16/conversational-marketing-with-scala-and-lift</id>
   <content type="html">&lt;p&gt;As most of my readers are technical (yes, thats you there) I wont labour the marketing peice, but if your interested, David wrote a really nice article explaining his concept about what happens when social media meets cross-media; find it &lt;a href='http://david.baldaro.me.uk/2009/10/social-media-meets-cross-media/'&gt;over here&lt;/a&gt;&lt;/p&gt;

&lt;h2 id='a_cunning_scheme_indeed'&gt;A cunning scheme indeed&lt;/h2&gt;

&lt;p&gt;So, from the off, this was going to be an interesting campaign to put together because there were numerous issues, including:&lt;/p&gt;

&lt;p&gt;* Lots of concurrent (and asynchronous) read / write ops to Twitter API&lt;/p&gt;

&lt;p&gt;* Backend communication to XMPie cluster&lt;/p&gt;

&lt;p&gt;* Push production status back down to the browser&lt;/p&gt;

&lt;p&gt;* Downloading of avatar images automatically from twitter and insert into XMPie asset source&lt;/p&gt;

&lt;p&gt;* Doing any of this in the given time frame!?&lt;/p&gt;

&lt;p&gt;This project was going to have a sizeable set of works attached no doubt to manage the interplay between XMPie systems and the Twitter API.&lt;/p&gt;

&lt;h2 id='technology_sandwich'&gt;Technology Sandwich&lt;/h2&gt;

&lt;p&gt;To implement this campaign, I ended up using a whole bunch of different technologies&amp;#8230; The implementing stack eventually ended up utilising the following:&lt;/p&gt;

&lt;p&gt;* Lift&lt;/p&gt;

&lt;p&gt;* Dispatch&lt;/p&gt;

&lt;p&gt;* Scala Actors&lt;/p&gt;

&lt;p&gt;* XMPie uProduce&lt;/p&gt;

&lt;p&gt;* XMPie ICP&lt;/p&gt;

&lt;p&gt;* Microsoft SQL Server&lt;/p&gt;

&lt;p&gt;In earlier drafts of this article I tried to explain the interplay between components, but simply could not find a good way to articulate the meaning. To that end, I hope diagram gets the structure across sufficiently!:&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2009/10/16/twitter-app-design_1.jpg' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;As you can see - quite a number of software components here! I&amp;#8217;ve been working with Scala and XMPie uProduce for quite a while now and have built up some very nice abstractions that completely hide calling of services under the hood.&lt;/p&gt;

&lt;p&gt;This entire campaign was implemented based on top of ICP, using my Scala abstraction along with the awesome power of Scala Actors, scheduling and some generally very cool libraries like &lt;a href='http://databinder.net/dispatch/'&gt;Dispatch&lt;/a&gt;&lt;/p&gt;

&lt;h2 id='questions'&gt;Questions&lt;/h2&gt;

&lt;p&gt;A few people asked me to write this post, but as im not sure what specifically you might have been interested in, if you want to know more about how its put together, what does what etc then I would gladly take questions! Just leave a comment at the bottom and i&amp;#8217;ll get back to you&amp;#8230;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Replacing Checkpoint SecureClient with IPSecuritas on Snow Leopard</title>
   <link href="http://timperrett.com/2009/08/31/replacing-checkpoint-secureclient-with-ipsecuritas-on-snow-leopard"/>
   <updated>2009-08-31T21:57:00+01:00</updated>
   <id>hhttp://timperrett.com/2009/08/31/replacing-checkpoint-secureclient-with-ipsecuritas-on-snow-leopard</id>
   <content type="html">&lt;p&gt;So its that time again - another awesome Apple update to the best operating system in the world; for most, its a joyous time, one of new beginnings and wonderment&amp;#8230;. for some, alas this is just an ideal as all there proprietary software comes crumbling down under a new kernel.&lt;/p&gt;

&lt;p&gt;Friday was one of these momentous days, and yes, my world came crumbling down. For those who don&amp;#8217;t read my blog often I work remotely 85% of my working weeks as the company I work for are in another country so having a secure and speedy VPN is critical to actually getting paid and doing some work. After upgrading OSX 10.5 to Snow Leopard my Checkpoint SecureClient completely stopped working - this appears to be the plight of many users out in the interweb so I thought id write up this guide how to use IPSecuritas (as it rocks) which is infinitely better than the default checkpoint client (which sucks major ass!).&lt;/p&gt;

&lt;h3 id='why_should_i_care_about_ipsecuritas'&gt;Why should I care about IPSecuritas?&lt;/h3&gt;

&lt;p&gt;This is simple - basically (as above) it rocks and has the following great features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Its speedy.&lt;/li&gt;

&lt;li&gt;Automatic connection recovery&lt;/li&gt;

&lt;li&gt;Password persistance&lt;/li&gt;

&lt;li&gt;Can talk to a bunch of different Firewall types&amp;#8230; no more vendor tie-ins&lt;/li&gt;

&lt;li&gt;Great OSX integration&lt;/li&gt;

&lt;li&gt;Automatic connection upon login (instantly connected to VPN!)&lt;/li&gt;

&lt;li&gt;Oh, did I mention its fast?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='removing_checkpoint_secureclient'&gt;Removing Checkpoint SecureClient&lt;/h3&gt;

&lt;p&gt;OK, so now we&amp;#8217;ve established that SecureClient is evil, lets remove it. Helpfully, checkpoint took the time to provde a shell script in the install directory to do just this. Open a Terminal window (Applications &amp;gt; Utilities &amp;gt; Terminal) and type the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# i&amp;#39;m not 100% sure on the names, as im writing this from memory, 
# but just have a poke around and you&amp;#39;ll find what I mean.
timperrett$ cd /opt/C (press tab for auto-complete then return key)
timperrett$ open Uninstall.command&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Type &amp;#8220;yes&amp;#8221; when prompted - the script will then go about removing all the various components. If your thinking of skipping this step, your free to, but remember than this installation is completely broken and wont ever run under Snow Leopard as it appears to be tied to the 9.x Kernel present in 10.5&amp;#8230; so you might as well clean up and keep tidy.&lt;/p&gt;

&lt;h3 id='setting_up_ipsecuritas'&gt;Setting up IPSecuritas&lt;/h3&gt;

&lt;p&gt;If you havent already, &lt;a href='http://www.lobotomo.com/products/IPSecuritas/'&gt;download IPSecuritas from here&lt;/a&gt; - open the DMG and drag the application to your Applications directory. Once there, double click the application to load it for the first time - you&amp;#8217;ll need to enter your Administrator password then the application will install a daemon onto your system and configure itself. Once completed, take my advice and reboot your system - upon reboot you should see a new menu item that looks like a broken wire (below, dont worry about &amp;#8220;XMPie&amp;#8221;, thats just what I decided to call my profile)&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2009/8/31/ipsecuritas-menu.png' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;Choose the &amp;#8220;Open IPSecuritas&amp;#8221; menu item - and up should spring the main GUI. You now need to configure a connection - this is what you will use to connect to your VPN endpoint (clue&amp;#8217;s in the name!). Making this connection is however a rather technical process for most users so im going to post screen shots of my configuration at every stage so that you can make something similar (yours may not be identical - it really depends on the setup implemented on the firewall; however, what I detail uses common place defaults).&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2009/8/31/ipsecuritas-tab-1.png' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;So the two boxes in red are the important ones. For &lt;strong&gt;Remote IPSec Device&lt;/strong&gt; you need to fill in the domain name or IP address of your firewall / vpn endpoint; this is organisation specific so i&amp;#8217;ve removed mine. Secondly, &lt;strong&gt;Network address&lt;/strong&gt; - this is the base IP range to which you want to connect to; again, organisation specific and yours will likely be different - if you don&amp;#8217;t know, check with an IT administrator.&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2009/8/31/ipsecuritas-tab-2.png' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;These are standard security options needed to work with the checkpoint vpn - because I work long hours connected to the VPN, i&amp;#8217;ve set it to timeout after 10 hours (essentially it never cuts me off and im in charge&amp;#8230; sweet).&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2009/8/31/ipsecuritas-tab-3.png' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;Again, this is standard checkpoint stuff so just copy the configurations as is - you don&amp;#8217;t need to know whats what.&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2009/8/31/ipsecuritas-tab-4.png' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;So this is an interested panel - the two boxes ive marked in red need to be filled with your username for the VPN connection; you should have this already with that which you were using with the Checkpoint SecureClient system. In this example (and the checkpoint default) its using Hybrid RSA, but a lot of organisations use XAuth RSA etc that involve certificates etc&amp;#8230; if you need this, just use the certificate manager and configure accordingly. I&amp;#8217;ve also set it to remember my password so that I dont have to keep entering it - depending on your outlook, this is a good/bad thing. Personally, I think its a great timesaver!&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2009/8/31/ipsecuritas-tab-5.png' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;Depending on your setup, you may want to configure specilized DNS servers - you might want this if you have servers that you wish you access with a UNC style such as:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;\\somefileshare&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Without specifying those DNS, your VPN will try to use external DNS and you just wont get what you want (or expect). I&amp;#8217;ve removed mine for security reasons, but it should be fairly simple to figure out what you need to enter.&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2009/8/31/ipsecuritas-tab-6.png' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;So this is the killer panel that confuses most people - you have some fairly finite control over the connection parameters - if your using Checkpoint VPN-1, just do as I have (unless your using another authorisation mechanism) and you should succeed!&lt;/p&gt;

&lt;p&gt;Once you have all that, your good to go - just close the window, and click &amp;#8220;Start&amp;#8221; on the main IPSeceritas window then provided all went well you should get a green light next to the connection name - in my instance, i called the connection &amp;#8220;office&amp;#8221;. If you are having issues, seek help from your IT administrator as it might be a configuration issue - with VPN&amp;#8217;s your client much EXACTLY match what the endpoint is configured to&amp;#8230; any miss-match at all will result in failure; however if you wish to debug the issue yourself, bring up the connection log from the top bar menu and you&amp;#8217;ll be able to see exactly what is going on under the hood (if you need a boat load of wire information, set the logging level in preferences to DEBUG and then restart/reboot IPSecuritas)&lt;/p&gt;

&lt;p&gt;Enjoy, and good luck.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>How To: Extensive Localization with the Liftweb Framework</title>
   <link href="http://timperrett.com/2009/07/26/how-to-extensive-localization-with-the-liftweb-framework"/>
   <updated>2009-07-26T22:06:00+01:00</updated>
   <id>hhttp://timperrett.com/2009/07/26/how-to-extensive-localization-with-the-liftweb-framework</id>
   <content type="html">&lt;p&gt;One of the best things about &lt;a href='http://liftweb.net/'&gt;Lift&lt;/a&gt; is its amazingly flexible template and resource localization system. This article discusses the mechanisms that you can use to localize your application.&lt;/p&gt;

&lt;h3 id='overview'&gt;Overview&lt;/h3&gt;

&lt;p&gt;Out of the box, Lift gives you the following options - items 1 and 2 require zero boiler plate, whilst the 3rd option gives you the flexibility to extend the localization however you need.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text localization from property bundles&lt;/li&gt;

&lt;li&gt;Full template localization&lt;/li&gt;

&lt;li&gt;Custom resource bundle provider hook&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will now take a look at each localization option in turn, in relative detail stopping to investigate how they work.&lt;/p&gt;

&lt;h3 id='assumed_environment'&gt;Assumed environment&lt;/h3&gt;

&lt;p&gt;For the length of this article we&amp;#8217;ll assume that we have the need to localize into English (our default language), French, German and Hebrew. These languages have the following locale codes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;		Language 
		Code &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;English&lt;/p&gt;

&lt;p&gt;en_GB&lt;/p&gt;

&lt;p&gt;French&lt;/p&gt;

&lt;p&gt;fr_FR&lt;/p&gt;

&lt;p&gt;German&lt;/p&gt;

&lt;p&gt;de_DE&lt;/p&gt;

&lt;p&gt;Hebrew&lt;/p&gt;

&lt;p&gt;he_IL&lt;/p&gt;

&lt;p&gt;These are standard ISO codes used by the Java localization system, irrespective of Lift et al. As a bit of background for those of you not familiar with locale codes and there purpose, you can see that the first part of the locale code denotes the spoken language - for example, en is English - and the second part after the underscore is the country code. This is amazingly helpful for languages like English and Arabic which are spoken in many countries as it gives you a specific language and then culture on which you can account for language nuances etc. Salutations are a classic one - UK English might have a salutation of &amp;#8220;Good afternoon&amp;#8221; whilst Australian English might have &amp;#8220;Good ay&amp;#8217;&amp;#8220;.&lt;/p&gt;

&lt;p&gt;In order to tell Lift that this application will be localized into several languages, we have to set a customized localeCalculator. In our application it will look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  def localeCalculator(request : Box[HttpServletRequest]): Locale = 
  request.flatMap(r =&amp;gt; {
  def workOutLocale: Box[java.util.Locale] = 
  S.findCookie(localeCookieName) match {
    case Full(cookie) =&amp;gt; cookie.getValue()
    case _ =&amp;gt; Full(LiftRules.defaultLocaleCalculator(request))
  }
  tryo(r.getParameter(&amp;quot;locale&amp;quot;)) match {
    case Full(null) =&amp;gt; workOutLocale
    case Empty =&amp;gt; workOutLocale
    case Failure(_,_,_) =&amp;gt; workOutLocale
    case Full(selectedLocale) =&amp;gt; {
      setLocale(selectedLocale)
      selectedLocale
    }
  }
}).openOr(java.util.Locale.getDefault())&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add this function someplace in your application - here we&amp;#8217;ll assume its just in the Boot class, then set it in LiftRules like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;LiftRules.localeCalculator = localeCalculator _&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='text_localization_from_property_bundles'&gt;Text localization from property bundles&lt;/h3&gt;

&lt;p&gt;So, given our working languages we have several issues at hand and several strategies we could choose. Lets start with the most basic form of localization that will be familiar with most users of the java platform&amp;#8230; properties files loaded as a ResourceBundle.&lt;/p&gt;

&lt;p&gt;So lets assume that we have our translations already completed, we just need to put them into key-value pairs in properties files located in:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;`${project.basedir}/src/main/resources/mybundlename_*locale*`&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So for us, that looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mybundlename_en_GB.properties
mybundlename_fr_FR.properties
mybundlename_de_DE.properties
mybundlename_he_IL.properties&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is pretty standard stuff that is well documented in the javadocs from sun. So, you need to know how to specify value keys within lift. There are two use cases, one is in your code, and the other is in your HTML templates.&lt;/p&gt;

&lt;p&gt;In code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;S.?(&amp;quot;mykey&amp;quot;)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In template:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;lift:loc locid=&amp;quot;mykey&amp;quot;&amp;gt;Default Text&amp;lt;/lift:loc&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is all well and good, but there are use cases that simple key/value replacement doesnt take care of - with our use case languages we have a great example here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hebrew is a language that is written right-to-left (RTL) so generally the content / css / markup will be quite different&lt;/li&gt;

&lt;li&gt;Within the languages that are left-to-right (LTR), French and English have a comparable number of character tokens, but german is typically more verbose and content takes up more room.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, to deal with such cases Lift brings you comprehensive template localization which we&amp;#8217;ll now discuss.&lt;/p&gt;

&lt;h3 id='template_file_localization'&gt;Template file localization&lt;/h3&gt;

&lt;p&gt;Given this conundrum about language direction and content length lift can assert different template names. For example, lets assume that in your webapp directory you have a file called index.html - based on the LiftRules.localeCalculator Locale that is returned, it can choose the right template. With the problems we face here, we might have:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;index_en_GB.html
index_en_AU.html
index_de.html
index_he.html&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This would then yield different content templates for German and Hebrew, and gives us two distinctly different english templates for UK English and Australian English&amp;#8230; for arguments sake the imagery in the two templates could be different because Australian culture is somewhat more casual than compared to England.&lt;/p&gt;

&lt;p&gt;This exact same scheme also applies for CSS resources if you do not need the possibly side effect of code duplication in this system.&lt;/p&gt;

&lt;h3 id='custom_resource_bundle_provider_hook'&gt;Custom resource bundle provider hook&lt;/h3&gt;

&lt;p&gt;One of the driving mantras of Lift is that everything, and we mean everything has sensible defaults, but you can hook right into the core lift lifecycle and add your own stuff. Localization is no different and it is of course a common idiom to need to load localization content from a database backed cache. I wont delve into exactly how you handle the caching or similar (that my friends is up to you) but this is how you pass the special resource bundles into Lift&amp;#8217;s cycle:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;LiftRules.resourceBundleFactories.prepend { 
  case (basename, locale) if localeAvalible_?(locale) =&amp;gt; 
      CacheResourceBundle(locale)
  case _ =&amp;gt; CacheResourceBundle(new Locale(&amp;quot;en&amp;quot;,&amp;quot;GB&amp;quot;))
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the above example, localeAvalible_? checks if this locale is available (from a value in my application) and of course, CacheResourceBundle is a subclass of ResourceBundle and has the following signature:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;case class CacheResourceBundle(loc: Locale) extends ResourceBundle&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='conclusion'&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Thats pretty much it folks - by way of a mix of these schemes its possible to build up a very rich localization methodology which works for pretty much all locale needs. In this example we have discussed language lengths, RTL languages and given you all the code you need to get going with localization in Lift - go forth and localize!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Lift AMQP with RabbitMQ and Scala – Tutorial and Screencast</title>
   <link href="http://timperrett.com/2009/05/22/lift-amqp-with-rabbitmq-and-scala-tutorial-and-screencast"/>
   <updated>2009-05-22T11:39:00+01:00</updated>
   <id>hhttp://timperrett.com/2009/05/22/lift-amqp-with-rabbitmq-and-scala-tutorial-and-screencast</id>
   <content type="html">&lt;p&gt;Admitidally, every time i&amp;#8217;ve ever looked at the &lt;a href='http://liftweb.net/'&gt;Lift&lt;/a&gt; codebase in TextMate, i&amp;#8217;ve always wondered what the hell the &amp;#8220;lift-amqp&amp;#8221; module was for. Well, curiosity may have killed the cat but it was not enough of deterrent to me finding out and building a sample AMQP / RabbitMQ application!&lt;/p&gt;

&lt;h3 id='amqp_you_say'&gt;AMQP you say?&lt;/h3&gt;

&lt;p&gt;Yup, thats right. AMQP - Advanced Message Queuing Protocol to the lay&amp;#8217; man not familiar with the acronym. Essentially AMQP is an open standard for enterprise messaging. There are several implementations of the standard, namely, &lt;a href='http://www.openamq.org/'&gt;Open AMQ&lt;/a&gt; and &lt;a href='http://www.rabbitmq.com/'&gt;RabbitMQ&lt;/a&gt; - the latter is newer and generally considered to be the defacto implementation. Rabbit MQ is written in &lt;a href='http://erlang.org/'&gt;ERLang&lt;/a&gt; and has clients for Java, .NET, Ruby etc etc.&lt;/p&gt;

&lt;h3 id='so_where_does_lift_fit_in'&gt;So where does Lift fit in?&lt;/h3&gt;

&lt;p&gt;Strictly speaking, it doesn&amp;#8217;t. It just so happens that &lt;a href='http://twitter.com/stevej'&gt;Steve J&lt;/a&gt; was working on the Lift team some time ago and wrote a nifty Scala wrapper around the standard (and highly mutable) Java client implementation of Rabbit MQ. To all intense purpose, &amp;#8220;lift-amqp&amp;#8221; can be used in any Scala application and has no other dependencies within the Lift framework.&lt;/p&gt;

&lt;h3 id='handwavy_overview'&gt;Hand-wavy overview&lt;/h3&gt;

&lt;p&gt;Lets get down to business&amp;#8230; I spent quite a lot of time just looking at the source code and scala-docs for lift-amqp and for the longest while couldn&amp;#8217;t figure out what went where. Being a fairly visual person, I&amp;#8217;ve drawn up a diagram that explains the implementation and how you (yes, you reading this) would implement your application:&lt;/p&gt;

&lt;p&gt;&lt;img src='/uploads/2009/5/18/lift-amqp.jpg' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='a_working_example'&gt;A working example?&lt;/h3&gt;

&lt;p&gt;So rather than try to post lots of pictures - I thought just putting up a screen-cast explaining the components would make more sense :-)&lt;/p&gt;
&lt;embed src='http://blip.tv/play/AYGD0GoC?p=1' height='320' allowscriptaccess='always' width='100%' wmode='transparent' type='application/x-shockwave-flash' allowfullscreen='true' /&gt;
&lt;h3 id='the_client_listener'&gt;The client listener&lt;/h3&gt;

&lt;p&gt;So from the diagram above that explains the code layout - you can see that one of the first things you need to do is subclass AMQPDispatcher. The below is my example code that connects to the RabbitMQ broker and firstly declares a queue with the appropriate parameters. If you wondering why when the 2nd client connected in my example things didn&amp;#8217;t explode and complain about more than one exchange existing with the same name, thats because RabbitMQ is clever enough to know that if the queue / exchange already exists then it just Noop&amp;#8217;s the requests. Its a nice feature.&lt;/p&gt;

&lt;p&gt;class DemonstrationSerializedAMQPDispatcherTueueName: String, factory: ConnectionFactory, host: String, port: Int) extends AMQPDispatcherTactory, host, port) { override def configure(channel: Channel) { val ticket = channel.accessRequest(&amp;#8220;/data&amp;#8221;) channel.exchangeDeclare(ticket, &amp;#8220;mult&amp;#8221;, &amp;#8220;fanout&amp;#8221;) channel.queueDeclare(ticket, queueName) channel.queueBind(ticket, queueName, &amp;#8220;mult&amp;#8221;, &amp;#8220;example.&lt;em&gt;&amp;#8221;) channel.basicConsume(ticket, queueName, false, new SerializedConsumer(channel, this)) } }&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So, your probably thinking that this was not the class that I created an instance of during the screencast - and you&amp;#8217;d be right. Essentially we still need a wrapper class to mask our dispatcher; the listener proper.&lt;/p&gt;

&lt;p&gt;The purpose of the listener is to establish a connection to the broker, pass the right credentials etc. Within the listener we create an instance of the dispatcher and start its actor. We also then just have an inner class that we use for example purposes (another actor) that prints out the messages you saw in the terminal window. In reality, this would likely be passing messages to some other, external actor which handled the business process. For a full code listing see the end of this article.&lt;/p&gt;

&lt;h3 id='the_postman'&gt;The postman&amp;#8230;&lt;/h3&gt;

&lt;p&gt;So now that you know how the example listens for messages, lets see the posting code&amp;#8230;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  val params = new ConnectionParameters
  params.setUsername(&amp;quot;guest&amp;quot;)
  params.setPassword(&amp;quot;guest&amp;quot;)
  params.setVirtualHost(&amp;quot;/&amp;quot;)
  params.setRequestedHeartbeat(0)
  val factory = new ConnectionFactory(params)
  // Create a new instance of the string sender.
  // This sender will send messages to the &amp;quot;mult&amp;quot; exchange with a 
  // routing key of &amp;quot;routeroute&amp;quot; 
  val amqp = new StringAMQPSender(
    factory, &amp;quot;macbookpro&amp;quot;, 5672, &amp;quot;mult&amp;quot;, &amp;quot;example.demo&amp;quot; 
  )
  amqp.start

  /**
   * Salute the rabbit!
   */
  def salute = amqp ! AMQPMessage(&amp;quot;hey there!&amp;quot;)
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Little explanation needed here - essentially the string sender is just an actor that knows how to respond to AMQPMessage&amp;#8230;. it couldn&amp;#8217;t be simpler! I hope this has proved helpful and a good overview of the lift-amqp module.&lt;/p&gt;

&lt;p&gt;If you would like to download the source code, you can get it from &lt;a href='http://github.com/timperrett/rabbitmq-scala-tutorial/tree/master'&gt;here&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>XMPie Marketing Console for iPhone</title>
   <link href="http://timperrett.com/2009/05/20/xmpie-marketing-console-for-iphone"/>
   <updated>2009-05-20T09:54:00+01:00</updated>
   <id>hhttp://timperrett.com/2009/05/20/xmpie-marketing-console-for-iphone</id>
   <content type="html">&lt;p&gt;Its been a long time since I posted my original application for iPhone - iDashboard - to control XMPie uProduce on the move. I&amp;#8217;ve been busy with a bunch of other cool stuff and in the run up to the annual XMPie Users Group meeting in Las Vegas decided to make Marketing Console for iPhone!&lt;/p&gt;

&lt;p&gt;The application syndicates reporting and analysis information about your campaigns and lets you see the latest up-to-date charting / figures wherever you are. Currently, the application is using an internal R&amp;D; build of Marketing Console; so right now you&amp;#8217;ll have to wait before you can monitor your own campaigns on the move!&lt;/p&gt;

&lt;p&gt;If you have feedback, just leave a comment at the bottom of the article. Enjoy&amp;#8230;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Running Rabbit MQ on Mac OSX – Solving {badrpc,nodedown}</title>
   <link href="http://timperrett.com/2009/05/17/running-rabbit-mq-on-mac-osx-solving-badrpcnodedown"/>
   <updated>2009-05-17T23:06:00+01:00</updated>
   <id>hhttp://timperrett.com/2009/05/17/running-rabbit-mq-on-mac-osx-solving-badrpcnodedown</id>
   <content type="html">&lt;p&gt;Im currently exploring Rabbit MQ and had a few issues getting up and running reliably on Mac OSX. The problem wasted so much of my own free time that I thought it would be a good idea to post about it and perhaps it might help others in the future.&lt;/p&gt;

&lt;h3 id='the_problem'&gt;The Problem&lt;/h3&gt;

&lt;p&gt;The broken boots normally as the rabbitmq user defined in the system - however, when trying to connect to it using rabbitmqctl you get the following error (repeatedly):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;macbookpro:~ timperrett$ sudo rabbitmqctl status
Status of node rabbit@macbookpro ...
{badrpc,nodedown}
...done.&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='the_solution'&gt;The Solution&lt;/h3&gt;

&lt;p&gt;After many hours dabbling, and checking, checking again, rechecking my user and permissions setup, I found that it was actually to do with the way in which ERlang networks. Essentially, I was running the broker on:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rabbit@macbookpro&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, whilst I could ping the host &amp;#8220;macbookpro&amp;#8221; from terminal, it appears that Rabbit MQ needed it defined in the /etc/hosts file in order to work correctly.&lt;/p&gt;

&lt;p&gt;Both strange and annoying, perhaps this will save someone some time!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>URL Rewriting with the Lift Framework</title>
   <link href="http://timperrett.com/2009/05/03/url-rewriting-with-the-lift-framework"/>
   <updated>2009-05-03T20:39:00+01:00</updated>
   <id>hhttp://timperrett.com/2009/05/03/url-rewriting-with-the-lift-framework</id>
   <content type="html">&lt;p&gt;With my on-going effort to write more documentation and articles for &lt;a href='http://liftweb.net'&gt;Lift&lt;/a&gt; I&amp;#8217;ve decided to write a walk through of &lt;a href='http://liftweb.net'&gt;Lifts&lt;/a&gt; dispatching and rewriting mechanisms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before we start this discussion, its important that you know (and understand) the importance of partial functions in scala. If your not familiar, check out &lt;a href='http://suereth.blogspot.com/2008/11/using-partial-functions-and-pattern.html'&gt;this article&lt;/a&gt; - it should fill you in on all the particulars.&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id='application_boot'&gt;Application Boot&lt;/h3&gt;

&lt;p&gt;If your not familiar with Lift or are new, you should understand that anything of consequence that changes the application environment must in someway hook into the boot-up cycle - the default looks something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Boot {
  def boot {
    // where lift will look for snippets
    LiftRules.addToPackages(&amp;quot;eu.getintheloop.tutorial&amp;quot;)
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ok, so not a great deal going on there&amp;#8230; this is however a bare-bones lift boot class. In our case, we want to add a rewrite so that the following mappings take place:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/product/some-product-link

/** maps onto **/

./webapp/product-display.html&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Its important to note that rewriting is just that, its not used for redirects or any other such activity - its 100% for URI translation and interpretation.&lt;/p&gt;

&lt;h3 id='adding_a_rewrite'&gt;Adding a Rewrite&lt;/h3&gt;

&lt;p&gt;Pretty much all of application configuration within Lift is done through the &lt;strong&gt;LiftRules&lt;/strong&gt; object - its the central place for configuration PFs and operation vars. So, how do we use it? Well, first add the following to the top of your Boot.scala file.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import _root_.net.liftweb.http.LiftRules&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next, add the following code below the snippet package definition:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;LiftRules.rewrite.prepend(NamedPF(&amp;quot;ProductExampleRewrite&amp;quot;) {
  case RewriteRequest(
      ParsePath(&amp;quot;product&amp;quot; :: product :: Nil, _, _,_), _, _) =&amp;gt; 
    RewriteResponse(
      &amp;quot;product-display&amp;quot; :: Nil, Map(&amp;quot;product&amp;quot; -&amp;gt; product)
  )
})&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='rewrite_matching_in_detail'&gt;Rewrite matching in detail&lt;/h3&gt;

&lt;p&gt;So lets step through this part by part&amp;#8230; we already know about the LiftRules object and what its for, and one of its var properties is &amp;#8220;rewrite&amp;#8221; - a RuleSeq - and has the notion of both prepending values, and appending them. In this case, we prepend this rewrite rule, meaning that it will execute before any other rewrite rules previously added to the rewrite var.&lt;/p&gt;
&lt;code&gt;List[String]&lt;/code&gt;
&lt;pre&gt;&lt;code&gt;/**
 * options for RewriteRequest
 */
case class RewriteRequest(
  val path : ParsePath, 
  val requestType : RequestType, 
  val httpRequest : HttpServletRequest
) 

/**
 * options for ParsePath
 */
case class ParsePath(
  val partPath : List[String], 
  val suffix : String, 
  val absolute : Boolean, 
  val endSlash : Boolean
) 

/**
 * options for requestType object
 */

GetRequest
PostRequest
PutRequest
DeleteRequest&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The first argument in the RewriteRequest is a ParsePath, this is one of the primary URI matching mechanisms and enables you to define detailed paramaters on which request to match and which to ignore. Lets take a look at some various RewriteRequest examples:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/**
 * example 1.
 * matches: GET /some/demo/path
 */

RewriteRequest(
  ParsePath(&amp;quot;some&amp;quot; :: &amp;quot;demo&amp;quot; :: &amp;quot;path&amp;quot; :: Nil, &amp;quot;&amp;quot;, true, false), 
  GetRequest, _
)

/**
 * example 2.
 * matches: PUT /some/image.png
 */

RewriteRequest(
  ParsePath(&amp;quot;some&amp;quot; :: &amp;quot;image&amp;quot; :: Nil, &amp;quot;png&amp;quot;, true, false), 
  PutRequest, _
)

/**
 * example 3.
 * matches: * /some/demo/
 */

RewriteRequest(
  ParsePath(&amp;quot;some&amp;quot; :: &amp;quot;demo&amp;quot; :: &amp;quot;index&amp;quot;, &amp;quot;&amp;quot;, true, true), _, _
)

/**
 * example 4.
 * matches: GET /product/[item]/details
 */

RewriteRequest(
  ParsePath(&amp;quot;product&amp;quot; :: item :: &amp;quot;details&amp;quot; :: Nil, &amp;quot;&amp;quot;, true, true), 
    GetRequest, _
)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So far we&amp;#8217;ve seen how to configure the incoming request - to complete the picture, lets now take our request handling and couple that up with matching the response and mapping parameters so they are then available in the rest of our code via S.param.&lt;/p&gt;

&lt;p&gt;The RewriteRequest object has several overload apply methods to keep the verbosity of your code to a minimum - namely, these overloads are:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def apply(path : ParsePath, params : Map[String, String])
def apply(path : List[String])
def apply(path : List[String], suffix : String)
def apply(path : List[String], params : Map[String, String])&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can see that this gives us a bunch of flexibility depending on our needs - straight rewrite, rewrite with params etc etc. Lets take a look at some examples:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/**
 * rewrite to a html file in webapp/show.html with no params
 */

RewriteResponse(&amp;quot;show&amp;quot; :: Nil)

/**
 * rewrite to a html file in webapp/show.html with 
 * a paramater called &amp;quot;product&amp;quot; from
 * a parameter placeholder called product
 */

RewriteResponse(&amp;quot;show&amp;quot; :: Nil, Map(&amp;quot;product&amp;quot; -&amp;gt; product))

/**
 * rewrite to a html file in webapp/example.pdf with 
 * no params, but a pdf suffix
 */

RewriteResponse(&amp;quot;example&amp;quot; :: Nil, &amp;quot;pdf&amp;quot;)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We have now looked at both requests and response - so moving back to our original example I hope you can see how it now works. One thing we have no explored is how to access the various parameters you might configure in your snippets / other application code. The answer my friends, is simple:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;S.param(&amp;quot;product&amp;quot;).openOr(&amp;quot;fail over product&amp;quot;)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By now I presume you are a rewriting guru!&amp;#8230; that might be a bit overboard, but I hope you found this guide informative and useful.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>A detailed look at Lift’s view code binding system</title>
   <link href="http://timperrett.com/2009/04/13/a-detailed-look-at-lifts-view-code-binding-system"/>
   <updated>2009-04-13T16:31:00+01:00</updated>
   <id>hhttp://timperrett.com/2009/04/13/a-detailed-look-at-lifts-view-code-binding-system</id>
   <content type="html">&lt;h2 id='overview'&gt;Overview&lt;/h2&gt;

&lt;p&gt;This stuff crops up time after time again, and people are always asking about how bind() works and what they should actually be doing with it within there lift apps. I&amp;#8217;ve seen some fairly ugly abuse of scala.xml._ within Lift snippets&amp;#8230; however, not only does this tightly couple your HTML design with the snippet code behind - and thus turn into a nightmare for your designers - your missing out on some of lifts best features!&lt;/p&gt;

&lt;p&gt;All the code snippets below presume the following imports:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import _root_.scala.xml.{NodeSeq,Text,Node,Elem}
import _root_.net.liftweb.util.{Box,Full,Empty,Helpers,Log}
import _root_.net.liftweb.util.Helpers._
import _root_.net.liftweb.http.{S,SHtml}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Also, all the methods are a part of the snippet class &amp;#8220;Demo&amp;#8221;.&lt;/p&gt;

&lt;h3 id='basic_binding'&gt;Basic Binding&lt;/h3&gt;

&lt;p&gt;So, if we want to deal with a view control on the server side, we need to bind it to a namespace in the markup. In our first example, we&amp;#8217;ll just create a text input and populate its value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scala Snippet&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var tempValue: String = &amp;quot;&amp;quot; 

def exampleOne(xhtml: NodeSeq): NodeSeq = bind(&amp;quot;example&amp;quot;, xhtml,
  &amp;quot;item_one&amp;quot; -&amp;gt; SHtml.text(
   tempValue, // the &amp;quot;read&amp;quot; value
   tempValue = _), // the &amp;quot;write&amp;quot; function
  &amp;quot;submit&amp;quot; -&amp;gt; SHtml.submit(&amp;quot;Submit&amp;quot;, () =&amp;gt; Log.info(tempValue))
)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;s&lt;/p&gt;

&lt;p&gt;So, lets just review quickly. We&amp;#8217;ve made a string variable that were going to assign the value of our text field when the form is submitted. Furthermore, if you watch the console window you see that upon submission the value you entered is output to the console.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XHTML Code&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;lift:demo.example_one form=&amp;quot;post&amp;quot;&amp;gt;
  &amp;lt;p&amp;gt;Sample input: &amp;lt;example:item_one example:id=&amp;quot;demo_id&amp;quot;&amp;gt;&amp;lt;/example:item_one&amp;gt;&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;example:submit&amp;gt;&amp;lt;/example:submit&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/lift:demo.example_one&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can see how the prefix we specified in the bind function (&amp;#8220;example&amp;#8221;) is now used in the markup body of the snippet. Also, note how the actual snippet call uses snake_case (&amp;#8220;example_one&amp;#8221;) when our method is called &amp;#8220;exampleOne&amp;#8221; - Lift is clever enough to know what method you are trying to use&amp;#8230; this ensures your designers dont moan about camel cased markup!&lt;/p&gt;

&lt;h3 id='binding'&gt;Binding++&lt;/h3&gt;

&lt;p&gt;The previous example was illustrative, but pretty usless in real applications. Lets take a look at something that is a bit more feature full - namely, a small form that updates a database table using the Mapper persistence framework.&lt;/p&gt;

&lt;p&gt;Before we begin lets assume that we have a model class called &amp;#8220;User&amp;#8221;, and it has the fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;first_name - MappedString&lt;/li&gt;

&lt;li&gt;last_name - MappedString&lt;/li&gt;

&lt;li&gt;email - MappedEmail&lt;/li&gt;

&lt;li&gt;display_email - MappedBoolean&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this fictional form, users just enter their details and a new database user row is added.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scala Snippet&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; def exampleTwo(xhtml: NodeSeq): NodeSeq = {
  var user: User = new User
  def submitHandler() = {
    if(user.saveMe){
      S.redirectTo(&amp;quot;thank-you&amp;quot;)
    }
  }
  bind(&amp;quot;example&amp;quot;,xhtml,
    &amp;quot;first_name&amp;quot; -&amp;gt; SHtml.text(user.first_name, user.first_name(_)),
    &amp;quot;last_name&amp;quot; -&amp;gt; SHtml.text(user.last_name, user.last_name(_))
    &amp;quot;users_email&amp;quot; -&amp;gt; SHtml.text(user.email, user.email(_)),
    &amp;quot;display_email&amp;quot; -&amp;gt; SHtml.checkbox(false, user.display_email(_)),
    &amp;quot;submit&amp;quot; -&amp;gt; SHtml.submit(&amp;quot;Submit&amp;quot;, submitHandler _)
  )
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here we have something slightly more complex - the principals are exactly the same but with more fields and a nested method to handle the submit button. In this case, the submit button just saves a new record to the database and then if successful redirects the user to a thank-you page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XHTML Code&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;lift:demo.example_two form=&amp;quot;post&amp;quot;&amp;gt;
  &amp;lt;p&amp;gt;
    &amp;lt;label for=&amp;quot;first_name&amp;quot;&amp;gt;
      User name &amp;lt;example:first_name example:id=&amp;quot;first_name&amp;quot;&amp;gt;&amp;lt;/example:first_name&amp;gt;
    &amp;lt;/label&amp;gt;
  &amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;
    &amp;lt;label for=&amp;quot;last_name&amp;quot;&amp;gt;
      Last name &amp;lt;example:last_name example:id=&amp;quot;last_name&amp;quot;&amp;gt;&amp;lt;/example:last_name&amp;gt;
    &amp;lt;/label&amp;gt;
  &amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;
    &amp;lt;label for=&amp;quot;users_email&amp;quot;&amp;gt;
      Email &amp;lt;example:users_email example:id=&amp;quot;users_email&amp;quot;&amp;gt;&amp;lt;/example:users_email&amp;gt;
    &amp;lt;/label&amp;gt;
  &amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;
    Display your email? &amp;lt;example:display_email&amp;gt;&amp;lt;/example:display_email&amp;gt;
  &amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;example:submit&amp;gt;&amp;lt;/example:submit&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/lift:demo.example_two&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can see how we have neatly wrapped our inputs in labels (a largely view centric concern) without any changes or specific ties to the server side logic that does the database insert. This example also shows another common mistake that new-commers make&amp;#8230; there is no crazy magic binding going on between the names of the bind placeholders and what you put in them&amp;#8230; its purely a convention thing / coincidence that they are called the same. You are free to call them whatever you feel appropriate.&lt;/p&gt;

&lt;h3 id='advanced_binding'&gt;Advanced Binding&lt;/h3&gt;

&lt;p&gt;Its when you need advanced binding that lift really comes into play - lets take the oh-so common idiom of one article having many &amp;#8220;tags&amp;#8221;; as you are reading this on my blog i&amp;#8217;ll assume you are familiar with the notion.&lt;/p&gt;

&lt;p&gt;So, assuming we have a Article model object with the appropriate fields, and we have a Tag model object that has a &lt;code&gt;MappedForeignKey&lt;/code&gt; field relating back to the Article model object. We&amp;#8217;ll assume we have a utility method in the article object that grabs all the tags for that article - this will allow us to do something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;article.tags.flatMap(tag =&amp;gt; ....)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Lets get down to business:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scala Snippet&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def exampleThree(xhtml: NodeSeq): NodeSeq = { 
  // load article based on a fictional url parameter
  val article = Article.find(By(Article.link, S.param(&amp;quot;permalink&amp;quot;)))
  article.flatMap(a =&amp;gt; bind(&amp;quot;a&amp;quot;, xhtml,
    &amp;quot;body&amp;quot; -&amp;gt; Text(a.body), // outputs the article body
    &amp;quot;tags&amp;quot; -&amp;gt; a.tags.flatMap(t =&amp;gt; 
      bind(&amp;quot;t&amp;quot;, chooseTemplate(&amp;quot;tag&amp;quot;,&amp;quot;list&amp;quot;, xhtml),
        &amp;quot;name&amp;quot; -&amp;gt; Text(t.name)
      )
    )
  ))
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After loading a single article based on the URL parameter passed to the snippet by some routing or query string parameter (doing this is out of scope for this article - check on &lt;a href='http://wiki.liftweb.net'&gt;the lift wiki&lt;/a&gt;) - we can the bind the contents of that model object and also iterate over the list of tags associated with that article.&lt;/p&gt;

&lt;p&gt;The new stuff here is both the nested bind, and the chooseTemplate(&amp;#8230;) method - this actually lets us tell the binding that for this nested bind, were going to be using a set template within the passed / input XHTML. Very cool - you&amp;#8217;ll see this working in the view code below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XHTML Code&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;lift:demo.example_three&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;a:body&amp;gt;&amp;lt;/a:body&amp;gt;&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;Tagged with: &amp;lt;a:tags&amp;gt; 
  &amp;lt;tag:list&amp;gt;
    | &amp;lt;t:name&amp;gt;&amp;lt;/t:name&amp;gt; |
  &amp;lt;/tag:list&amp;gt;
&amp;lt;/a:tags&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/lift:demo.example_three&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can see how we output the normal dynamic information just as we would any other bind item, wrapping the body in a scala.xml.Text node. We then posistion the tags placeholder of the outer bind in the correct place. Following that we then define the tag template and the content inside the tag template using the &amp;#8220;t&amp;#8221; prefix we specified in the nested bind function within the exampleThree method def. This should be fairly self evident that the chooseTemplate method is selecting the tag:list template and using that for each itteration of the nested bind - this is way cool and extremely usfull in most applications.&lt;/p&gt;

&lt;p&gt;This concludes the tutorial - I hope this has been useful for someone :-)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Understanding Lift’s StreamingResponse</title>
   <link href="http://timperrett.com/2009/03/19/understanding-lifts-streamingresponse"/>
   <updated>2009-03-19T17:15:00+00:00</updated>
   <id>hhttp://timperrett.com/2009/03/19/understanding-lifts-streamingresponse</id>
   <content type="html">&lt;p&gt;I was just looking at the &lt;a href='http://github.com/dpp/liftweb/blob/d983b2136ccc578631e4927abf3db5a63bb09d2d/lift/src/main/scala/net/liftweb/http/HttpResponse.scala#L262'&gt;Lift&amp;#8217;s StreamingResponse&lt;/a&gt; and was a bit bemused by the structural type being used for the first parameter. After some fiddling around I realized that:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;data: {def read(buf: Array[Byte]): Int}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will actually make the method more flexible and not tied to a particular hierarchy of classes (and super classes). So, if your looking at &lt;a href='http://github.com/dpp/liftweb/blob/d983b2136ccc578631e4927abf3db5a63bb09d2d/lift/src/main/scala/net/liftweb/http/HttpResponse.scala#L262'&gt;Lift&amp;#8217;s StreamingResponse&lt;/a&gt; and thinking &amp;#8220;what the hell&amp;#8221;, all you need to remember is that you can pass any thing into the first parameter as long as it implements the read method with the above signature. This, IMO, is majority cool. The default thing that implements this signature is java.io.InputStream, but you could of course pass anything - even your own custom classes!&lt;/p&gt;

&lt;p&gt;A sample implementation might look like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var data: Array[Byte] = // get your data here
val headers = 
    (&amp;quot;Content-type&amp;quot; -&amp;gt; &amp;quot;application/pdf&amp;quot;) :: 
    (&amp;quot;Content-length&amp;quot; -&amp;gt; data.length.toString) :: 
    (&amp;quot;Content-disposition&amp;quot; -&amp;gt; &amp;quot;attachment; filname=download.pdf&amp;quot;) 
    :: Nil
Full(StreamingResponse(
  new java.io.ByteArrayInputStream(data),
  () =&amp;gt; {},
  data.length, 
  headers, Nil, 200)
)

&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, to recap, structural types are awesome!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Are iPhone applications the latest marketing frontier?</title>
   <link href="http://timperrett.com/2009/03/01/are-iphone-applications-the-latest-marketing-frontier"/>
   <updated>2009-03-01T20:43:00+00:00</updated>
   <id>hhttp://timperrett.com/2009/03/01/are-iphone-applications-the-latest-marketing-frontier</id>
   <content type="html">&lt;p&gt;Recently I&amp;#8217;ve noticed more and more iPhone applications being released in the run up to both film releases and real-world product launches for large purchase items such as cars. So, what do the marketing chaps want to achieve with these adventures into the world of mobile computing?&lt;/p&gt;

&lt;p&gt;Can we summarize that the marketeers see the iPhone as a lot more than just a mobile device? I think so, otherwise they simply wouldnt bother right? The thing I simply cannot get my head around, is how, or indeed if, the marketeers look to get any ROI on what must be a sizable amount of time and investment to create these iPhone apps which are usually quite sophisticated games.&lt;/p&gt;

&lt;h2 id='rhino_ball'&gt;Rhino Ball&lt;/h2&gt;

&lt;p&gt;For example, lets take &lt;a href='http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=294531474&amp;amp;mt=8'&gt;Rhino Ball&lt;/a&gt; - a pretty sophisticated 3D game in which you control a hamster in a rolling ball. Pretty amusing, but I cant say it really compelled me to go and see the film. So why bother? In times of recession and tight budgets, I simply cant fathom why they are spending money on this rather niche medium to touch a small group of people with a weak message.&lt;/p&gt;

&lt;p&gt;Perhaps this is just a prime example of marketing depts. blowing budgets for the simple reason &amp;#8220;its cool&amp;#8221;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>New Internationalization Extendability in Lift</title>
   <link href="http://timperrett.com/2009/02/28/new-internationalization-extendability-in-lift"/>
   <updated>2009-02-28T00:26:00+00:00</updated>
   <id>hhttp://timperrett.com/2009/02/28/new-internationalization-extendability-in-lift</id>
   <content type="html">&lt;p&gt;I just &lt;a href='http://github.com/dpp/liftweb/commit/6b9cb7d6c97fd69f4a565b448d8f0d3077a6047a'&gt;committed&lt;/a&gt; new functionality into &lt;a href='http://liftweb.net'&gt;lift&lt;/a&gt; master for handling the abstraction of i18n ResourceBundles&amp;#8217; that are powered by custom sources - for example, database driven localization, or hooking into some translation service.&lt;/p&gt;

&lt;p&gt;Now, you can do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; LiftRules.resourceBundleFactories.prepend { 
   case (_, locale) if locale.getISO3Language == &amp;quot;eng&amp;quot; 
      =&amp;gt; new MyResources
   case (_, locale) if locale.getISO3Language == &amp;quot;swe&amp;quot; 
      =&amp;gt; new MyResources_sv
   case (_, locale) =&amp;gt; new DBResourceLoader(locale)
 }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this example we assume that you have fictional java.util.ResourceBundle subclasses called &amp;#8220;MyResources&amp;#8221; and &amp;#8220;MyResources_sv&amp;#8221;. Furthermore, if the ISO 639-3 code is not either &amp;#8220;eng&amp;#8221; or &amp;#8220;swe&amp;#8221;, then it attempts to load it from another fictional ResourceBundle subclass &amp;#8220;DBResourceLoader&amp;#8221;.&lt;/p&gt;

&lt;p&gt;Long term, I will probably provide a ProtoDBResourceBundle or something similar, but for now, your on your own to implement the clever string and translation loading :-)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Can Open Source gain Enterprise traction through the back door?</title>
   <link href="http://timperrett.com/2009/02/16/can-open-source-gain-enterprise-traction-through-the-back-door"/>
   <updated>2009-02-16T00:37:00+00:00</updated>
   <id>hhttp://timperrett.com/2009/02/16/can-open-source-gain-enterprise-traction-through-the-back-door</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;NB: What follows is pure opinion and based on no actual metric&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As we enter the final stages of the Lift 1.0, I cant help but reflect on open source, the enterprise, and how actions taken by communities that create great projects like lift ultimately have a real and tangible benefit to companies.&lt;/p&gt;

&lt;p&gt;For a lot of organizations, open source software is generally seen as too much of a &amp;#8220;risk&amp;#8221; as their is no official support for products blah blah blah. However, it appears to me at least, that more commercial grade systems are having their open APIs integrated into OSS by the communities that power them, we are indeed seeing OSS adopting enterprise, rather than the other way around. This trend appears to be growing at a pretty quick rate with tools like SAP, Oracle and Salesforce.com (all mainstays of enterprise systems) being integrated in lots of different environments and OSS - for instance, Rails integration for salesforce, oracle middleware drivers for PHP etc etc etc.&lt;/p&gt;

&lt;p&gt;I then got to thinking - where the hell did all this integration come from? More than likely, it came from guys and girls who were hacking this stuff out with tools they would usually have access to in a enterprise environment (at the workplace). That to me appears to be a fairly sensible rational, now for the &amp;#8220;why&amp;#8221;&amp;#8230;&lt;/p&gt;

&lt;p&gt;This I fear is a little more complicated - perhaps those hackers wanted to play with it? Perhaps it was a pet project (a la google private projects)? Or maybe something else entirely? Whatever the reason, the fact remains those tools exist. Now, the really interesting thing I believe to be about this is that the next time those same developers (and perhaps their co-workers) need to complete a project, what tools might they choose to use? Something that they need to write from scratch&amp;#8230;? or something they already made in their spare time for that OSS framework or such?&lt;/p&gt;

&lt;p&gt;With platforms such as the JVM welcoming technologies like Scala, that still run on the same infrastructure yet can have a totally different code design, I think we might see more and more OSS &amp;#8220;leaking in through the backdoor&amp;#8221; into the enterprise? OK, yes, its true that most large dev environments have equally large teams to manage all the accompanying bureaucracy, but I think this type of backdoor behavior might well find traction in the SME arena and give birth to a new erea of OSS coding in the enterprise.&lt;/p&gt;

&lt;p&gt;Whatever happens - I for one really do hope that SME and Corporate companies open their eyes to what comunity powered development has to offer.&lt;/p&gt;

&lt;p&gt;Stop seeing the risk, and start appreciating the possibilities :-)&lt;/p&gt;

&lt;p&gt;Over and out.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Change in XMPie 4.5+ API user command</title>
   <link href="http://timperrett.com/2009/01/14/change-in-xmpie-4-5-api-user-command"/>
   <updated>2009-01-14T09:52:00+00:00</updated>
   <id>hhttp://timperrett.com/2009/01/14/change-in-xmpie-4-5-api-user-command</id>
   <content type="html">&lt;p&gt;I have recently been working on some API automation for &lt;a href='http://www.xmpie.com'&gt;XMPie&lt;/a&gt; uProduce and after some head scratching, realized that the username paramater has now changed format.&lt;/p&gt;

&lt;p&gt;Previously, you only needed to provide a username and password on api methods, however, in the new version it is important to include your customer name in a windows AD format. For example, if your credentials were:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Customer Name: ABC
User Name: badger
Password: 123456&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You would need to present the username in your API call like so:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ABC\badger&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I hope this save someone, somewhere, some time!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Now writing for Scala Blogs...</title>
   <link href="http://timperrett.com/2008/12/23/now-writing-for-scala-blogs"/>
   <updated>2008-12-23T17:19:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/12/23/now-writing-for-scala-blogs</id>
   <content type="html">&lt;p&gt;Yesterday &lt;a href='http://www.blogger.com/profile/14454965475839432618'&gt;Jorge Ortiz&lt;/a&gt; invited me to join the team at &lt;a href='http://scala-blogs.org'&gt;scala-blogs.org&lt;/a&gt; - obviously I was delighted, and now I will be sharing my adventures in scala both through this blog, and on scala-blogs.&lt;/p&gt;

&lt;p&gt;For my first article I&amp;#8217;ll be writing about the PayPal integration I created with David Pollak for Lift.&lt;/p&gt;

&lt;p&gt;Watch this space boys and girls, and dont forget to check out &lt;a href='http://scala-blogs.org'&gt;scala-blogs.org&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Enabling launchers and warnings with scala-maven-plugin</title>
   <link href="http://timperrett.com/2008/12/19/enabling-launchers-and-warnings-with-scala-maven-plugin"/>
   <updated>2008-12-19T12:47:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/12/19/enabling-launchers-and-warnings-with-scala-maven-plugin</id>
   <content type="html">&lt;p&gt;If your using the scala-maven plugin and need to enable some of the cool extra functionality then check out these pom.xml snippets:&lt;/p&gt;

&lt;p&gt;To enable launchers which let you do&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mvn scala:run&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;use an XML snippet like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;configuration&amp;gt;
  &amp;lt;scalaversion&amp;gt;${scala.version}&amp;lt;/scalaversion&amp;gt;
  &amp;lt;args&amp;gt;
    &amp;lt;arg&amp;gt;-target:jvm-1.5&amp;lt;/arg&amp;gt;
    &amp;lt;arg&amp;gt;-unchecked&amp;lt;/arg&amp;gt;
   &amp;lt;/args&amp;gt;
   &amp;lt;launchers&amp;gt;
     &amp;lt;launcher&amp;gt;
       &amp;lt;id&amp;gt;main-launcher&amp;lt;/id&amp;gt;
       &amp;lt;mainclass&amp;gt;com.myproj.TheMainClass&amp;lt;/mainclass&amp;gt;
       &amp;lt;args&amp;gt;
         &amp;lt;arg&amp;gt;/some/intial/argument&amp;lt;/arg&amp;gt;
       &amp;lt;/args&amp;gt;
     &amp;lt;/launcher&amp;gt;
  &amp;lt;/launchers&amp;gt;
&amp;lt;/configuration&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Also note the &amp;#8220;-unchecked&amp;#8221; compiler argument&amp;#8230; this will then prompt you if you have any deprection warnings and suggest how you could go about fixing them.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Will WADL provide a second wind for REST uptake in enterprise?</title>
   <link href="http://timperrett.com/2008/11/06/will-wadl-provide-a-second-wind-for-rest-uptake-in-enterprise"/>
   <updated>2008-11-06T20:47:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/11/06/will-wadl-provide-a-second-wind-for-rest-uptake-in-enterprise</id>
   <content type="html">&lt;p&gt;Any one who has ever implemented a SOAP consuming client service will appreciate that the tooling for various languages is a very welcome feather in SOAP&amp;#8217;s cap. Without the WSDL tooling that web service developers are accustomed to, a large portion of those developers would probably struggle to use the said service as the sher verbosity of the SOAP entity payload is simply overwhelming.&lt;/p&gt;

&lt;h2 id='rest_a_idealist_view_of_the_web_or_serious_technology'&gt;REST: A idealist view of the web or serious technology?&lt;/h2&gt;

&lt;p&gt;When REST came onto the scene it appeared to be met with two very different view points. The open source communities and web purists rejoiced&amp;#8230; a resource orientated architecture which allowed them to scrap there verbose SOAP and XML-RPC service flow. However, from what I saw first-hand, the reaction from enterprise was somewhat different; namely, one of &amp;#8220;So now we have to implement clients by hand? Sod that!&amp;#8221;.&lt;/p&gt;

&lt;p&gt;For a number of developers, including myself, we could see that REST was a much better architectural style for distributed computing on the web, but with ever decreasing budgets and squeezed time scales the added overhead of creating totally bespoke services - and therefore clients - was one that proved somewhat of a bitter pill to swallow.&lt;/p&gt;

&lt;h2 id='wadl_here_to_save_the_day'&gt;WADL: Here to save the day?&lt;/h2&gt;

&lt;p&gt;Recently, &lt;a href='https://wadl.dev.java.net/'&gt;WADL&lt;/a&gt; is coming to the fore as a structured way for providing description and automated development workflow for using REST services. &lt;a href='https://wadl.dev.java.net/'&gt;WADL&lt;/a&gt; is based around similar principles to &lt;a href='http://www.w3.org/TR/wsdl'&gt;WSDL&lt;/a&gt; in that it provides a contract of service between service resource and the client.&lt;/p&gt;

&lt;p&gt;If &lt;a href='https://wadl.dev.java.net/'&gt;WADL&lt;/a&gt; can provide a robust framework for automated tooling with REST, I really think that we&amp;#8217;ll see REST pick up a second wind of uptake in the enterprise setting. With players like Yahoo! leading by example, how long will it be before others follow suit?&lt;/p&gt;

&lt;p&gt;Only time will tell&amp;#8230;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Adding JASYPT encryption to your scala JPA entity classes</title>
   <link href="http://timperrett.com/2008/10/27/adding-jasypt-encryption-to-your-scala-jpa-entity-classes"/>
   <updated>2008-10-27T00:58:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/10/27/adding-jasypt-encryption-to-your-scala-jpa-entity-classes</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve recently been looking at how best to make sensitive user data encrpytable within JPA models when in use with lift. I came accross &lt;a href='http://www.jasypt.org/'&gt;JASYPT&lt;/a&gt; and it seems to be a really nice encryption tool. If you want to add it to your scala JPA models, do something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;package eu.getintheloop.bloglite.model

import javax.persistence._
import java.util.Date
import org.jasypt.util.password.BasicPasswordEncryptor

@Entity
@Table(){val name=&amp;quot;users&amp;quot;}
class User extends BaseEntity {
  @Id
  @GeneratedValue(){val strategy = GenerationType.IDENTITY}
  @Column(){val insertable = false, val unique = true}
  var id: Long = _

  @Column{val nullable = true}
  var first_name: String = &amp;quot;&amp;quot; 

  @Column{val nullable = true}
  var last_name: String = &amp;quot;&amp;quot; 

  @Column{val unique = true, val nullable = false}
  var username: String = &amp;quot;&amp;quot; 

  @Column{val nullable = false}
  var password_hash: String = &amp;quot;&amp;quot; 

  @Column{val unique = false, val nullable = false}
  var email: String = &amp;quot;&amp;quot; 

  @Column{val unique = false, val nullable = false}
  var is_active: Boolean = false

  def password: String = this.password_hash

  def password_=(in: String) = this.password_hash = encrypt(in)

  def authenticate(in: String): Boolean = {
    new BasicPasswordEncryptor().checkPassword(in, password) 
      &amp;amp;&amp;amp; is_active
  }

  private def encrypt(in: String): String = 
    new BasicPasswordEncryptor().encryptPassword(in)

}&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>Explictially Setting Application DocType with Lift</title>
   <link href="http://timperrett.com/2008/10/01/explictially-setting-application-doctype-with-lift"/>
   <updated>2008-10-01T10:02:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/10/01/explictially-setting-application-doctype-with-lift</id>
   <content type="html">&lt;p&gt;As you might know, I use the &lt;a href='http://liftweb.net'&gt;lift framework&lt;/a&gt; a &lt;strong&gt;lot&lt;/strong&gt; - I recently came across a strange issue where I couldnt set my own doctype in the layout template. Maybe this nugget of information will be usefull for someone:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ResponseInfo.docType = { 
  case _ if S.getDocType._1 =&amp;gt; S.getDocType._2 
  case _ =&amp;gt; Full(DocType.xhtmlStrict) 
}

/*
Avalible options are:

xhtmlTransitional
xhtmlStrict
xhtmlFrameset
xhtml11
xhtmlMobile

*/&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;UPDATE (Lift 2.1)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Be sure to use the following as ResponseInfo is deprecated.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;LiftRules.docType.default.set(r =&amp;gt; Full(DocType.xhtmlStrict))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Doing so will ensure you don&amp;#8217;t get any warnings etc during compile time.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Free your mind with FreeMind</title>
   <link href="http://timperrett.com/2008/09/30/free-your-mind-with-freemind"/>
   <updated>2008-09-30T23:44:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/09/30/free-your-mind-with-freemind</id>
   <content type="html">&lt;p&gt;Check out this great open source mind mapping tool called &lt;a href='http://freemind.sourceforge.net'&gt;FreeMind&lt;/a&gt; - I recently came accross it whilst reading &lt;a href='http://acupof.blogspot.com/2008/01/background-hibernate-comes-with-three.html'&gt;this article&lt;/a&gt; about hibernate 2nd level caching.&lt;/p&gt;

&lt;p&gt;A true testament to the power of OSS and the great software it can produce.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>World First: XMPie Dashboard Application for Apple iPhone</title>
   <link href="http://timperrett.com/2008/08/26/world-first-xmpie-dashboard-application-for-apple-iphone"/>
   <updated>2008-08-26T17:57:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/08/26/world-first-xmpie-dashboard-application-for-apple-iphone</id>
   <content type="html">&lt;p&gt;Readers of my blog will know that I love macs. Absolutely anything to do with Apple interests me; to that end, it will not surprise you that I have been doing some iPhone development.&lt;/p&gt;

&lt;p&gt;For kicks I decided to write a mobile XMPie Dashboard application which would let you control XMPie uProduce whilst out and about. Whilst this is a sheer technology demonstration, its fairly functional and a great example of how with the right knowledge and skill, absolutly anything is possible within the XMPie toolset.&lt;/p&gt;

&lt;p&gt;Below is a quick screencast demonstrating the application in all its glory!&amp;#8230;.&lt;/p&gt;

&lt;p&gt;Im interested in your thoughts, so please comment below if you feel so inclined&amp;#8230;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Running Resin Alongside Microsoft IIS</title>
   <link href="http://timperrett.com/2008/08/24/running-resin-alongside-microsoft-iis"/>
   <updated>2008-08-24T01:10:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/08/24/running-resin-alongside-microsoft-iis</id>
   <content type="html">&lt;p&gt;I recently thought that it would be good to run a Servlet container alongside IIS which is so well embedded in the clients that I deal with as they are mainly .NET types&amp;#8230;&lt;/p&gt;

&lt;p&gt;Anyone who has read my blog before will now that I have somewhat of a penchant for &lt;a href='http://caucho.com/products/resin.xtp'&gt;Resin&lt;/a&gt; - so once again, this was my choice of servlet container. Luckily for me, Caucho are awesome enough to supply an ISAPI filter which drops right into your IIS system, making Resin just an other ISAPI filter! Very sweet.&lt;/p&gt;

&lt;p&gt;If you too would like to have some Java sweetness on your M$ box, then check out &lt;a href='http://www.caucho.com/resin/doc/install-iis.xtp'&gt;this walkthrough&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>I Want To Be A Rocket Man!</title>
   <link href="http://timperrett.com/2008/08/23/i-want-to-be-a-rocket-man"/>
   <updated>2008-08-23T15:05:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/08/23/i-want-to-be-a-rocket-man</id>
   <content type="html">&lt;p&gt;I just came across this on DIGG. I wouldn&amp;#8217;t usually blog about this type of thing, but its truly amazing&amp;#8230; can you imagine if they massed produced these one day - we might be flying to work!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Hessian Kit Framework for Objective-C Released</title>
   <link href="http://timperrett.com/2008/08/09/hessian-kit-framework-for-objective-c-released"/>
   <updated>2008-08-09T16:54:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/08/09/hessian-kit-framework-for-objective-c-released</id>
   <content type="html">&lt;p&gt;This sweet new cocoa framework is now available for &lt;a href='http://sourceforge.net/projects/hessiankit'&gt;download from Sourceforge&lt;/a&gt; - if your writing anything for mac that involves client &amp;lt;-&amp;gt; server interplay, then this is certainly worth a look.&lt;/p&gt;

&lt;p&gt;Small, fast and lightweight. What more could you want?&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Enterprise Social Messaging</title>
   <link href="http://timperrett.com/2008/08/08/enterprise-social-messaging"/>
   <updated>2008-08-08T11:06:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/08/08/enterprise-social-messaging</id>
   <content type="html"></content>
 </entry>
 
 <entry>
   <title>Programatically adding Applications to the Login Items</title>
   <link href="http://timperrett.com/2008/07/28/programatically-adding-applications-to-the-login-items"/>
   <updated>2008-07-28T14:27:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/07/28/programatically-adding-applications-to-the-login-items</id>
   <content type="html">&lt;p&gt;Its taking some kicking around, but here is the fruit of my labour&amp;#8230; using core foundation over the RC bridge.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require &amp;#39;osx/cocoa&amp;#39;

loginItems = OSX::CFPreferencesCopyValue(
      &amp;quot;AutoLaunchedApplicationDictionary&amp;quot;, 
      &amp;quot;loginwindow&amp;quot;, 
      OSX::KCFPreferencesCurrentUser, 
      OSX::KCFPreferencesAnyHost)

application_path = File.expand_path(&amp;quot;~/path/to/your.app&amp;quot;)
application_hidden = false

loginItems &amp;lt;&amp;lt; OSX::NSDictionary.dictionaryWithObjects_forKeys(
    [ application_path, application_hidden ], 
    [ :Path, :Hide ])

# puts loginItems

OSX::CFPreferencesSetValue(
    &amp;quot;AutoLaunchedApplicationDictionary&amp;quot;, 
    loginItems, 
    &amp;quot;loginwindow&amp;quot;, 
    OSX::KCFPreferencesCurrentUser, 
    OSX::KCFPreferencesAnyHost)

OSX::CFPreferencesSynchronize(&amp;quot;loginwindow&amp;quot;, 
        OSX::KCFPreferencesCurrentUser, 
        OSX::KCFPreferencesAnyHost)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With any luck this might help someone :-)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Checking Network Connectivity with Ruby</title>
   <link href="http://timperrett.com/2008/07/25/checking-network-connectivity-with-ruby"/>
   <updated>2008-07-25T10:53:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/07/25/checking-network-connectivity-with-ruby</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve just been playing around with a few things and stumbled accross a really neat ruby lib called ‘timeout&amp;#8217;. I used it to make a quick check for network connectivity like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require &amp;#39;timeout&amp;#39;
require &amp;#39;socket&amp;#39;

begin
  timeout(10) do
    TCPSocket.new(&amp;quot;www.rubyforge.org&amp;quot;, 80)
  end
    puts true
rescue
  puts false
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For so few lines thats a really neat; I thought so at least! :-)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Great guide for people interested in Scala</title>
   <link href="http://timperrett.com/2008/07/17/great-guide-for-people-interested-in-scala"/>
   <updated>2008-07-17T17:33:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/07/17/great-guide-for-people-interested-in-scala</id>
   <content type="html">&lt;p&gt;I just came across a great &lt;a href='http://www.scala-lang.org/'&gt;Scala&lt;/a&gt; &lt;a href='http://developers.sun.com/learning/javaoneonline/2008/pdf/TS-5165.pdf'&gt;presentation from JavaOne&lt;/a&gt;. If your not looking at learning &lt;a href='http://www.scala-lang.org/'&gt;Scala&lt;/a&gt;, then this presentation will give you a whole heap of reasons to get up and do something about it.&lt;/p&gt;

&lt;p&gt;Download the article &lt;a href='http://developers.sun.com/learning/javaoneonline/2008/pdf/TS-5165.pdf'&gt;from here&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Website Is Down!</title>
   <link href="http://timperrett.com/2008/07/09/the-website-is-down"/>
   <updated>2008-07-09T11:57:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/07/09/the-website-is-down</id>
   <content type="html">&lt;p&gt;A friend of mine sent this to me - anyone working in IT will appreciate the funny side of this!!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Bongtastic load testing!!</title>
   <link href="http://timperrett.com/2008/07/08/bongtastic-load-testing"/>
   <updated>2008-07-08T22:56:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/07/08/bongtastic-load-testing</id>
   <content type="html">&lt;p&gt;My mind escapes me at this late hour on a Tuesday eve, but Im fairly sure i&amp;#8217;ve blogged about the &lt;a href='http://www.hpl.hp.com/research/linux/httperf/'&gt;httperf&lt;/a&gt; tool from HP Labs before.&lt;/p&gt;

&lt;p&gt;Anyway, if I havent, thats a different story, as today, I want to point you good reader to the wonderfull tool that is &lt;a href='http://bong.rubyforge.org/'&gt;Bong&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.hpl.hp.com/research/linux/httperf/'&gt;httperf&lt;/a&gt; has somewhat cryptic command syntax, and bong is a really nice wrapper around it which make leveraging the full power of &lt;a href='http://www.hpl.hp.com/research/linux/httperf/'&gt;httperf&lt;/a&gt; a breeze.&lt;/p&gt;

&lt;p&gt;Check out the &lt;a href='http://bong.rubyforge.org/'&gt;Bong home page&lt;/a&gt; for more info - I&amp;#8217;ll put up a quick tutorial when its not so late and my brain is functioning properly.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>How to use Photoshop Smart Object</title>
   <link href="http://timperrett.com/2008/06/28/how-to-use-photoshop-smart-object"/>
   <updated>2008-06-28T13:02:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/06/28/how-to-use-photoshop-smart-object</id>
   <content type="html">&lt;p&gt;I just stumbled accross &lt;a href='http://www.mydamnchannel.com/Big_Fat_Brain/You_Suck_At_Photoshop__Season_2/YouSuckAtPhotoshop11SmartObjects_803.aspx'&gt;this article&lt;/a&gt; - the subject matter certainly puts questions over the sanity of the author, but, never the less it is actually quite a good example (or tutorial if you can go that far) of how to use Smart Objects within Photoshop.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Were Moving!</title>
   <link href="http://timperrett.com/2008/06/25/were-moving"/>
   <updated>2008-06-25T15:01:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/06/25/were-moving</id>
   <content type="html">&lt;p&gt;This is just a quick note; my apologies for the lack of posting lately - its not that I haven&amp;#8217;t had anything to write about, quite the opposite&amp;#8230; but right now im preparing for a server upgrade and I have already ported the blog data, so yes, Im being a bit lazy, but we should be all ported to the new servers in a couple of weeks.&lt;/p&gt;

&lt;p&gt;So bear with me guys, Cheers&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>iPhone 3G – Roll on July 11th</title>
   <link href="http://timperrett.com/2008/06/10/iphone-3g-roll-on-july-11th"/>
   <updated>2008-06-10T12:41:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/06/10/iphone-3g-roll-on-july-11th</id>
   <content type="html">&lt;p&gt;If you havent seen it already, then where the hell have you been? iPhone 3G is comming out July 11th, and, yes, like all the other Apple disciples I shall be venturing down to my local store to get one. Sweet mother of god, just look at it&amp;#8230;. its got GPS and everything&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;img src='http://blog.timperrett.com/assets/2008/6/10/iphone-3g.jpg' alt='' /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Amazon EC2; Could This Be The Best Computing Platform Ever?</title>
   <link href="http://timperrett.com/2008/06/09/amazon-ec2-could-this-be-the-best-computing-platform-ever"/>
   <updated>2008-06-09T23:28:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/06/09/amazon-ec2-could-this-be-the-best-computing-platform-ever</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve recently started using &lt;a href='http://aws.amazon.com/ec2'&gt;Amazon EC2&lt;/a&gt; and put quite simply, it could well be the best computing platform the world has ever seen! Its flexible, scalable, and &lt;a href='http://calculator.s3.amazonaws.com/calc5.html'&gt;very competitively priced&lt;/a&gt; which makes it an attractive proposition for users that are currently on fixed priced virtual machine hosting.&lt;/p&gt;

&lt;p&gt;The real differentiator with &lt;a href='http://aws.amazon.com/ec2'&gt;EC2&lt;/a&gt; is that you are effectively building a linux machine from scratch that can be flug around there cloud to any location. So, that means you could make an image of your running machine using there &lt;a href='http://developer.amazonwebservices.com/connect/entry.jspa?externalID=368'&gt;AMI Tools&lt;/a&gt; and have your box running in East Coast America. Pretty straight forward so far. You then get wind (pun intended) that a massive hurricane is about to hit the East Coast, and you&amp;#8217;d feel safer if your servers were far far away, right? No problem, with a simple one line command you can re-deploy the image to the West Coast cloud and everything would just pick up where it left off! Amazing!&lt;/p&gt;

&lt;p&gt;On top of all that clever trickery, you get pretty decent control over firewall ACL&amp;#8217;s and the choice of box configuration is pretty decent - the ‘small&amp;#8217; machine still has 1.7GB of RAM, which is a boat load more than most of VM&amp;#8217;s on the market. You can even get 7.5GB and 15GB variants.&lt;/p&gt;

&lt;p&gt;Amazon, you have out-done yourselves. Congratulations!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>How To Fix Generating XMPie API Java Stubs With Metro</title>
   <link href="http://timperrett.com/2008/06/06/how-to-fix-generating-xmpie-api-java-stubs-with-metro"/>
   <updated>2008-06-06T17:39:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/06/06/how-to-fix-generating-xmpie-api-java-stubs-with-metro</id>
   <content type="html">&lt;p&gt;As a number of you are aware, I have spent quite a bit of time wrestling with XMPie uProduce SOAP API with the CXF service framework in Java. I finally (and with quite a lot of disappointment on my part) gave up trying to get that to work. CXF just does not want to play nice and I cant seem to make the XJB bindings work correctly with it and the mish-mash WSDL coming from uProduce&lt;/p&gt;

&lt;p&gt;Anyway&amp;#8230; with that rant over, I tried to be objective and switched to using &lt;a href='https://metro.dev.java.net/'&gt;Metro&lt;/a&gt; - ok, out of the box I still had a whole heap of problems, exactly as I did with CXF. However, I have managed to wangle it!&lt;/p&gt;

&lt;h3 id='step_1'&gt;Step 1&lt;/h3&gt;

&lt;p&gt;You will need access to an XMPie server with the API&amp;#8217;s installed and working. For the sake of this example i just wget&amp;#8217;d the WSDL file so the generation code was not so bloated.&lt;/p&gt;

&lt;h3 id='step_2'&gt;Step 2&lt;/h3&gt;

&lt;p&gt;You&amp;#8217;ll need an XSD XJB binding file which looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;bindings xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot; xmlns=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot; xmlns:xsd=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot; version=&amp;quot;2.0&amp;quot;&amp;gt;

  &amp;lt;globalbindings&amp;gt;
    &amp;lt;xjc:simple&amp;gt;&amp;lt;/xjc:simple&amp;gt;
  &amp;lt;/globalbindings&amp;gt;

  &amp;lt;bindings scd=&amp;quot;~xsd:complexType&amp;quot;&amp;gt;
    &amp;lt;class name=&amp;quot;ComplexTypeType&amp;quot;&amp;gt;&amp;lt;/class&amp;gt;
  &amp;lt;/bindings&amp;gt;

  &amp;lt;bindings scd=&amp;quot;~xsd:simpleType&amp;quot;&amp;gt;
    &amp;lt;class name=&amp;quot;SimpleTypeType&amp;quot;&amp;gt;&amp;lt;/class&amp;gt;
  &amp;lt;/bindings&amp;gt;

  &amp;lt;bindings scd=&amp;quot;~xsd:group&amp;quot;&amp;gt;
    &amp;lt;class name=&amp;quot;GroupType&amp;quot;&amp;gt;&amp;lt;/class&amp;gt;
  &amp;lt;/bindings&amp;gt;

  &amp;lt;bindings scd=&amp;quot;~xsd:attributeGroup&amp;quot;&amp;gt;
    &amp;lt;class name=&amp;quot;AttributeGroupType&amp;quot;&amp;gt;&amp;lt;/class&amp;gt;
  &amp;lt;/bindings&amp;gt;

  &amp;lt;bindings scd=&amp;quot;~xsd:element&amp;quot;&amp;gt;
    &amp;lt;class name=&amp;quot;ElementType&amp;quot;&amp;gt;&amp;lt;/class&amp;gt;
  &amp;lt;/bindings&amp;gt;

  &amp;lt;bindings scd=&amp;quot;~xsd:attribute&amp;quot;&amp;gt;
    &amp;lt;class name=&amp;quot;attributeType&amp;quot;&amp;gt;&amp;lt;/class&amp;gt;
  &amp;lt;/bindings&amp;gt;
&amp;lt;/bindings&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Save this as xsd.xjb (or whatever you like, just make sure the name is reflected in the command below)&lt;/p&gt;

&lt;h3 id='step_3'&gt;Step 3&lt;/h3&gt;

&lt;p&gt;Actually generate the code! Your command might look different, but heres mine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  wsimport -b http://www.w3.org/2001/XMLSchema.xsd \
    -b src/xjb/xsd.xjb \
    -keep \
    -s src/java \
    -d target \
    -p com.xmpie.wsapi.icp \
    src/wsdl/InteractiveCampaign_SSP.wsdl&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should then see something like the following in your finder (or other OS file browser if not on mac):&lt;/p&gt;

&lt;p&gt;&lt;img src='http://blog.timperrett.com/assets/2008/6/6/metro-icp.gif' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;These are the class files created for the InteractiveCampaign WSDL - all 128 of them!&lt;/p&gt;

&lt;p&gt;Anyway, I have run out of time for today, but will try and get another blog up soon about how to use this in a client application from a java CLI.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Creo Darwin Set To Hot Up VDP Competition</title>
   <link href="http://timperrett.com/2008/06/06/creo-darwin-set-to-hot-up-vdp-competition"/>
   <updated>2008-06-06T14:54:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/06/06/creo-darwin-set-to-hot-up-vdp-competition</id>
   <content type="html">&lt;p&gt;Whilst at &lt;a href='http://drupa.com'&gt;Drupa&lt;/a&gt; I was lucky enough to get a back room showing of what &lt;a href='http://www.creoservers.com/'&gt;Creo&lt;/a&gt; will be releasing in Q4 of 2008 and into 2009.&lt;/p&gt;

&lt;p&gt;The first impressions are really great - the native UI (Cocoa on OSX and .NET windowing on WinTel) means that no matter what your platform you get widgets that you are familiar with and work seamlessly with the operating system. That really is quite a differentiator when compared to competing products, and one that I am sure a lot of people would welcome as even from personal experience, quite a number of other solutions are using SWNG, or, god forbid, AWT in Java which are clunky and just not up to the modern users expectations.&lt;/p&gt;

&lt;h3 id='plugins'&gt;Plugins&lt;/h3&gt;

&lt;p&gt;One of the things that really is very good about Darwin is the plugin system they have devised. Whilst I currently have no information on what inner complexities one might face with implementing your own plugin, the architecture I was shown looked very open, and very friendly - which is a massive plus point in my eyes.&lt;/p&gt;

&lt;h3 id='performance'&gt;Performance&lt;/h3&gt;

&lt;p&gt;Darwin was awesomely quick too - speed and beauty in the same package! Eliot Harper has blogged some very nice performance testing between &lt;a href='http://www.xmpie.com/'&gt;XMPie&lt;/a&gt; uDirect and &lt;a href='http://www.creoservers.com/'&gt;Creo&lt;/a&gt; Darwin which can be &lt;a href='http://www.veedeepee.com/2007/11/darwin_vs_udirect.html'&gt;found here&lt;/a&gt;&lt;/p&gt;

&lt;h3 id='integration'&gt;Integration&lt;/h3&gt;

&lt;p&gt;&lt;a href='http://www.creoservers.com/'&gt;Creo&lt;/a&gt; have changed the way in which the Darwin working environment is persisted - its now a separate DVJ file. This means that when working with InSite, the system can automagically create the darwin files for you. I&amp;#8217;d go out on a limb and say that if InSite is able to create those files, then any other system you might want to write would also be able to generate DVJ files - this could really create some interesting options for mash-up style workflows!&lt;/p&gt;

&lt;h3 id='what_about_the_cons'&gt;What About The Cons?&lt;/h3&gt;

&lt;p&gt;Ok, so all products have there cons - thats life - at the moment Darwin only supports flat file data-sources. Perhaps that will change over time, but we&amp;#8217;ll see I guess. Release is quite some time off so who knows what those guys might come up with!&lt;/p&gt;

&lt;p&gt;Kudos &lt;a href='http://www.creoservers.com/'&gt;Creo&lt;/a&gt; , this really is great work.&lt;/p&gt;

&lt;p&gt;Another interesting article about Darwin and InSite can be &lt;a href='http://www.veedeepee.com/2008/05/darwin_v3_insite_v4_1.html'&gt;found here&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>ProJet 3D Printer for Engineering Prototypes</title>
   <link href="http://timperrett.com/2008/06/06/projet-3d-printer-for-engineering-prototypes"/>
   <updated>2008-06-06T14:26:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/06/06/projet-3d-printer-for-engineering-prototypes</id>
   <content type="html">&lt;p&gt;This post is a bit off of the usual code focused articles I write, but having just arrived back from &lt;a href='http://www.drupa.com/'&gt;Drupa&lt;/a&gt; I feel that I just need to write a quick post about this as I really did think it was awesome!&lt;/p&gt;

&lt;p&gt;The product in question is &lt;a href='http://www.3dsystems.com/products/projet/index.asp'&gt;3D Systems ProJet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No word of a lie, this machine can &amp;#8220;print&amp;#8221; 3D models of things via an InkJet process - it really is amazing the fine, granular control they have over how it works its magic. Like I said, very off topic, but freaking awesome at the same time!!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Is Facebook lowering user expectations?</title>
   <link href="http://timperrett.com/2008/05/28/is-facebook-lowering-user-expectations"/>
   <updated>2008-05-28T07:05:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/05/28/is-facebook-lowering-user-expectations</id>
   <content type="html">&lt;p&gt;How many times have you been using &lt;a href='http://www.facebook.com'&gt;Facebook&lt;/a&gt; and received the &amp;#8220;Sorry, an error has occurred. We&amp;#8217;re working on getting this fixed as soon as we can.&amp;#8221; message?&lt;/p&gt;

&lt;p&gt;This appears to happen fairly often (relativly speaking) from what I can see. I wonder if this lowers peoples expectations of what uptime they should expect from the big web 2.0 platforms? For instance, I dont ever remember getting such a message on YouTube&amp;#8230; but then again a whole lot more people use facebook than use YouTube&amp;#8230;&lt;/p&gt;

&lt;p&gt;I guess my question is this&amp;#8230; Is it acceptable to be having public downtime on such sites/services that are becoming such a part of everyday society? I would say no, its not. Were told that facebook has somewhere in the region of 10,000 servers! So goodness knows why with 10K servers they cant get a decent amount of uptime for most users.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Zero Turnaround Release Open Source Version of JavaRebel Just for Scala</title>
   <link href="http://timperrett.com/2008/05/21/zero-turnaround-release-open-source-version-of-javarebel-just-for-scala"/>
   <updated>2008-05-21T09:57:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/05/21/zero-turnaround-release-open-source-version-of-javarebel-just-for-scala</id>
   <content type="html">&lt;p&gt;Its been in the wings for some time now but the announcement has finally been made public. This is great news as it means that when were coding in Scala the classes in your web container will automatically be updated without the need to restart the container and redeploy the WAR.&lt;/p&gt;

&lt;p&gt;For more on this check out &lt;a href='http://www.zeroturnaround.com/news/scala-goes-dynamic-with-javarebel/'&gt;the announcement&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Using Embedded Resin as a Development Container</title>
   <link href="http://timperrett.com/2008/05/19/using-embedded-resin-as-a-development-container"/>
   <updated>2008-05-19T08:24:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/05/19/using-embedded-resin-as-a-development-container</id>
   <content type="html">&lt;p&gt;I recently read &lt;a href='http://weblogs.java.net/blog/vivekp/archive/2008/05/scala_lift_web.html'&gt;this article&lt;/a&gt; and realised that I had never blogged about the resin plugin that works perfectly with lift for development and deployment.&lt;/p&gt;

&lt;p&gt;Heres what you need to add to your pom.xml&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    &amp;lt;build&amp;gt;
   ...
   &amp;lt;finalname&amp;gt;${project.name}&amp;lt;/finalname&amp;gt;
   ...
    
      &amp;lt;plugin&amp;gt;
        &amp;lt;groupid&amp;gt;com.caucho&amp;lt;/groupid&amp;gt;
        &amp;lt;artifactid&amp;gt;resin-maven-plugin&amp;lt;/artifactid&amp;gt;
        &amp;lt;version&amp;gt;3.1.6&amp;lt;/version&amp;gt;
        &amp;lt;configuration&amp;gt;
          &amp;lt;contextpath&amp;gt;/&amp;lt;/contextpath&amp;gt;
        &amp;lt;/configuration&amp;gt;
      &amp;lt;/plugin&amp;gt;
    ...
&amp;lt;/build&amp;gt;

&amp;lt;pluginrepositories&amp;gt;
...
&amp;lt;pluginrepository&amp;gt;
  &amp;lt;id&amp;gt;caucho&amp;lt;/id&amp;gt;
  &amp;lt;name&amp;gt;Caucho&amp;lt;/name&amp;gt;
  &amp;lt;url&amp;gt;http://caucho.com/m2&amp;lt;/url&amp;gt;
&amp;lt;/pluginrepository&amp;gt;
...
&amp;lt;/pluginrepositories&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note, the final name var is important, as thats what resin uses to point at. Dont worry tho, as lift already has a name element so provided you haven&amp;#8217;t deleted it, your laughing.&lt;/p&gt;

&lt;p&gt;Next, to boot the server, just do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    mvn resin:run&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That should be it! Enjoy!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Exposing Lift Components via Hessian/Burlap with Resin Container</title>
   <link href="http://timperrett.com/2008/05/05/exposing-lift-components-via-hessianburlap-with-resin-container"/>
   <updated>2008-05-05T19:51:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/05/05/exposing-lift-components-via-hessianburlap-with-resin-container</id>
   <content type="html">&lt;p&gt;Right, as you know, I use the &lt;a href='http://liftweb.net/index.php/Main_Page'&gt;lift&lt;/a&gt; framework a lot these days. I also use &lt;a href='http://caucho.com/products/resin.xtp'&gt;Resin&lt;/a&gt; as my choice container. So, i recently got to thinking, wouldn&amp;#8217;t it be cool if i could just bosh together a simple way to expose controllers in lift via the groovy protocols made available by &lt;a href='http://caucho.com/products/resin.xtp'&gt;Resin&lt;/a&gt; - well, I have here an example of just such a thing.&lt;/p&gt;

&lt;h3 id='lift_side'&gt;Lift Side&lt;/h3&gt;

&lt;p&gt;Ok, before anyone has a poke at this code&amp;#8230; it was a very quick and dirty example, so its not ideal, and obviously your code would be a whole lot more complex, but this article is just about proving concept.&lt;/p&gt;

&lt;p&gt;I set up the object that I want to expose via remoting. Critically, there would be nothing stopping me using the persistance built into lift, or anything else available to java or scala for that matter. The key is the traits&amp;#8230; as they are like java interfaces (broadly speaking), they let resin know what methods it can call.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;package com.timperrett.resin.example.controller

trait HelloTrait {
  def hello: String
}
class HelloWorld extends Object with HelloTrait {
  def hello = &amp;quot;Hello from lift&amp;quot; 
}&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='resin_configuration'&gt;Resin Configuration&lt;/h3&gt;

&lt;p&gt;Next, we add a bit of config to resin so that it knows how/where to expose the service. Critically, we could have used Hessian, Burlap or CXF (for SOAP) and all by being pushed out of the container with zero extra effort.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; &amp;lt;web-app root-directory=&amp;quot;webapps/lift-remoting-example&amp;quot; id=&amp;quot;/lift-remoting-example&amp;quot;&amp;gt;
  &amp;lt;servlet-mapping url-pattern=&amp;quot;/api/hello-world&amp;quot; servlet-class=&amp;quot;com.timperrett.resin.example.controller.HelloWorld&amp;quot;&amp;gt;
    &amp;lt;protocol uri=&amp;quot;hessian:&amp;quot;&amp;gt;&amp;lt;/protocol&amp;gt;
  &amp;lt;/servlet-mapping&amp;gt;
&amp;lt;/web-app&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='client_side_in_another_language'&gt;Client Side (in another language!)&lt;/h3&gt;

&lt;p&gt;To proove the point, I thought I would just make a simple client in another language (namely ruby):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require &amp;#39;rubygems&amp;#39;
require &amp;#39;hessian&amp;#39;

url = http://127.0.0.1:8080/lift-remoting-example/api/hello-world
client = Hessian::HessianClient.new(url)
puts client.hello&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Again, a very simple example, but one that proves the point. You should then see &amp;#8220;Hello from lift&amp;#8221; output in the terminal window.&lt;/p&gt;

&lt;h3 id='project_files'&gt;Project Files&lt;/h3&gt;

&lt;p&gt;You can download my example &lt;a href='http://download.timperrett.com/pub/lift-resin-remoting-example.zip'&gt;from here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you found this article interesting, or have played with this yourself also, then by all means leave a comment or get in touch.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Hessian and Burlap for API transit</title>
   <link href="http://timperrett.com/2008/05/02/hessian-and-burlap-for-api-transit"/>
   <updated>2008-05-02T13:59:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/05/02/hessian-and-burlap-for-api-transit</id>
   <content type="html">&lt;h2 id='web_services_for_api_mehhh_havent_we_heard_all_this_before'&gt;Web Services for API? Mehhh, haven&amp;#8217;t we heard all this before?&lt;/h2&gt;

&lt;p&gt;Well, frankly, yes, you probably have. But you might not have had the full story. Im not talking about SOAP or other such protocols that require a serious amount of time at remoting-protacol-fat-camp&amp;#8230; Today I would like to take some time to talk about the Burlap and Hessian protocols. For the astute readers, yes, those are the same ones that I was banging on about in a previous post when talking about hot technology for 2008. They are both slick remoting systems that run on Resin (they probably can be run on other JEE servers too, but frankly I haven&amp;#8217;t tried), and according the chaps at Caucho:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Hessian and Burlap are compact binary and XML protocols for applications needing performance without protocol complexity. Hessian is a small binary protocol. Burlap is a matching XML protocol. Providing a web service is as simple as creating a servlet.&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sounds pretty cool doesn&amp;#8217;t it? Well they are. I have been playing with Resin running these protocols and evaluating them as methods for creating robust API which 3rd parties can easily integrate with. Before reflecting on what I have experienced during these trials with Burlap/Hessian I would have instantly said that Hessian was better, but then I got to reflecting on use in the world: is it really practical to use binary remoting protocols for services that the 3rd party user does not know well? I think about the times in which I have been developing clients to services I don&amp;#8217;t know (or didnt build for that matter) and I do usually end up looking at the message body when trying to troubleshoot any issues that might arise - and Hessian would be totally unworkable in that instance.&lt;/p&gt;

&lt;p&gt;Anyway, to conclude, if you or a partner company are working in tandem and have a good working relationship then sure, its got to be Hessian all the way; its fast, its light weight&amp;#8230; its all good. However if your exposing services for developers at a 3rd party, then you should really consider Burlap, as it could make someone else&amp;#8217;s life so much easier. On the other hand, you could just be greedy and use Resin to expose Hessian, Burlap and SOAP!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Flash goes open source!</title>
   <link href="http://timperrett.com/2008/05/01/flash-goes-open-source"/>
   <updated>2008-05-01T23:48:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/05/01/flash-goes-open-source</id>
   <content type="html">&lt;p&gt;It appears that flash has finally gone open source - craziness all round from Adobe at the moment.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://aralbalkan.com/1332'&gt;http://aralbalkan.com/1332&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Papervision 3D Trailer</title>
   <link href="http://timperrett.com/2008/04/28/papervision-3d-trailer"/>
   <updated>2008-04-28T10:08:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/04/28/papervision-3d-trailer</id>
   <content type="html">&lt;p&gt;I appreciate this is a little late in terms of the papervision bandwagon, but I only came across this on the tube this morning. A truly awesome display of what the latest version of flash + papervision is capable of:&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Geek Honors: Joins Scala Lift Core Team</title>
   <link href="http://timperrett.com/2008/04/24/geek-honors-joins-scala-lift-core-team"/>
   <updated>2008-04-24T23:17:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/04/24/geek-honors-joins-scala-lift-core-team</id>
   <content type="html">&lt;p&gt;My appologies; I hardly ever blow my own trumpet on this blog, but I just cant let &lt;a href='http://groups.google.com/group/liftweb/browse_thread/thread/73de06d51a42c5d1'&gt;this one&lt;/a&gt; pass without a good old toot of the proverbial horn.&lt;/p&gt;

&lt;p&gt;Today I joined the &lt;a href='http://liftweb.net/index.php/Main_Page'&gt;lift&lt;/a&gt; committers. That might not sound much, but when you think that &lt;a href='http://liftweb.net/index.php/Main_Page'&gt;lift&lt;/a&gt; will be the next Ruby on Rails size phenomenon to hit the development community, thats pretty dang awesome.&lt;/p&gt;

&lt;p&gt;I shall toot no more - respect to David and the rest of the other guys on &lt;a href='http://liftweb.net/index.php/Main_Page'&gt;lift&lt;/a&gt; core&amp;#8230; you freaking rock!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Accessing OSX Network Interfaces From  Wireshark X11</title>
   <link href="http://timperrett.com/2008/04/23/accessing-osx-network-interfaces-from-wireshark-x11"/>
   <updated>2008-04-23T11:57:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/04/23/accessing-osx-network-interfaces-from-wireshark-x11</id>
   <content type="html">&lt;p&gt;Just a short post for people who might not be sure how to get Wireshark to read the interfaces from your mac&amp;#8230;&lt;/p&gt;

&lt;p&gt;I had to run the applications as root:wheel to let the X11 interface read the network interface devices. To do the same, just run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;sudo /Applications/Wireshark.app/Contents/MacOS/Wireshark&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, when prompted, just enter your password (provided you are a machine administrator that is). Wireshark X11 should then boot up and work without problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If your on 10.4 you will need to install X11 beforehand&lt;/strong&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>NGINX (Engine-X) Rewrite Rules For CakePHP</title>
   <link href="http://timperrett.com/2008/04/17/nginx-engine-x-rewrite-rules-for-cakephp"/>
   <updated>2008-04-17T18:59:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/04/17/nginx-engine-x-rewrite-rules-for-cakephp</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve been doing some work with &lt;a href='http://wiki.codemongers.com/Main'&gt;NGINX&lt;/a&gt; of late and anyone familiar with &lt;a href='http://www.cakephp.org/'&gt;CakePHP&lt;/a&gt; will know that it ships out of the box with Apache .htaccess files to make sure that the URL&amp;#8217;s are devoid of there query string.&lt;/p&gt;

&lt;p&gt;Anyway, enough talk, if you want to host cakephp on NGINX, you&amp;#8217;ll need to use a vhost like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    server { 
        listen       80;
        server_name  somedomain.com;
        access_log  /var/www/logs/somedomain.access.log  main;
        error_log   /var/www/logs/somedomain.error.log info;
        rewrite_log on;

        # rewrite rules for cakephp
        location / {
          root   /var/www/sites/somedomain.com/current;
          index  index.php index.html;

          # If the file exists as a static file serve it 
          # directly without running all
          # the other rewite tests on it
          if (-f $request_filename) { 
            break; 
          }
          if (!-f $request_filename) {
            rewrite ^/(.+)$ /index.php?url=$1 last;
            break;
          }
        }

        location ~ \.php$ {
          fastcgi_pass 127.0.0.1:9000;
          fastcgi_index index.php;
          fastcgi_param SCRIPT_FILENAME \
          /var/www/sites/somedomain.com/current$fastcgi_script_name;
          include fastcgi_params;
        }
    }&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>Apache CXF Graduates From The Incubator</title>
   <link href="http://timperrett.com/2008/04/16/apache-cxf-graduates-from-the-incubator"/>
   <updated>2008-04-16T23:12:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/04/16/apache-cxf-graduates-from-the-incubator</id>
   <content type="html">&lt;p&gt;Today was the day that &lt;a href='http://incubator.apache.org/cxf/'&gt;Apache CXF&lt;/a&gt; graduated out of the incubator and will now become a full bonafied apache project. This is such brilliant news as it means that CXF &lt;strong&gt;should&lt;/strong&gt; replace Apache Axis and Xfire as the defaco Java services framework.&lt;/p&gt;

&lt;p&gt;Congratulations to &lt;a href='http://www.dankulp.com'&gt;Dan Kulp&lt;/a&gt; and the rest of the CXF team - all the sterling work has paid off after about 20+ months of rocking development.&lt;/p&gt;

&lt;p&gt;I wish them all the best for the future - CXF will be a big hit!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Tutorial: Getting Started with Apache CXF</title>
   <link href="http://timperrett.com/2008/04/12/tutorial-getting-started-with-apache-cxf"/>
   <updated>2008-04-12T12:53:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/04/12/tutorial-getting-started-with-apache-cxf</id>
   <content type="html">&lt;p&gt;If you are looking to lean CXF, then you should really read this:&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.jroller.com/gmazza/entry/using_strikeiron_s_super_data'&gt;http://www.jroller.com/gmazza/entry/using_strikeiron_s_super_data&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was one of the best written tutorials I managed to find and covers both Maven and Ant compilation.&lt;/p&gt;

&lt;p&gt;Kudos Glen!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Java Is Not A Dirty Word…</title>
   <link href="http://timperrett.com/2008/04/11/java-is-not-a-dirty-word"/>
   <updated>2008-04-11T11:01:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/04/11/java-is-not-a-dirty-word</id>
   <content type="html">&lt;p&gt;Strong title I know&amp;#8230; It feels like thats how Java is regarded these days - Ruby and Python are becoming the golden boys of programming choice and poor ol&amp;#8217; java is being left out in the cold because people only remember it as having crap costing/license models where you &lt;span&gt;the developer&lt;/span&gt; needed to pay for everything.&lt;/p&gt;

&lt;p&gt;Well, I have good news for you my friends, Java should no longer be a dirty word! The inertia that Ruby on Rails had in the Java community did cause quite a lot of controversy its true, but its almost like after the initial xenophobia had worn off they sat up and thought &amp;#8220;you know what, these guys might actually be onto something here&amp;#8221;. I recently got into using &lt;a href='http://maven.apache.org/'&gt;Maven 2&lt;/a&gt;, and god, my good god, its a million times better than Ant, which just sucked so badly I cant explain! For anyone who is familiar with &lt;a href='http://rake.rubyforge.org/'&gt;Rake&lt;/a&gt;, &lt;a href='http://maven.apache.org/'&gt;Maven&lt;/a&gt; is like &lt;a href='http://rake.rubyforge.org/'&gt;Rake&lt;/a&gt;, but with all the package management stuff built right in - it does still have a certain level of entry required, but it just simplifies the process of created projects and managing dependencies in a very streamlined way.&lt;/p&gt;

&lt;p&gt;The language itself has evolved quite a lot too - the new &lt;a href='http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html'&gt;annotations&lt;/a&gt; are used heavily be JEE apps and frameworks - take &lt;a href='http://incubator.apache.org/cxf/'&gt;CXF&lt;/a&gt; as an example; it will eventually replace XFire and Axis2 as the premier SOAP/WebService framework for Java, its a very very powerful tool and pretty easy to use (relatively speaking)&lt;/p&gt;

&lt;p&gt;Anyway, I digress&amp;#8230; my point is that if, like me, you left Java because the last time you worked with it you were slogging it out with 1.4 and Ant hell, then perhaps its time you took another look? Java has had &lt;strong&gt;significant&lt;/strong&gt; investment as a platform, and there is a hell of a lot of good code out there for doing pretty much anything you can think of. In all honesty, one of the main reasons I have come back to &lt;a href='http://java.sun.com/javaee/technologies/javaee5.jsp'&gt;JEE&lt;/a&gt; and the &lt;a href='http://en.wikipedia.org/wiki/Java_Virtual_Machine'&gt;JVM&lt;/a&gt; in general is deployment - the &lt;a href='http://en.wikipedia.org/wiki/Java_Virtual_Machine'&gt;JVM&lt;/a&gt; is very robust, and the containers built of top of it like &lt;a href='http://caucho.com/products/resin.xtp'&gt;Resin&lt;/a&gt; and &lt;a href='https://glassfish.dev.java.net/'&gt;Glassfish&lt;/a&gt; are being used in very high-concurrency environments and the deployment method via JAR or WAR is just so much more robust than on a platform like Ruby - and thats coming from having spent nearly the past 3 years solidly coding Ruby and doing all manner of deployments!&lt;/p&gt;

&lt;p&gt;Dont write Java off - its an amazing platform, so what if its not as easy to get started as with other languages; think long-term, its a language that will grow with you rather than one you might someday reach the ceiling of - or just find incredibly annoying when the application dispatchers crash for a past time ;-)&lt;/p&gt;

&lt;p&gt;Over and out&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>One Click Installer for Apache Maven 2.0.8 on Mac OSX</title>
   <link href="http://timperrett.com/2008/04/10/one-click-installer-for-apache-maven-2-0-8-on-mac-osx"/>
   <updated>2008-04-10T10:06:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/04/10/one-click-installer-for-apache-maven-2-0-8-on-mac-osx</id>
   <content type="html">&lt;p&gt;I have put together an all-in-one installer for Apache Maven 2.0.8 and Scala 2.7.0-final! Just download the installer, be it on 10.5 or 10.4, just download the right distro for your operating system and then follow the installation procedure.&lt;/p&gt;

&lt;p&gt;The installer will then automatically append all the right shell variables to your $PATH so they will be freshly available from the terminal - splendid.&lt;/p&gt;

&lt;p&gt;You can find the &lt;a href='http://timperrett.com/download.html'&gt;all in one maven installer for OSX here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Any problems feel free to get in touch.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>New Download Section on timperrett.com</title>
   <link href="http://timperrett.com/2008/04/09/new-download-section-on-timperrett-com"/>
   <updated>2008-04-09T18:24:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/04/09/new-download-section-on-timperrett-com</id>
   <content type="html">&lt;p&gt;Well, I finally pulled my finger out and put together a download section on my main site - I have included a couple of different packages right now, but I should be adding stuff up there on a fairly regular basis so stay tuned listeners!&lt;/p&gt;

&lt;p&gt;You can find my new download section &lt;a href='http://timperrett.com/download.html'&gt;here&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>How to use rails 2.0.2 without a database</title>
   <link href="http://timperrett.com/2008/04/09/how-to-use-rails-2-0-2-without-a-database"/>
   <updated>2008-04-09T14:53:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/04/09/how-to-use-rails-2-0-2-without-a-database</id>
   <content type="html">&lt;h2 id='step_1'&gt;Step 1&lt;/h2&gt;

&lt;p&gt;Run the rake task to freeze rails 2.0.2 into the project so your not reading from gems:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;rake rails:freeze:gems&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='step_2'&gt;Step 2&lt;/h2&gt;

&lt;p&gt;Remove the database.yml file from RAILS_ROOT/config/&lt;/p&gt;

&lt;h2 id='step_3'&gt;Step 3&lt;/h2&gt;

&lt;p&gt;Change line 21 in RAILS_ROOT/config/enviroment.rb to:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;config.frameworks -= [ :active_record ]&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Bobs your uncle, that should be it!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Cross Platform Language Mashups Are The Way Forward</title>
   <link href="http://timperrett.com/2008/04/05/cross-platform-language-mashups-are-the-way-forward"/>
   <updated>2008-04-05T16:11:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/04/05/cross-platform-language-mashups-are-the-way-forward</id>
   <content type="html">&lt;p&gt;With new cross-language mash ups appearing all the time with things like JRuby and Jython it makes me wonder where all this is going? Will we have J2EE apps deployed alongside dynamic languages all within the same container, all capable of leveraging the awesome JVM runtime? If so, then wow, thats an awesome proposition. Pretty much every language you can think of is now deployable within a java container - its even possible to deploy .net applications via mono!&lt;/p&gt;

&lt;p&gt;Perhaps people will start to standardize on the JVM as a platform - all this constant fighting over runtimes, platforms and environments makes work for the developer and architect extremely difficult; we want to keep up with the latest developments, but it just makes it so difficult to do that with all this chopping and changing.&lt;/p&gt;

&lt;p&gt;Anyway, things I think are going to be seriously hot this year are:&lt;/p&gt;

&lt;p&gt;&lt;a href='http://caucho.com/products/resin.xtp'&gt;Resin Application Server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href='http://liftweb.net/index.php/Main_Page'&gt;Lift Framework&lt;/a&gt; and &lt;a href='http://www.scala-lang.org/'&gt;Scala&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href='http://jruby.codehaus.org/'&gt;JRuby&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href='http://caucho.com/products/hessian.xtp'&gt;Hessian Binary Remoting&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ll see how things play out over the next few months, but whatever happens, its going to be exciting to see how all these technologies interact with each other - which fizzle out and which go on to achieve wonderful things.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Updated XMPie / Merb Extension for Merb 0.9.2</title>
   <link href="http://timperrett.com/2008/04/03/updated-xmpie-merb-extension-for-merb-0-9-2"/>
   <updated>2008-04-03T17:23:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/04/03/updated-xmpie-merb-extension-for-merb-0-9-2</id>
   <content type="html">&lt;p&gt;Just a quick note that I have refactored the code base for the XMPie ICP extension for Merb 0.9.2 and added some extra cool things that are inherited by the ICP subclasses.&lt;/p&gt;

&lt;p&gt;Now, its possible to add validation into the model subclass. Lets say we have a feild defined in our uPlan called ‘email&amp;#8217; and ‘user_name&amp;#8217;. I need the ‘user_name&amp;#8217; field to be required, which you can now do like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Visitor &amp;lt; Xmpie::Icp::Base
  validates_presence_of :user_name
end

# in your controller...
@visitor.valid? # =&amp;gt; true if has a user_name, otherwise false&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All exciting stuff! When XMPie make ICP a more viable persistance tier, then this will no doubt be the quickest and slickest way to implement front ends in. Furthermore, with the Engine Yard team working on &lt;a href='http://brainspl.at/articles/2008/02/12/what-do-you-want-to-see-in-mod_rubinius'&gt;mod_rubinus&lt;/a&gt; then we should see ruby web application performance finally get where it needs to be.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Extending Adobe CS3 Applications</title>
   <link href="http://timperrett.com/2008/03/31/extending-adobe-cs3-applications"/>
   <updated>2008-03-31T16:28:00+01:00</updated>
   <id>hhttp://timperrett.com/2008/03/31/extending-adobe-cs3-applications</id>
   <content type="html">&lt;p&gt;Of late ive been doing some investigation into extending InDesign with plugins and such. Traditional Adobe plugins needed to be written in C++ but now with the addition of the CS3 SDK its possible to write JSXB&amp;#8217;s from which you can extend the UI and all sorts of other good stuff!&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve been playing around with it, and true, its not as quick as C++, but its so much vastly more accessible the trade off does not seem like a major crime. If you want to try it for yourself, check out the SDK &lt;a href='http://www.adobe.com/devnet/indesign/sdk/'&gt;here&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Capistrano recipe for Merb 0.5.3 in production</title>
   <link href="http://timperrett.com/2008/03/14/capistrano-recipe-for-merb-0-5-3-in-production"/>
   <updated>2008-03-14T12:38:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/03/14/capistrano-recipe-for-merb-0-5-3-in-production</id>
   <content type="html">&lt;p&gt;Further to my &lt;a href='http://blog.timperrett.com/2008/3/13/monitoring-merb-processes-in-the-wild-with-god'&gt;article about God, and using it for watching Merb&lt;/a&gt; it seemed like a good idea that I also post my capistrano recipe so people can get the complete picture :)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# MIT License
# 
# Copyright (c) 2008, Tim Perrett
# 
# Permission is hereby granted, free of charge, to any person 
# obtaining a copy of this software and associated 
# documentation files (the &amp;quot;Software&amp;quot;), to deal in the Software
# without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, 
# and/or sell copies of the Software, and to permit persons 
# to whom the Software is furnished to do so, subject to the 
# following conditions:
# 
# The above copyright notice and this permission notice shall 
# be included in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED &amp;quot;AS IS&amp;quot;, WITHOUT WARRANTY OF 
# ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
# TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 
# OR OTHER DEALINGS IN THE SOFTWARE.

set :application, &amp;quot;domain.com&amp;quot; 

set :repository, &amp;quot;svn://yourrepo.com/path/to/repo&amp;quot; 

# Set your SVN and SSH User
set :user, &amp;quot;sshuser&amp;quot; 
set :svn_user, &amp;quot;svnuser&amp;quot; 
#Set the full path to your application on the server
set :deploy_to, &amp;quot;/path/to/your/#{application}&amp;quot; 

# define your servers
role :app, &amp;quot;domain.com&amp;quot; 
role :web, &amp;quot;domain.com&amp;quot; 
role :db, &amp;quot;domain.com&amp;quot;, :primary =&amp;gt; true

desc &amp;quot;Link in the production extras&amp;quot; 
task :after_update_code do
  run &amp;quot;ln -nfs #{shared_path}/log #{release_path}/log&amp;quot; 
end

desc &amp;quot;Merb it up with&amp;quot; 
deploy.task :restart do
  # you need to add restart tasks for each port you plan 
  # to run merb on. Whilst this is a little long winded, 
  # it will ensure uptime compared to the sledge hammer
  # than is #{current_path}/script/stop_merb
  run &amp;quot;(cd #{current_path}; merb -k 4006); sleep 1; \
  #{current_path}/script/merb -u timperrett -G timperrett \
  -M #{current_path}/config/merb.yml -p 4006 \
  -e production -d&amp;quot; 
  run &amp;quot;(cd #{current_path}; merb -k 4007); sleep 1; \
  #{current_path}/script/merb -u timperrett -G timperrett \
  -M #{current_path}/config/merb.yml -p 4007 \
  -e production -d&amp;quot; 
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Any problems, let me know :)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Monitoring Merb Processes in the Wild with God</title>
   <link href="http://timperrett.com/2008/03/13/monitoring-merb-processes-in-the-wild-with-god"/>
   <updated>2008-03-13T15:04:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/03/13/monitoring-merb-processes-in-the-wild-with-god</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;Before you start reading, this post only applies for Merb 0.5.3, any newer version is totally untested&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you take &lt;a href='http://www.merbivore.com/'&gt;Merb&lt;/a&gt; out into the wild, it does, unfortunatly, suffer a lot of the same problems as the mongrel handler than runs Rails.&lt;/p&gt;

&lt;p&gt;There is however a saviour out there - &lt;a href='http://god.rubyforge.org'&gt;God&lt;/a&gt; - To clarify, im not talking about the man upstairs; rather the process monitoring tool which rocks at restarting bloated mongrel processes on &lt;em&gt;nix based OS.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href='http://www.merbivore.com/'&gt;Merb&lt;/a&gt; handler does not have any way of restarting a running cluster, so you physically have to stop, then start a new merb process. This is somewhat out of sync with how the god process handling and restarting works in that you define start, stop and critically, restart paramaters. To get around this we have to use a hacky sleep then start method - its not ideal, but hey, it works :)&lt;/p&gt;

&lt;p&gt;Rather than letting merb handle the process forking, what were going to do is let &lt;a href='http://god.rubyforge.org'&gt;God&lt;/a&gt; handle the writing of Pids and managing of the process. Ok, less of all this talk and lets take a look at some configuration code for the &lt;a href='http://god.rubyforge.org'&gt;God&lt;/a&gt; configuration.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# MIT License
# 
# Copyright (c) 2008, Tim Perrett
# 
# Permission is hereby granted, free of charge, to any person 
# obtaining a copy of this software and associated 
# documentation files (the &amp;quot;Software&amp;quot;), to deal in the Software
# without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, 
# and/or sell copies of the Software, and to permit persons 
# to whom the Software is furnished to do so, subject to the 
# following conditions:
# 
# The above copyright notice and this permission notice shall 
# be included in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED &amp;quot;AS IS&amp;quot;, WITHOUT WARRANTY OF 
# ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
# TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 
# OR OTHER DEALINGS IN THE SOFTWARE.

SITE_LOCATION = &amp;quot;/var/www/sites/domain.com&amp;quot; 
MERB_ROOT = &amp;quot;#{SITE_LOCATION}/current&amp;quot; 
MERB_CONFIG = &amp;quot;#{SITE_LOCATION}/shared/config/merb.yml&amp;quot; 
MERB_ENVIROMENT = &amp;#39;production&amp;#39;
PROCESS_USER = &amp;#39;timperrett&amp;#39;
PROCESS_GROUP = &amp;#39;timperrett&amp;#39;

%w{4006 4007}.each do |port|  
  God.watch do |w|

    pid_path = File.join(MERB_ROOT, &amp;#39;log&amp;#39;,&amp;quot;merb.#{port}.pid&amp;quot;)

    w.name = &amp;quot;merb-#{port}&amp;quot; 
    w.interval = 30.seconds # default
    w.start = &amp;quot;#{MERB_ROOT}/script/merb -u #{PROCESS_USER} \
    -G #{PROCESS_GROUP} -M #{MERB_CONFIG} -p #{port} \
    -e #{MERB_ENVIROMENT} -d&amp;quot; 
    w.log = &amp;quot;/home/timperrett/godmerb.log&amp;quot; 
    w.stop = &amp;quot;(cd #{MERB_ROOT}; merb -k #{port})&amp;quot; 
    w.restart = &amp;quot;(cd #{MERB_ROOT}; merb -k #{port}); sleep 1; \
    #{MERB_ROOT}/script/merb -u #{PROCESS_USER} -G \
    #{PROCESS_GROUP} -M #{MERB_CONFIG} -p #{port} \
    -e #{MERB_ENVIROMENT} -d&amp;quot; 
    w.start_grace = 5.seconds
    w.restart_grace = 20.seconds
    w.pid_file = File.join(MERB_ROOT, &amp;quot;log/merb.#{port}.pid&amp;quot;)
    # w.group = &amp;quot;merbs&amp;quot; 
    w.behavior(:clean_pid_file)

    w.start_if do |start|
      start.condition(:process_running) do |c|
        c.interval = 10.seconds
        c.running = false
      end
    end

    w.restart_if do |restart|
      restart.condition(:memory_usage) do |c|
        c.above = 51.megabytes
        c.times = [3, 5] # 3 out of 5 intervals
      end

      restart.condition(:cpu_usage) do |c|
        c.above = 50.percent
        c.times = 5
      end
    end

    w.lifecycle do |on|
      on.condition(:flapping) do |c|
        c.to_state = [:start, :restart]
        c.times = 5
        c.within = 5.minute
        c.transition = :unmonitored
        c.retry_in = 5.minutes
        c.retry_times = 5
        c.retry_within = 2.hours
      end
    end

  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Im not sure that this is ideal, but it certainly seems to work for me and importantly keeps the site running without problems - which is a dang sight better than them becoming unresponsive!&lt;/p&gt;

&lt;p&gt;I hope this might help someone, somewhere&amp;#8230;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Choosing a style of personalised URL</title>
   <link href="http://timperrett.com/2008/03/13/choosing-a-style-of-personalised-url"/>
   <updated>2008-03-13T10:45:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/03/13/choosing-a-style-of-personalised-url</id>
   <content type="html">&lt;p&gt;I think that pretty much all the ‘Personalised URL&amp;#8217; jobs that I have ever needed to do have always been of the directory style, e.g:&lt;/p&gt;

&lt;p&gt;www.domain.com/mylovelyusername&lt;/p&gt;

&lt;p&gt;However, it strikes me that a better and more programatically favourable format is the sub-domain pattern, e.g:&lt;/p&gt;

&lt;p&gt;mylovelyusername.domain.com&lt;/p&gt;

&lt;p&gt;In this instance you don&amp;#8217;t have to worry about holding information in sessions, or setting up anything else complicated to make sure that they visit that URL first - it doesn&amp;#8217;t matter with the sub-domain pattern as you always have there unique identifier to hand in the URL. Im not wholly sure why it is that more people don&amp;#8217;t see the benefit of doing this - if you ask me it ‘feels&amp;#8217; more personal that a one time visit to a directory style URL.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Colloquy: An Awesome OSX IRC Client</title>
   <link href="http://timperrett.com/2008/02/22/colloquy-an-awesome-osx-irc-client"/>
   <updated>2008-02-22T21:06:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/02/22/colloquy-an-awesome-osx-irc-client</id>
   <content type="html">&lt;p&gt;After having used Limechat IRC, I just discovered &lt;a href='http://colloquy.info/'&gt;Colloquy&lt;/a&gt; and its awesome! Really slick interface - loving there work. Help yourself out and download it!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Personalised video’s with XMPie Version 4</title>
   <link href="http://timperrett.com/2008/02/19/personalised-videos-with-xmpie-version-4"/>
   <updated>2008-02-19T11:26:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/02/19/personalised-videos-with-xmpie-version-4</id>
   <content type="html">&lt;p&gt;Check out these awesome personalized video&amp;#8217;s which its now possible to produce using &lt;a href='http://xmpie.com'&gt;XMPie version 4!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kudos to &lt;a href='http://www.veedeepee.com/2008/02/personalised_videos.html'&gt;Eliot&lt;/a&gt; as he has been talking about personalized video for some time now and its finally been brought into the core version 4 product.&lt;/p&gt;

&lt;p&gt;Check these awesome samples from the recent XUG meet in Vegas&amp;#8230;&lt;/p&gt;
&lt;iframe src='http://www.hipcast.com/playweb?audioid=P86ea158aabfec14af426209fa8943cefbFt6Q1REYmN0&amp;buffer=5&amp;fc=FFFFFF&amp;pc=CCFF33&amp;kc=FFCC33&amp;bc=FFFFFF&amp;player=vp24' height='243' frameborder='0' width='392' scrolling='no'&gt; &lt;/iframe&gt;&lt;iframe src='http://www.hipcast.com/playweb?audioid=P7924270f926dad8ba57b0071b244c2c8bFt6Q1REYmN3&amp;buffer=5&amp;fc=FFFFFF&amp;pc=CCFF33&amp;kc=FFCC33&amp;bc=FFFFFF&amp;player=vp24' height='243' frameborder='0' width='392' scrolling='no'&gt; &lt;/iframe&gt;</content>
 </entry>
 
 <entry>
   <title>Working MySQL 5 OLEDB Connectivity for XMPie Server</title>
   <link href="http://timperrett.com/2008/02/15/working-mysql-5-oledb-connectivity-for-xmpie-server"/>
   <updated>2008-02-15T13:30:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/02/15/working-mysql-5-oledb-connectivity-for-xmpie-server</id>
   <content type="html">&lt;p&gt;Well, after a long stint of having no decent MySQL support (as uProduce only supports up to version 4 out of the box. Other than my ODBC monkey patch there has been no version 5 support), I have managed to find a working, and critically viable, solution for using MySQL 5 with XMPie uProduce.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://cherrycitysoftware.com/ccs/Providers/ProvMySQL.aspx'&gt;cherrycitysoftware.com&lt;/a&gt; sell (not that you can even call it that, its only $10) a little mysql driver that with a little bit of work you can make work with uProduce and uPlan - its nice to have MySQL back!&lt;/p&gt;

&lt;p&gt;You can use a DSN with generic DB like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;Provider=OleMySql.MySqlSource.1;Password=YOURPASSWORD;Persist 
SecurityInfo=True;User ID=YOURUSERNAME;Data Source=YOURDBHOST;
Location=YOURDBHOST;Mode=Read;Trace=&amp;quot;&amp;quot;;Initial Catalog=INITIALDATABASE&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Initial results are great - its working cleanly and quickly - good times with MySQL!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>XSLT using Ruby</title>
   <link href="http://timperrett.com/2008/01/31/xslt-using-ruby"/>
   <updated>2008-01-31T19:10:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/01/31/xslt-using-ruby</id>
   <content type="html">&lt;h1 id='short_story'&gt;Short Story&lt;/h1&gt;

&lt;p&gt;libxsl-ruby is a &lt;strong&gt;nightmare&lt;/strong&gt; to install. If you can indeed get it to install at all. I couldnt get the bloody thing to install at all on my 10.5 OSX box; and thats with ALL the required libs installed. I get the impression that its not very well maintained anymore and the project following has dropped off.&lt;/p&gt;

&lt;p&gt;I turned to &lt;strong&gt;ruby-xslt&lt;/strong&gt; - based on REXML, so yes, its slower. If your looking for speed then persist with the libxsl ruby path, but otherwise, save yourself a lot of time and just use this. Its vastly simpler!&lt;/p&gt;

&lt;h1 id='longer_story'&gt;Long(er) Story&lt;/h1&gt;

&lt;p&gt;Libxsl sucks. Strong statment I know. I would say im a fairly techincal chap, and ive just spent, nay, wasted, the last 3 - 4 hours trying to work out why libxsl-ruby wont install. Thats a bit of a bugger indeed. Who knows what the problem is, but ultimately its less portable due to reliance of the Gnome XML parsing libs. Granted there very fast, but thats no help at all if you cant even install them.&lt;/p&gt;

&lt;p&gt;REXML vs Libxml is a non-contest. We all know libxml is significantly faster - if you need that speed then i strongly advise you to continue with libxml; it will pay dividends in the end. If however your not going to need &lt;strong&gt;very&lt;/strong&gt; fast parsing, then really, save yourself a lot of wasted time and use REXML.&lt;/p&gt;

&lt;p&gt;REXML is bundled with the ruby distribution, so its also a lot more portable that libxml2. Anyway, if your even still reading, stop now, and bosh this into your terminal:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;sudo gem install ruby-xslt&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Job done.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Flash: Go To And Learn</title>
   <link href="http://timperrett.com/2008/01/29/flash-go-to-and-learn"/>
   <updated>2008-01-29T14:18:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/01/29/flash-go-to-and-learn</id>
   <content type="html">&lt;p&gt;I &lt;a href='http://www.gotoandlearn.com/'&gt;stumbled upon this the other day;&lt;/a&gt; it looks to be a really really great resource if your wanting to get up to date with all the latest flash goings on!&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.gotoandlearn.com/'&gt;&lt;img src='/assets/2008/1/23/flash-logo.png' alt='' /&gt;&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>For the rubber band flicking child in us all</title>
   <link href="http://timperrett.com/2008/01/20/for-the-rubber-band-flicking-child-in-us-all"/>
   <updated>2008-01-20T23:32:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/01/20/for-the-rubber-band-flicking-child-in-us-all</id>
   <content type="html">&lt;p&gt;Santa, this Christmas I would like a rubber band gatling gun&amp;#8230;.&lt;/p&gt;
&lt;object height='355' width='425'&gt;&lt;param name='movie' value='http://www.youtube.com/v/0GAUnuuBkW4&amp;rel;=1' /&gt;&lt;param name='wmode' value='transparent' /&gt;&lt;embed src='http://www.youtube.com/v/0GAUnuuBkW4&amp;rel;=1' height='355' wmode='transparent' width='425' type='application/x-shockwave-flash' /&gt;&lt;/object&gt;</content>
 </entry>
 
 <entry>
   <title>Deploying Ruby WebGen with Capistrano</title>
   <link href="http://timperrett.com/2008/01/11/deploying-ruby-webgen-with-capistrano"/>
   <updated>2008-01-11T17:47:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/01/11/deploying-ruby-webgen-with-capistrano</id>
   <content type="html">&lt;p&gt;&lt;a href='http://webgen.rubyforge.org/'&gt;WebGen&lt;/a&gt; is a groovy little tool that makes building HTML sites a lot simpler, and makes maintenance a lot more efficient via clever templating. I wont labour the pro&amp;#8217;s and con&amp;#8217;s of the project here, I&amp;#8217;ll just get on with explaining how to deploy version webgen sites using our good friend Capistrano.&lt;/p&gt;

&lt;p&gt;First off, install Capistrano:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;$ sudo gem install capistrano -y&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next, we need to prepar our webgen dir with all the relevant deployment information. &lt;strong&gt;All these commands presume you have ‘cd&amp;#8217; to the webgen project directory&lt;/strong&gt; Capistrano provides a simple way to do this&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;$ mkdir config
$ capify .&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next we need to setup our new deploy.rb file, mine looks a little something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;set :application, &amp;quot;yourapplication.com&amp;quot; 
set :repository,  &amp;quot;svn://yourhost/path/to/webgen/site/output&amp;quot; 

# If you aren&amp;#39;t deploying to /u/apps/#{application} on the
# target servers (which is the default), you can specify 
# the actual location via the :deploy_to variable:
set :deploy_to, &amp;quot;/var/www/sites/#{application}&amp;quot; 

# If you aren&amp;#39;t using Subversion to manage your 
# source code, specify your SCM below:
# set :scm, :subversion
set :user, &amp;quot;deploy&amp;quot; 
set :svn_user, &amp;quot;badger&amp;quot; 

role :app, &amp;quot;yourapplication.com&amp;quot; 
role :web, &amp;quot;yourapplication.com&amp;quot; 
role :db,  &amp;quot;yourapplication.com&amp;quot;, :primary =&amp;gt; true

# Overrides the default task supplied by cap, as this 
# is a static site there are no mongrel&amp;#39;s et al 
# that need restarting
desc &amp;quot;Deploy webgen site&amp;quot; 
deploy.task :restart do
  puts &amp;quot;Using webgen, so nothing to restart&amp;quot; 
end

# also, because we have configured logging via our HTTP 
# server (e.g. nginx, apache etc) we have no need for this 
# part of the deployment phase to we again, just override it
# with an arbitrary message
desc &amp;quot;Override default cap behavior for finalize_update&amp;quot; 
deploy.task :finalize_update do
  puts &amp;quot;We dont need no stinking logs...&amp;quot; 
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, all being well, we need to setup the server to respond to cap:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;$ cap deploy:setup&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then we should be able to deploy our project with no problems!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;$ cap deploy&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I hope this was of use to someone, somewhere, sometime :)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Intergrated support for text messaging from merb</title>
   <link href="http://timperrett.com/2008/01/05/intergrated-support-for-text-messaging-from-merb"/>
   <updated>2008-01-05T01:37:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/01/05/intergrated-support-for-text-messaging-from-merb</id>
   <content type="html">&lt;p&gt;Well, I got board - what can I say!&lt;/p&gt;

&lt;p&gt;If you have a signup.to account you can enjoy really seamless intergration with merb for sending messages :)&lt;/p&gt;

&lt;p&gt;All you need to to send a SMS is write something like this in one of your controllers:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;send_sms(ExampleMessenger, 
               :some_method, 
               { :from =&amp;gt; &amp;quot;02UK&amp;quot;, 
                 :to =&amp;gt; &amp;quot;44123456789&amp;quot; })&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thats pretty dang sweet; its also all very MVC, using its own messaging controllers (complete with generators) and ERB files for the message content. Lovely.&lt;/p&gt;

&lt;p&gt;If anyone gets use out of it, I would really love to hear about it - &lt;a href='http://rubyforge.org/frs/?group_id=4542'&gt;download the gems here&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Is Rails no longer the flavor of the month?</title>
   <link href="http://timperrett.com/2008/01/05/is-rails-no-longer-the-flavor-of-the-month"/>
   <updated>2008-01-05T00:11:00+00:00</updated>
   <id>hhttp://timperrett.com/2008/01/05/is-rails-no-longer-the-flavor-of-the-month</id>
   <content type="html">&lt;p&gt;Firstly, I read &lt;a href='http://www.zedshaw.com/rants/rails_is_a_ghetto.html'&gt;this blog post&lt;/a&gt; by Zed Shaw. Quite frankly I was disgusted that someone who has given so much to our community has been treated so poorly by prominent figures within our very inner circles and the major vendors. I must point out I do not know Zed, Ive never met him, nor will I likely ever meet him, but yet he helped me many times way back in the early days of mongrel, as im sure he did with countless others - and for that, he gets my respects and applause.&lt;/p&gt;

&lt;p&gt;His blog posts about the problems with Rails echoed conversations I have had multiple times of late with various other developers and architects. People feel rails is bloated and has a lot of inefficiencies - which is true, and whilst 2.1 is leaner, it could still do with a good going over at fat camp&amp;#8230; That sounds bad I admit, but I am not ignorant of the fact that we do have an awful lot to thank Rails (and DHH especially) for - the ideas behind Rails have changed the way the &lt;strong&gt;whole&lt;/strong&gt; development community look at there working practices from start to finish. The shear magnitude of that is mind-blowing.&lt;/p&gt;

&lt;p&gt;Personally, Rails has changed the way I look at code, the way I think and more - this blog is even powered by rails. Despite all that, when I build a Rails project now, I cant help but feel, well, a little bit dirty. Initially in my Rails career I loved the way that the bulk of the complexity was abstracted far far away down the rabbit hole - thats not because I was an incompetent coder - it was just new and exciting, and seemed like such a great idea at the time (like so many other things&amp;#8230;). Now however, I feel like we need more; more control, more transparency in our frameworks and tools. Less black boxes and more turner-prize type glass ones!&lt;/p&gt;

&lt;p&gt;I ask you the reader one thing: Is it time we said farewell to Rails? Or is it a case of the grass is greener on the other side?&lt;/p&gt;

&lt;p&gt;Some of you reading this might be thinking that this is all well and good, but what the hell are we going to use to build our projects. Well, I have been putting a lot of time into the &lt;a href='http://merbivore.com/'&gt;Merb framework&lt;/a&gt; recently, and it is, categorically, &lt;strong&gt;awesome&lt;/strong&gt;, not to mention thread safe ;) Working with it feels just, well, better. Ezra has crafted a great framework that has taken heed of Rails&amp;#8217; shortcomings, that my friends can only be a good thing&amp;#8230;&lt;/p&gt;

&lt;p&gt;Anyway, I&amp;#8217;ll be posting some Merb tutorials up here soon, so I hope you will give it a try and let me know how you get on.&lt;/p&gt;

&lt;p&gt;Happy coding guys, and farewell Rails, its been emotional!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Implementing XMPie ICP with my new ICP extension framework</title>
   <link href="http://timperrett.com/2007/12/28/implementing-xmpie-icp-with-my-new-icp-extension-framework"/>
   <updated>2007-12-28T11:18:00+00:00</updated>
   <id>hhttp://timperrett.com/2007/12/28/implementing-xmpie-icp-with-my-new-icp-extension-framework</id>
   <content type="html">&lt;p&gt;Well its taken a while to put together, but I am finally reaching the point at which its really useable and sweet to work with. I would love to hear peoples thoughts on this - are you already using the DW controls? If so, what are your thoughts on this new style of working? Is it too limited by way of being too techie?&lt;/p&gt;

&lt;p&gt;Its important to note that this framework is &lt;strong&gt;100% cross platform&lt;/strong&gt; any only requires Ruby, and the RubyGems package management; this screen-cast however was created on OSX Leopard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MAKE SURE YOU VIEW FULL SCREEN TO READ THE TEXT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>MetaProgramming with Ruby</title>
   <link href="http://timperrett.com/2007/12/22/metaprogramming-with-ruby"/>
   <updated>2007-12-22T13:18:00+00:00</updated>
   <id>hhttp://timperrett.com/2007/12/22/metaprogramming-with-ruby</id>
   <content type="html">&lt;p&gt;Of late of been writing some nice gems makings heavy use of meta programming. If anyone is looking at doing something similar, I would high recommend you check out these resources:&lt;/p&gt;

&lt;p&gt;http://www.infoq.com/presentations/metaprogramming-ruby&lt;/p&gt;

&lt;p&gt;http://www.rubyplus.org/&lt;/p&gt;

&lt;p&gt;The talk about self and its meaning was extremely interesting - its really surprising how flexible it &lt;em&gt;can&lt;/em&gt; be in the right hands :)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Finally got hold of new Revel8 KTP boards</title>
   <link href="http://timperrett.com/2007/12/14/finally-got-hold-of-new-revel8-ktp-boards"/>
   <updated>2007-12-14T19:13:00+00:00</updated>
   <id>hhttp://timperrett.com/2007/12/14/finally-got-hold-of-new-revel8-ktp-boards</id>
   <content type="html">&lt;p&gt;Well, its been a while, the but the guys at &lt;a href='http://www.exclaimskiboards.co.uk/'&gt;Exclaim Skiboards&lt;/a&gt; came through and I know have in my possession a slick pair of Revel8 KTP skiboards!!! Were off to Tamworth snow dome tomorrow to try them out - god I really cant wait! Just look how hot they are&amp;#8230;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updated after snowdome trip&amp;#8230;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well, they rock. Simple. Everyone on the slope kept asking what they were and saying how they were the coolest thing they&amp;#8217;d ever seen - it was annoying that people kept calling them &amp;#8220;snowblades&amp;#8221; tho; they were hastily corrected - no&amp;#8230; their &amp;#8220;skiboards&amp;#8221; you muppet!!&lt;/p&gt;

&lt;p&gt;&lt;img src='http://blog.timperrett.com/assets/2007/12/14/ktp-skiboards.jpg' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;God, im so hooked - bring on Italy!!!!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Give your database some GIS sugar!</title>
   <link href="http://timperrett.com/2007/12/13/give-your-database-some-gis-sugar"/>
   <updated>2007-12-13T19:38:00+00:00</updated>
   <id>hhttp://timperrett.com/2007/12/13/give-your-database-some-gis-sugar</id>
   <content type="html">&lt;p&gt;Well, its time for production now - remember that tutorial way back about building PostGRE on OSX? Well Ive just done it on Ubuntu Server, but from scratch, with all the GIS bells and whistles ;)&lt;/p&gt;

&lt;h2 id='lets_tuck_in'&gt;Lets tuck in&amp;#8230;&lt;/h2&gt;

&lt;p&gt;First off, rather than me labour the point (anyone familiar with linux will breeze this part) check out &lt;a href='http://postgis.refractions.net/pipermail/postgis-users/2007-July/016368.html'&gt;this really usefull post&lt;/a&gt; - its got all the things you need for doing the actual compilation and install.&lt;/p&gt;

&lt;p&gt;There are however a few Ubuntu related &amp;#8220;gotchas&amp;#8221;. Firstly, after you install GEOS, both ldconfig doesnt yet know about the new libs you&amp;#8217;ve just installed at &lt;strong&gt;/usr/local/lib&lt;/strong&gt;. To make it read the new libs you&amp;#8217;ve gotta create a new file called &lt;strong&gt;ld.so.conf&lt;/strong&gt; and stick it in /etc - fill it with the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;/lib/
/usr/lib/
/usr/local/lib/
/usr/X11R6/lib/&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then to make it read in the new config, do this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;/sbin/ldconfig -f /etc/ld.so.conf&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To check that its now reading your GEOS libs, run the following, and make sure you see a &lt;strong&gt;similar&lt;/strong&gt; output (depending on the version of GEOS you installed)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;$ /sbin/ldconfig -p | grep geos
    libgeos_c.so.1 (libc6,x86-64) =&amp;gt; /usr/local/lib/libgeos_c.so.1
    libgeos_c.so (libc6,x86-64) =&amp;gt; /usr/local/lib/libgeos_c.so
    libgeos.so.2 (libc6,x86-64) =&amp;gt; /usr/lib/libgeos.so.2
    libgeos.so (libc6,x86-64) =&amp;gt; /usr/lib/libgeos.so&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='another_helping_sir'&gt;Another helping sir?&lt;/h2&gt;

&lt;p&gt;OK - were good to go on that front. The key thing now is that we need to be able to add GIS functions and type handlers to any given database. Provided you set up the ldconfig stuff correctly, doing:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;su -- postgres /usr/local/pgsql/bin/psql \
-f /usr/local/pgsql/share/lwpostgis.sql \
-d yourdbnamegoeshere&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If this didnt work, you have a problem with your ldconfig! There are fixes out there which advise changing the lwpostgis.sql script, but in my personal opinion, thats not fixing the problem, thats just dirtying a fresh install.&lt;/p&gt;

&lt;p&gt;Next, after I had everything up and running, it was puzzling me that there was no init.d script available (the google force was not strong today), I rummaged around in the source I downloaded, and found a &lt;strong&gt;startup-scripts&lt;/strong&gt; dir in the contrib directory, result. Take that script, and bosh it into /etc/init.d and do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;sudo /usr/sbin/update-rc.d postgresql-8.2.5 defaults&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then you have a fully working PostGRE install with GIS sugar!!!&lt;/p&gt;

&lt;p&gt;Hopefully this might help someone one day :)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Symbian applications you need in your life</title>
   <link href="http://timperrett.com/2007/12/10/symbian-applications-you-need-in-your-life"/>
   <updated>2007-12-10T17:16:00+00:00</updated>
   <id>hhttp://timperrett.com/2007/12/10/symbian-applications-you-need-in-your-life</id>
   <content type="html">&lt;p&gt;Recently I found out that their is a swath of stuff avalible to install on your mobile device if your running Symbian OS.&lt;/p&gt;

&lt;p&gt;My personal favorite is Google maps, which works amazingly well - &lt;a href='http://www.google.com/gmm/tour.html?hl=en_GB'&gt;check out an online demo of it here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is also a GMail app, which works really nicely - &lt;a href='http://www.google.com/mobile/mail/index.html'&gt;More info on that can be found here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, for those of you who might want to restart your remote box on the go, there is a mobile SSH client that runs on an mobile with a JVM. Fly over to &lt;a href='http://www.xk72.com/midpssh/'&gt;XK72&lt;/a&gt; to check out MidpSSH client; it even lets you record macros for repeats tasks! Magic!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Launch of XMPie google group</title>
   <link href="http://timperrett.com/2007/12/06/launch-of-xmpie-google-group"/>
   <updated>2007-12-06T20:54:00+00:00</updated>
   <id>hhttp://timperrett.com/2007/12/06/launch-of-xmpie-google-group</id>
   <content type="html">&lt;p&gt;Well, its finally happened - an independent, open, and crucially free forum for discussing XMPie technology in a global community.&lt;/p&gt;

&lt;p&gt;This is all pretty new but I would love to see some good conversations bubble up on there in the not too distant future - if you would like to sign up get yourself over to &lt;a href='http://groups.google.com/group/xmpie-users/subscribe?hl=en'&gt;this page&lt;/a&gt; ASAP!&lt;/p&gt;

&lt;p&gt;We are hoping that this will prove a useful and valuable resource for XMPie discussion - I hope to see as many of you on list as possible!!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Wouldn’t you love to be as good as this?</title>
   <link href="http://timperrett.com/2007/11/04/wouldnt-you-love-to-be-as-good-as-this"/>
   <updated>2007-11-04T11:24:00+00:00</updated>
   <id>hhttp://timperrett.com/2007/11/04/wouldnt-you-love-to-be-as-good-as-this</id>
   <content type="html">&lt;p&gt;I came across this on YouTube - awesome, simply awesome :)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Obligatory post about leopard OS X</title>
   <link href="http://timperrett.com/2007/11/04/obligatory-post-about-leopard-os-x"/>
   <updated>2007-11-04T11:19:00+00:00</updated>
   <id>hhttp://timperrett.com/2007/11/04/obligatory-post-about-leopard-os-x</id>
   <content type="html">&lt;p&gt;I know, I know, I know - I just couldnt help myself but I needed to post about Lepoard!&lt;/p&gt;

&lt;p&gt;It was a smooth upgrade on the whole, bar some funny issue with the DNS that couldnt resolve some external items; switching to openDNS worked like a charm.&lt;/p&gt;

&lt;p&gt;Anyway, I wont bang on about time machine et al as thats been done to death!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>How to install PostgreSQL with PostGIS spatial on OSX</title>
   <link href="http://timperrett.com/2007/10/26/how-to-install-postgresql-with-postgis-spatial-on-osx"/>
   <updated>2007-10-26T13:32:00+01:00</updated>
   <id>hhttp://timperrett.com/2007/10/26/how-to-install-postgresql-with-postgis-spatial-on-osx</id>
   <content type="html">&lt;p&gt;Recently spatial calculations have fascinated me. Hardly what most people would consider fascinating, but hey!&lt;/p&gt;

&lt;p&gt;Most of the modern enterprise (I use that term loosely as someone is bound to comment complaining that some of this list are &lt;strong&gt;not&lt;/strong&gt; ‘enterprise&amp;#8217; enough) RDBMS have spatial GIS extensions. This allows them to conduct exteamly complex calculations about size, posistion and location in a three dimensional way - pretty freaking cool! Common databases that have GIS extensions are:&lt;/p&gt;

&lt;p&gt;PostGRE - &lt;a href='http://postgis.refractions.net/'&gt;PostGIS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oracle - &lt;a href='http://www.oracle.com/technology/products/spatial/index.html'&gt;Oracle spatial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DB2 - &lt;a href='http://www-306.ibm.com/software/data/spatial/'&gt;IBM Spatial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MySQL - &lt;a href='http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html'&gt;MySQL spatial entensions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;there are lots more&amp;#8230; just google for your specific backend.&lt;/p&gt;

&lt;p&gt;Anyway&amp;#8230; for this article we&amp;#8217;ll focus on PostGRE PostGIS, and running it on OSX.&lt;/p&gt;

&lt;h1 id='step_1'&gt;Step 1&lt;/h1&gt;

&lt;p&gt;You will need to (download a whole bunch of frameworks from here)&lt;span&gt;http://www.kyngchaos.com/software/unixport/frameworks&lt;/span&gt; and run the installer. That will give you some of the base libs and frameworks that PostGIS requires; such as GEOS, GDAL etc etc&lt;/p&gt;

&lt;h1 id='step_2'&gt;Step 2&lt;/h1&gt;

&lt;p&gt;Add a new user on your system and make sure its short name is &lt;strong&gt;postgres&lt;/strong&gt; - this is the user you will run the database server as. See below from my box:&lt;/p&gt;

&lt;p&gt;&lt;img src='http://blog.timperrett.com/assets/2007/11/4/mac-account-screen_1.png' alt='' /&gt;&lt;/p&gt;

&lt;h1 id='step_3'&gt;Step 3&lt;/h1&gt;

&lt;p&gt;Download the latest PostGRE installer &lt;a href='http://www.kyngchaos.com/software/unixport/postgres'&gt;from here&lt;/a&gt;. This will load up PostGRE in &lt;strong&gt;/usr/local/pgsql&lt;/strong&gt;; while your there i&amp;#8217;d install the startup item so you dont have to load the server manually evertime you restart your mac.&lt;/p&gt;

&lt;p&gt;Once installed you need to do some editing of the conf files. For me, I just needed a local development server, so I loaded up /usr/local/pgsql/data/postgresql.conf and changed the line&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#listen_addresses = ‘&lt;/strong&gt;‘**&lt;/p&gt;

&lt;p&gt;to&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;listen_addresses = ‘&lt;/strong&gt;‘**&lt;/p&gt;

&lt;p&gt;This will ensure that our server binds to all the interfaces the box has. If you want to be more specific, just enter the IP of your machine.&lt;/p&gt;

&lt;p&gt;Next, you need to edit the pg_hba.conf file to add a generic host like so:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;host all all 0.0.0.0/0 md5&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This lets anyone from any IP/subnet connect as any user. I must stress that this was for development purposes so you might want to be a bit more explicit for a production enviroment.&lt;/p&gt;

&lt;h1 id='step_4'&gt;Step 4&lt;/h1&gt;

&lt;p&gt;Now you have PostGRE installed and configured, run the PostGIS installer - this will PostGIS to your install. We now need to create a new database and add the spatial extensions to it so that our querys will work&amp;#8230; but before we can do that we&amp;#8217;ll need to enable PL/SQL like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;CREATE LANGUAGE &amp;#39;plpgsql&amp;#39; HANDLER plpgsql_call_handler LANCOMPILER &amp;#39;PL/pgSQL&amp;#39;&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, from PgAdmin3, open the query tool, and browse to &lt;strong&gt;/usr/local/pgsql/share/lwpostgis.sql&lt;/strong&gt; - run that query, and dont worry about the output (unless its an error!) and refresh the view in PgAdmin3, you should then see the functions list gone from 0 for 600+ - thats all your spatial extensions loaded up ready for use.&lt;/p&gt;

&lt;p&gt;That should be it - check out &lt;a href='http://www.bostongis.com'&gt;Boston GIS&lt;/a&gt; for more on GIS querys and so on - its exteamly complex and out of scope for this article. Happy geocoding people&amp;#8230;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Making XMPie work with PostGRE SQL 8.3 backend</title>
   <link href="http://timperrett.com/2007/10/19/making-xmpie-work-with-postgre-sql-8-3-backend"/>
   <updated>2007-10-19T01:39:00+01:00</updated>
   <id>hhttp://timperrett.com/2007/10/19/making-xmpie-work-with-postgre-sql-8-3-backend</id>
   <content type="html">&lt;p&gt;For all the good things about XMPie, one of my niggles has been the lack of support for PostGRE SQL. I guess thats pretty understanderble; most of there client base use SQL server and other such MS products to some degree. There are times when id really like to use PostGre SQL as the backend and it can be a bit annoying. Anyway&amp;#8230;thats another story&amp;#8230;. for now were just going to look at implementing the OLEDB conectivity onto the servers to make it talk to our datasource.&lt;/p&gt;

&lt;p&gt;Before we begin please note that it is critical to make sure that your PostgreSQL server can accept connections from your host IP. Otherwise you will get an error detailing that windows could not initialize the OLEDB provider. So, for those not familiar with PGSQL, check your postgresql.conf and pg_hba.conf&amp;#8230;.&lt;/p&gt;

&lt;h2 id='step_1'&gt;Step 1&lt;/h2&gt;

&lt;p&gt;Ok, firstly you will need to install the OLEDB driver onto the server (and all extension serves where applicible)&amp;#8230;&lt;/p&gt;

&lt;p&gt;Download the OLEDB driver files &lt;a href='http://pgfoundry.org/frs/?group_id=1000085&amp;amp;release_id=539'&gt;from here&lt;/a&gt; - its currently in beta so do bear that in mind. Once downloaded, unzip it and copy &lt;strong&gt;libpq.dll&lt;/strong&gt; and &lt;strong&gt;PgOleDb.dll&lt;/strong&gt; to your &lt;strong&gt;windows\system32&lt;/strong&gt; folder.&lt;/p&gt;

&lt;p&gt;Next, to register those new files as sources, go Start &amp;gt; Run and type&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;regsvr32 PGOLEDB.DLL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All being well you should see a sucsess box - if not, then i guess check your spelling against the DLL :)&lt;/p&gt;

&lt;h2 id='step_2'&gt;Step 2&lt;/h2&gt;

&lt;p&gt;Now, provided you got your working OLEDB driver up and running in the previous step (be sure to test this with a UDL script) you should be able to add the database into the xmpie dashboard using a dsn something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;Provider=PostgreSQL OLE DB Provider;Password=&amp;lt;pass&amp;gt;;
User ID=root;Data Source=127.0.0.1;Location=demo;Extended Properties=&amp;amp;#8221;&amp;amp;#8221;
&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I am going to be doing some testing to see if this is any quicker than SQL Server (fingers crossed it will be) - stay tunned readers!&lt;/p&gt;

&lt;p&gt;Give me a shout if you dont seem to be able to make this work (for whatever reason)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Im sure Microsoft must be a synonym for crap?</title>
   <link href="http://timperrett.com/2007/10/15/im-sure-microsoft-must-be-a-synonym-for-crap"/>
   <updated>2007-10-15T13:14:00+01:00</updated>
   <id>hhttp://timperrett.com/2007/10/15/im-sure-microsoft-must-be-a-synonym-for-crap</id>
   <content type="html">&lt;p&gt;I recently have had to do come C++ coding - not my usual play ground i must admit, but never the less, something I needed to do.&lt;/p&gt;

&lt;p&gt;My first port of call was to download the Visual C++ installer, which I did. Fine and dandy I thought, it &lt;em&gt;seemed&lt;/em&gt; to work ok. The GUI was typical 2007 style, so yes, I couldn&amp;#8217;t find a thing.&lt;/p&gt;

&lt;p&gt;I then set about doing some coding, only to find that even simple stuff like&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;#include &amp;lt;windows.h&amp;gt;
&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I was getting all manner of errors in the bottom console. I only then found out that without the super duper &amp;#8220;Microsoft Platform SDK&amp;#8221; you couldn&amp;#8217;t actually do sweet f&lt;strong&gt;k all. So, to another 500mb download, on top of the painful download and installation of the IDE, this was somewhat insulting.&lt;/strong&gt;&lt;/p&gt;
&lt;rant&gt;





Microsoft, we the developers and end users of your software urge you to please plug your brain in before making these kinds of choices! I know you say VC++ is meant to only ‘give a taste' for windows C++ development, but if you want that taste to be something other than bitter resentment, make sure your products work properly out of the box!!





&lt;/rant&gt;</content>
 </entry>
 
 <entry>
   <title>Do you like spear wielding spartans?</title>
   <link href="http://timperrett.com/2007/10/06/do-you-like-spear-wielding-spartans"/>
   <updated>2007-10-06T14:10:00+01:00</updated>
   <id>hhttp://timperrett.com/2007/10/06/do-you-like-spear-wielding-spartans</id>
   <content type="html">&lt;p&gt;This has to be one of the best films of the year&amp;#8230;.&lt;/p&gt;
&lt;object height='353' width='425'&gt;&lt;param name='movie' value='http://www.youtube.com/v/wDiUG52ZyHQ&amp;rel;=1' /&gt;&lt;param name='wmode' value='transparent' /&gt;&lt;embed src='http://www.youtube.com/v/wDiUG52ZyHQ&amp;rel;=1' height='353' wmode='transparent' width='425' type='application/x-shockwave-flash' /&gt;&lt;/object&gt;</content>
 </entry>
 
 <entry>
   <title>Ruby SMS gateway client for sign-up.to</title>
   <link href="http://timperrett.com/2007/10/05/ruby-sms-gateway-client-for-sign-up-to"/>
   <updated>2007-10-05T20:44:00+01:00</updated>
   <id>hhttp://timperrett.com/2007/10/05/ruby-sms-gateway-client-for-sign-up-to</id>
   <content type="html">&lt;p&gt;Well, I finally got round to getting my own RubyForge project! Its been a while coming now, but I decided to release some of the work ive done using the (SignUpTo)&lt;span&gt;http://sign-up.to&lt;/span&gt; SMS gateway as a gem :)&lt;/p&gt;

&lt;p&gt;Its still very early stages, as i only needed something rough for the project I was working on, however i put it out anyway - its rough but it does work I assure you! lol&lt;/p&gt;

&lt;p&gt;You can check the project page at (signupto.rubyforge.org)&lt;span&gt;http://signupto.rubyforge.org&lt;/span&gt; and download the source files (here)&lt;span&gt;http://rubyforge.org/frs/?group_id=4542&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;Otherwise, if you wanna install via gems, just do the usual:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sudo gem install signupto&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id='so_how_do_i_use_it'&gt;So how do I use it?&lt;/h2&gt;

&lt;p&gt;For this example, we&amp;#8217;ll use rails, at thats probally where people might use it most often&amp;#8230; In your &lt;strong&gt;boot.rb&lt;/strong&gt; do&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;gem &amp;#39;signupto&amp;#39;&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then require the files in your enviroment.rb&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;require &amp;#39;net/sms/signupto&amp;#39;&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That will then let you use the classes anywhere in your app :) such as&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;account = Net::SMS::SignupTo::Account.new(‘YOUR ACCOUNT HASH&amp;#39;, ‘CUSTOMER&amp;#39;)
message = Net::SMS::SignupTo::Message.new(RECIPIENT_NUMBER,
&amp;#39;NAME OF SENDER (max 12 chars)&amp;#39;, 
‘BODY OF MESSAGE, NON-URI encoded&amp;#39;)&amp;lt;/code&amp;gt;






&amp;lt;code&amp;gt;send = Net::SMS::SignupTo::Send.new(account, message)&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The SMS&amp;#8217;s should then just fly out the door! Apologies as I know this is a very rushed first post about this, but I have places to go and people to see ;) I&amp;#8217;ll be bolstering the unit tests and examples soon. Stay tuned people!!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Fixing random PHP crashes on IIS 6 recorded as PHP memory leaks</title>
   <link href="http://timperrett.com/2007/09/30/fixing-random-php-crashes-on-iis-6-recorded-as-php-memory-leaks"/>
   <updated>2007-09-30T12:50:00+01:00</updated>
   <id>hhttp://timperrett.com/2007/09/30/fixing-random-php-crashes-on-iis-6-recorded-as-php-memory-leaks</id>
   <content type="html">&lt;p&gt;I recently came accross a serious problem that seems to be relativly un-documented bar other people raising bug tickets on bugs.php.net.&lt;/p&gt;

&lt;p&gt;If you are having problems with PHP on IIS where you get a couple page views from your application then you just get a blank screen? If so then read on&amp;#8230;.&lt;/p&gt;

&lt;p&gt;There was nothing in the Event Log for applicatons or system, so I tried re-starting IIS; with no luck. This particular problem seemed to be happening tottaly silently with absolutly no record anywhere (php_error.log et al). I them re-started the whole box, and upon boot up I checked the Event viewer and there was an entry in the application log detailing a memory leak in &amp;#8220;php.exe&amp;#8221;. So, a memory leak I thought, great&amp;#8230;&lt;/p&gt;

&lt;p&gt;Trawling the web I then found a document detailing how windows server kills off processes it deems to be at all ‘dangerous&amp;#8217;. It does this silently (which is unbeliviably handy) and fitted with the problems I was encountering. Going on the presumption that it was indeed killing the PHP process (or more specifically the worker threads) I turned to the application pool configuration&amp;#8230; And broke out alll my PHP apps into a seperate application pool. When they stoped working, I could just recycle the pool and they worked again for two requests. NB: Ive seen other peoples configurations take a couple more than 2 requests so bear that in mind if your having this problem.&lt;/p&gt;

&lt;p&gt;So, by now I knew that it was windows killing of the process causing the problems, however I wasnst sure how to fix it.&lt;/p&gt;

&lt;p&gt;I looked at the loaded modules in my PHP.ini, and found that removing all non-essential modules solved the problem. I then brought in one by one each PHP module, and found that it was not actually the modules them selves that were leaking, but just the order in which they were loaded causing the problem.&lt;/p&gt;

&lt;p&gt;Yes, thats very crap. I couldnt find a more elegant solution to this, and I really hope this helps someone as I must have wasted a day of my life trying to solve this bloody problem! lol&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Installing Apache 2.2 on OSX with mod_python</title>
   <link href="http://timperrett.com/2007/09/23/installing-apache-2-2-on-osx-with-mod_python"/>
   <updated>2007-09-23T16:18:00+01:00</updated>
   <id>hhttp://timperrett.com/2007/09/23/installing-apache-2-2-on-osx-with-mod_python</id>
   <content type="html">&lt;p&gt;Following on from setting up Django on your local system for dev purposes, I thought id just do an article about how to set up apache to use mod_python for when you want to roll your Django app out to the big bad world.&lt;/p&gt;

&lt;p&gt;Before you start, you will &lt;strong&gt;NEED&lt;/strong&gt; to have completed the other post about installing Django, as you need to have the mac python installer in and configured properly for this to work.&lt;/p&gt;

&lt;h2 id='step_1'&gt;Step 1&lt;/h2&gt;

&lt;p&gt;First of all we&amp;#8217;ve got to get Apache 2.2 working, as Apple only ship 1.3 with OSX (I wonder if this will change in Lepord? Lets hope so!). You can &lt;a href='http://mirror.public-internet.co.uk/apache/httpd/httpd-2.2.6.tar.gz'&gt;download the source here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Extract the archive and cd into the new directory. We need to configure it with some options so that we have proxying (which you might want for rails etc) and just some other candy you might find usefull at a later date.&lt;/p&gt;

&lt;p&gt;Set the CFLAGS:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;export CFLAGS=&amp;#8221;-arch i386″&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run this configure command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;./configure \
  --prefix=/Library/Apache-2.2.6 \
  --enable-so \
  --enable-mods-shared=all \
  --with-mpm=prefork \
  --enable-dav \
  --enable-cache \
  --enable-proxy \
  --enable-shared \
  --disable-static \
  --disable-unique-id \
  --disableipv6 \
  --enable-logio \
  --enable-deflate \
  --with-ldap \
  --with-ldap-include=/usr/include \
  --with-ldap-lib=/usr/lib 
  --with-included-apr 
  --enable-ldap \
  --enable-auth-ldap \
  --enable-cgi 
  --enable-cgid \
  --enable-suexec&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let it do its business then run the usual:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;make&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;then&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;make install&lt;/strong&gt; (NB: we dont use sudo here as that way apache is compiled with permisions that let you edit the conf files and so on without needing to be an admin which is just ‘nicer&amp;#8217; for local dev)&lt;/p&gt;

&lt;h2 id='step_2'&gt;Step 2&lt;/h2&gt;

&lt;p&gt;Configure your httpd.conf file as you see fit. I only really felt the need to change the following:&lt;/p&gt;

&lt;p&gt;Change user and group to your user name (or any other one you want) Change ServerAdmin email to an appropriate one Uncomment &amp;#8220;Include conf/extra/httpd-mpm.conf&amp;#8221; Uncomment &amp;#8220;Include conf/extra/httpd-default.conf&amp;#8221; Add &amp;#8220;NameVirtualHost &lt;em&gt;&amp;#8221; for virtual hosting&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;My personal preference is then to have an &amp;#8220;applications&amp;#8221; folder in the apache conf dir, for which I then add a directive to httpd.conf to load in per-application virtual hosting configurations. It just keeps it nice and clean that way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;mkdir /Library/Apache-2.2.6/conf/applications&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Include conf/applications in httpd.conf&lt;/strong&gt; (in your httpd.conf)&lt;/p&gt;

&lt;h2 id='step_3'&gt;Step 3&lt;/h2&gt;

&lt;p&gt;If you havent already, grab mod_python &lt;a href='http://mirror.fubra.com/ftp.apache.org/httpd/modpython/mod_python-3.3.1.tgz'&gt;from here&lt;/a&gt;. Extract, it and cd into the directory.&lt;/p&gt;

&lt;p&gt;You&amp;#8217;ll then need to configure it with the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;code&amp;gt;./configure --with-apxs=/Library/Apache-2.2.6/bin/apxs \
  --with-python=/Library/Frameworks/Python.framework/Versions/Current/bin/python&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then do &lt;strong&gt;make&lt;/strong&gt; and &lt;strong&gt;sudo make install&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Provided you got no errors upon compilation, all should be well. You just need to add another line to your httpd conf:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LoadModule python_module modules/mod_python.so&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id='step_4'&gt;Step 4&lt;/h2&gt;

&lt;p&gt;Poor yourself a nice cuppa!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Running Django on OSX</title>
   <link href="http://timperrett.com/2007/09/22/running-django-on-osx"/>
   <updated>2007-09-22T18:51:00+01:00</updated>
   <id>hhttp://timperrett.com/2007/09/22/running-django-on-osx</id>
   <content type="html">&lt;p&gt;No doubt you&amp;#8217;ve heard about the new python web framework thats making some waves at the moment - Django.&lt;/p&gt;

&lt;p&gt;As with most &lt;em&gt;nix developers, im running OSX (10.4), and wanted to get a working Django dev environment function to have a play around with it and found that a needed to mess around with a few things to get it working, so I thought id post them up here in case anyone else found them usefull :)&lt;/em&gt;&lt;/p&gt;

&lt;h2 id='step_1'&gt;Step 1&lt;/h2&gt;

&lt;p&gt;Download the python-mac &lt;a href='http://www.pythonmac.org/packages/'&gt;installer from here&lt;/a&gt; and run it. That will give you a working version of the latest python bin.&lt;/p&gt;

&lt;h2 id='step_2'&gt;Step 2&lt;/h2&gt;

&lt;p&gt;Checkout the latest version of Django source like so&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;cd /usr/local&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;svn co http://code.djangoproject.com/svn/django/trunk/ django&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id='step_3'&gt;Step 3&lt;/h2&gt;

&lt;p&gt;If you used the python installer for mac, then the below will work, otherwise, you&amp;#8217;ll need to just tweak the path&amp;#8217;s a bit:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ln -s /usr/local/django/django /Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/django&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id='step_4'&gt;Step 4&lt;/h2&gt;

&lt;p&gt;Add the django source to your path:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PATH=/usr/local/django/django/bin:$PATH&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then that should be it :) However, if your a touch on the forgetfull side when using the terminal, it can be annoying having to keep putting the .py on the end of the django commands, so we&amp;#8217;ll just quickly symlink them so if we forget to add .py, it wont slap us with a kipper&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;cd /usr/local/django/django&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ln -s django-admin.py django-admin&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then your all done! Enjoy Django :)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Very random video...</title>
   <link href="http://timperrett.com/2007/09/22/very-random-video"/>
   <updated>2007-09-22T14:21:00+01:00</updated>
   <id>hhttp://timperrett.com/2007/09/22/very-random-video</id>
   <content type="html">&lt;p&gt;&lt;a href='http://www.youtube.com/watch?v=wLLls9xINZs'&gt;Everyone loves a random video&amp;#8230;&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Running Pound reverse proxy on windows server 2003</title>
   <link href="http://timperrett.com/2007/09/22/running-pound-reverse-proxy-on-windows-server-2003"/>
   <updated>2007-09-22T12:50:00+01:00</updated>
   <id>hhttp://timperrett.com/2007/09/22/running-pound-reverse-proxy-on-windows-server-2003</id>
   <content type="html">&lt;p&gt;Pound is the unix reverse proxy software popularized by Rails deployment over the past 8-12 months. Pound is a unix tool, and was never meant to run under windows - it is however possible to make it run under windows if you package it up with some key DLL files from cygwin :)&lt;/p&gt;

&lt;p&gt;I must stress here that this is not necessarily the best thing to be doing, this post is more about how to do it &lt;strong&gt;if you really want too&lt;/strong&gt; rather than a &amp;#8220;do this, I really recommend it&amp;#8221; type post. There are also some issues with pound and its behavior with X-FORWARDED_FOR headers, but i wont bang on about that here; refer to google for more info. Anyway&amp;#8230; back to the post&amp;#8230;..&lt;/p&gt;

&lt;p&gt;Take the latest pound &lt;a href='http://www.apsis.ch/pound/'&gt;distro from here&lt;/a&gt; then compile it from within Cygwin like so&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;./configure &amp;#8211;without-ssl &amp;#8211;disable-log &amp;#8211;disable-dynscale&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;then&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;make all&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then you should be left with a working binary of pound within your build directory. In order to then make this work in a standalone fashion (I use the term standalone loosely as its still using the cygwin environment) you need to package several DLL files from cygwin:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;cygssl-0.9.8.dll&lt;/strong&gt; (required)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;cygcrypto-0.9.8.dll&lt;/strong&gt; (required)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;cygwin1.dll&lt;/strong&gt; (required)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;pound.exe&lt;/strong&gt; (required, should be fairly obvious!)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;cygrunsrv.exe&lt;/strong&gt; (optional, include only if you want to install pound as a service)&lt;/p&gt;

&lt;p&gt;with these files you can then run pound, and even install it as a service on the host machine. If you do want to install the service, run the following command:&lt;/p&gt;

&lt;p&gt;cygrunsrv &amp;#8211;install Pound &amp;#8211;path X:\applications\pound-2.3.2\bin\pound.exe &amp;#8211;args &amp;#8220;-f X:\applications\pound-2.3.2\config\pound.cfg&amp;#8221; &amp;#8211;stdout X:\applications\pound-2.3.2\log\pound.log &amp;#8211;stderr X:\applications\pound-2.3.2\log\pound.log&lt;/p&gt;

&lt;p&gt;Where &amp;#8220;X:\applications\pound-2.3.2&amp;#8221; is the real path to where ever it is on the file system you chose to install.&lt;/p&gt;

&lt;p&gt;If you don&amp;#8217;t want to compile your own, then you can download my version of &lt;a href='http://timperrett.com/download.html'&gt;pound 2.3.2 for windows here&lt;/a&gt;. It goes without saying I take no responsibility for any problems you might run into by using my compiled version; it worked for me thats all I can say!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Making IIS play nice with Apache on windows server 2003</title>
   <link href="http://timperrett.com/2007/09/21/making-iis-play-nice-with-apache-on-windows-server-2003"/>
   <updated>2007-09-21T14:55:00+01:00</updated>
   <id>hhttp://timperrett.com/2007/09/21/making-iis-play-nice-with-apache-on-windows-server-2003</id>
   <content type="html">&lt;p&gt;Now, being a unix man through and through, I do see the irony that my first blog post is about winows; such is life!&lt;/p&gt;

&lt;p&gt;Anyway&amp;#8230;&lt;/p&gt;

&lt;p&gt;Typically IIS and Apache do not work well together at all, as IIS hogs all IPs (both physical and ARP) on any given win 2003 machine which is why when trying to run anything else on port 80 on any IP can be a total nightmare.&lt;/p&gt;

&lt;p&gt;I recently had to do an install on a win 2003 box where the client wanted to support some of their legacy ASP applications, PHP, but then allowing scope in the future to run Rails, Seam and Django applications. This means running:&lt;/p&gt;

&lt;p&gt;* Apache with mod_python (for Django)&lt;/p&gt;

&lt;p&gt;* Apache proxying to mongrel (for Rails)&lt;/p&gt;

&lt;p&gt;* JBoss for Seam (EJB configuration)&lt;/p&gt;

&lt;p&gt;* IIS for ASP/ASP.NET&lt;/p&gt;

&lt;p&gt;IIS has no real ability to proxy to other backends (which in this instance we need due to the rails requirment) in the way Apache 2.2 does, so I chose to run Apache out front binding to one of my avalible 5 on this machine. Apache then uses proxy pass (or proxy balencer for rails) to pass PHP and ASP requests to IIS. No doubt there are people out there who would have chosen to run PHP on Apache, but due to the way the legacy applications were written, PHP and IIS were already installed so it made sense to leave it &amp;#8220;as is&amp;#8221; - no need to make more work for myself, especially as i only had one night to do the install!&lt;/p&gt;

&lt;h2 id='step_1'&gt;Step 1&lt;/h2&gt;

&lt;p&gt;IIS however requires a bit of wrangling before we can get on with the install of Apache&amp;#8230;Make sure you have your win 2003 install discs with you; as you&amp;#8217;ll need to install the support tools (found in support &amp;gt; tools on the cd). It is however possible to do this without the support tools, but it involves hacking around in the registry. Once you have the support tools installed, were going to be making some changes to let IIS know what exact IP address it can bind too. If you have the support tools installed you can the use the httpcfg tool like so (note: if using RDP you might need to logout then login to get support tools on your PATH)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;httpcfg set iplisten -i 555.555.555.555&lt;/strong&gt; (where this is your IP address)&lt;/p&gt;

&lt;p&gt;If you do not have the support tools (or your just too lazy to dig out that disc from the depths of the server room) you can edit the following registry key:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/HTTP/Paramaters&lt;/strong&gt; in there is a paramater called &lt;strong&gt;ListenOnlyList&lt;/strong&gt; from which you can edit with the list of IP&amp;#8217;s IIS should listen to.&lt;/p&gt;

&lt;p&gt;Once youve done that, restart IIS as usual from the MMC.&lt;/p&gt;

&lt;p&gt;Then you can do a &lt;em&gt;netstat -ano&lt;/em&gt; to see that IIS only binds to the IP you set. Simple.&lt;/p&gt;

&lt;h2 id='step_2'&gt;Step 2&lt;/h2&gt;

&lt;p&gt;Next up you need to download apache. I went with apache 2.2.4 without SSL, which i &lt;a href='http://mirrors.ibiblio.org/pub/mirrors/apache/httpd/binaries/win32/'&gt;grabbed from here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the installer, and make sure you choose on port 80 as a server for all users when installing.&lt;/p&gt;

&lt;p&gt;Once apache is installed, you&amp;#8217;ll need to set up port listening and IP address binding. This is a well discussed topic in the apache manuals so I wont labour the point here. See the &lt;a href='http://httpd.apache.org/docs/2.2/'&gt;apache docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I then set up some virtual hosting to hand my requests off to IIS. Granted, I could have done this with rewrite rules for .asp extensions, but I chose to proxy it on domains, due to my particular circumstances. Heres what my virtual host looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
  ServerName www.domain.co.uk
  ServerAlias domain.co.uk
  ProxyPreserveHost On
  ProxyPass / http://172.16.1.11:3000/
&amp;lt;/VirtualHost&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(Where my site definition within IIS was running on port 3000)&lt;/p&gt;

&lt;h2 id='step_3'&gt;Step 3&lt;/h2&gt;

&lt;p&gt;I then &lt;a href='http://www.python.org/download/'&gt;downloaded Python&lt;/a&gt; and installed it. And then I followed the very good instructions on &lt;a href='http://groups.google.com/group/comp.lang.python/msg/139af8c83a5a9d4f'&gt;setting up mod_python on google groups&lt;/a&gt;&lt;/p&gt;

&lt;h2 id='step_4'&gt;Step 4&lt;/h2&gt;

&lt;p&gt;Do the usual rails install bits and bobs - this is so well document I wont pollute the blogsphere any more :)&lt;/p&gt;

&lt;h2 id='step_5'&gt;Step 5&lt;/h2&gt;

&lt;p&gt;Java time&amp;#8230;. &lt;a href='http://sourceforge.net/project/showfiles.php?group_id=22866&amp;amp;package_id=193295'&gt;Download and run the JEMS installer&lt;/a&gt;. At this point we only want to install JBoss on the box with an EJB configuration; it will take a couple more posts to go into the configuration required to get JBoss Seam up and running so we shant discuss that here.&lt;/p&gt;

&lt;h2 id='summary'&gt;Summary&lt;/h2&gt;

&lt;p&gt;Thats pretty much it. Its not too difficult, you can proxy off to any service you want to (within reason) and you can have all the latest and greatest web serving technologys happily co-exsisting!&lt;/p&gt;</content>
 </entry>
 
 
</feed>
