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)

The Scala way:



  val input = "sample" 
  val encoding = "UTF-8" 

  base64Encode(
    hexDigest(
      input.getBytes(encoding)
    ).getBytes(encoding)
  )

The .NET way



  using System.Security.Cryptography;

  string input = "sample";

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

  StringBuilder sBuilder = new StringBuilder();
  for (int i = 0; i < data.Length; i++){
    sBuilder.Append(data[i].ToString("x2"));
  }

  string hash = sBuilder.ToString();

  Convert.ToBase64String(
    Encoding.UTF8.GetBytes(hash)
  );

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

The Scala way:



  val key: Array[Byte] = "qwehfjgtufkgurifghfkdjfg".getBytes("UTF-8")
  tripleDESEncrypt("sample", key)

The .NET way:



  using System.Security.Cryptography;

  string key = "qwehfjgtufkgurifghfkdjfg";
  string toEnc = "sample";

  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);

Maybe this will help someone avoid the pain I have endured with this! lol.

Picture the scene: Im sat in my chair, working away and then I get a fairly crazed phone call from a co-worker in sales – he apparently has this stunning new idea about how to leverage twitter as a marketing platform…

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 over here

A cunning scheme indeed

So, from the off, this was going to be an interesting campaign to put together because there were numerous issues, including:

  • Lots of concurrent (and asynchronous) read / write ops to Twitter API
  • Backend communication to XMPie cluster
  • Push production status back down to the browser
  • Downloading of avatar images automatically from twitter and insert into XMPie asset source
  • Doing any of this in the given time frame!?

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.

Technology Sandwich

To implement this campaign, I ended up using a whole bunch of different technologies… The implementing stack eventually ended up utilising the following:

  • Lift
  • Dispatch
  • Scala Actors
  • XMPie uProduce
  • XMPie ICP
  • Microsoft SQL Server

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!:

As you can see – quite a number of software components here! I’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.

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 Dispatch

Questions

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’ll get back to you…

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…. for some, alas this is just an ideal as all there proprietary software comes crumbling down under a new kernel.

Friday was one of these momentous days, and yes, my world came crumbling down. For those who don’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!).

Why should I care about IPSecuritas?

This is simple – basically (as above) it rocks and has the following great features:

  • Its speedy.
  • Automatic connection recovery
  • Password persistance
  • Can talk to a bunch of different Firewall types… no more vendor tie-ins
  • Great OSX integration
  • Automatic connection upon login (instantly connected to VPN!)
  • Oh, did I mention its fast?

Removing Checkpoint SecureClient

OK, so now we’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 > Utilities > Terminal) and type the following:



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

Type “yes” 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… so you might as well clean up and keep tidy.

Setting up IPSecuritas

If you havent already, download IPSecuritas from here – 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’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 “XMPie”, thats just what I decided to call my profile)...

Choose the “Open IPSecuritas” 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’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).

So the two boxes in red are the important ones. For Remote IPSec Device you need to fill in the domain name or IP address of your firewall / vpn endpoint; this is organisation specific so i’ve removed mine. Secondly, Network address – 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’t know, check with an IT administrator.

These are standard security options needed to work with the checkpoint vpn – because I work long hours connected to the VPN, i’ve set it to timeout after 10 hours (essentially it never cuts me off and im in charge… sweet).

Again, this is standard checkpoint stuff so just copy the configurations as is – you don’t need to know whats what.

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… if you need this, just use the certificate manager and configure accordingly. I’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!

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:

\\somefileshare

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

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!

Once you have all that, your good to go – just close the window, and click “Start” 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 “office”. If you are having issues, seek help from your IT administrator as it might be a configuration issue – with VPN’s your client much EXACTLY match what the endpoint is configured to… 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’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)

Enjoy, and good luck.

One of the best things about Lift is its amazingly flexible template and resource localization system. This article discusses the mechanisms that you can use to localize your application.

Overview

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.

  • Text localization from property bundles
  • Full template localization
  • Custom resource bundle provider hook

We will now take a look at each localization option in turn, in relative detail stopping to investigate how they work.

Assumed environment

For the length of this article we’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:

Language Code
English en_GB
French fr_FR
German de_DE
Hebrew he_IL

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 “Good afternoon” whilst Australian English might have “Good ay’”.

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:


def localeCalculator(request : Box[HttpServletRequest]): Locale = 
  request.flatMap(r => {
  def workOutLocale: Box[java.util.Locale] = 
  S.findCookie(localeCookieName) match {
    case Full(cookie) => cookie.getValue()
    case _ => Full(LiftRules.defaultLocaleCalculator(request))
  }
  tryo(r.getParameter("locale")) match {
    case Full(null) => workOutLocale
    case Empty => workOutLocale
    case Failure(_,_,_) => workOutLocale
    case Full(selectedLocale) => {
      setLocale(selectedLocale)
      selectedLocale
    }
  }
}).openOr(java.util.Locale.getDefault())

Add this function someplace in your application – here we’ll assume its just in the Boot class, then set it in LiftRules like so:


LiftRules.localeCalculator = localeCalculator _

Text localization from property bundles

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… properties files loaded as a ResourceBundle.

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:

${project.basedir}/src/main/resources/mybundlename_*locale*

So for us, that looks like:


mybundlename_en_GB.properties
mybundlename_fr_FR.properties
mybundlename_de_DE.properties
mybundlename_he_IL.properties

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.

In code:

S.?("mykey")

In template:

<lift:loc locid="mykey">Default Text</lift:loc>

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:

  • Hebrew is a language that is written right-to-left (RTL) so generally the content / css / markup will be quite different
  • 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.

So, to deal with such cases Lift brings you comprehensive template localization which we’ll now discuss.

Template file localization

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:


index_en_GB.html
index_en_AU.html
index_de.html
index_he.html

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… for arguments sake the imagery in the two templates could be different because Australian culture is somewhat more casual than compared to England.

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

Custom resource bundle provider hook

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’s cycle:


LiftRules.resourceBundleFactories.prepend { 
  case (basename, locale) if localeAvalible_?(locale) => 
      CacheResourceBundle(locale)
  case _ => CacheResourceBundle(new Locale("en","GB"))
}

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:


case class CacheResourceBundle(loc: Locale) extends ResourceBundle

Conclusion

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!

One of the confusing things about Lift for new comers are snippets – not only conceptually, but the bewildering array of options they have when choosing snippet implementation style. Users have to choose between snippet reflection, dispatch snippets and even statefull snippets that extend snippet dispatching!

Reflection Snippets

Loading class-based snippets via reflection is the default scheme in Lift as it offers a quick start for development. Given the following code in my snippet package:


import _root_.scala.xml.{NodeSeq,Text}

class HelloWorld {
  def speak = <span>Hello World</span>
}

I could then just call this in any Lift template I wanted by using the following:


<lift:hello_world.speak />

So right there, with no other plumbing we have a working snippet invocation – granted, our example is not feature full but it services our needs for this example. So this is all great, and works perfectly for development / low volume deployment, however when your site starts to scale this method of snippet modeling will become undesirable. Why? Every time you call the reflection snippet in your markup code, a new instance is instantiated and the appropriate method invoked – of course, if you have lots of the same snippet in a single page request cycle this is less than desirable (not to mention if said page is getting thousands of requests)

DispatchSnippet to the rescue!

In Scala we can of course use the object keyword to create a singleton object – this is most helpful in terms of snippets, as comparatively to creating lots of instances, here we will only have a single one which makes for a much more optimal snippet system. Lets take our previous snippet and turn it into a dispatch snippet:


import _root_.scala.xml.{NodeSeq,Text}
import _root_.net.liftweb.http.DispatchSnippet

object HelloWorld extends DispatchSnippet {
  def dispatch = { 
    case "talk" => speak
  }
  def speak = <span>Hello World</span>
}

There is of course a slight downside – the reflection snippets mean no plumbing, but with the DispatchSnippet we will of course just need to let Lift know when we call something in our XHTML what snippet instance we are referring to – we do this with a SnippetDispatchPF call in your Boot.scala file:


  LiftRules.snippetDispatch.append(
    Map("hello_world" -> HelloWorld)
  )

This means in our XHTML we can call:


<lift:hello_world.talk />

This has the exact same output as the reflection style snippet, but only using a single snippet instance for your application.

Admitidally, every time i’ve ever looked at the Lift codebase in TextMate, i’ve always wondered what the hell the “lift-amqp” 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!

AMQP you say?

Yup, thats right. AMQP – Advanced Message Queuing Protocol to the lay’ man not familiar with the acronym. Essentially AMQP is an open standard for enterprise messaging. There are several implementations of the standard, namely, Open AMQ and RabbitMQ – the latter is newer and generally considered to be the defacto implementation. Rabbit MQ is written in ERLang and has clients for Java, .NET, Ruby etc etc.

So where does Lift fit in?

Strictly speaking, it doesn’t. It just so happens that Steve J 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, “lift-amqp” can be used in any Scala application and has no other dependencies within the Lift framework.

Hand-wavy overview

Lets get down to business… 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’t figure out what went where. Being a fairly visual person, I’ve drawn up a diagram that explains the implementation and how you (yes, you reading this) would implement your application:

A working example?

So rather than try to post lots of pictures – I thought just putting up a screen-cast explaining the components would make more sense :-)

The client listener

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’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’s the requests. Its a nice feature.


class DemonstrationSerializedAMQPDispatcher[T](
  queueName: String, factory: ConnectionFactory, 
  host: String, port: Int) extends AMQPDispatcher[T](
    factory, host, port) {
  override def configure(channel: Channel) {
    val ticket = channel.accessRequest("/data")
    channel.exchangeDeclare(ticket, "mult", "fanout")
    channel.queueDeclare(ticket, queueName)
    channel.queueBind(ticket, queueName, "mult", "example.*")
    channel.basicConsume(ticket, queueName, false, 
      new SerializedConsumer(channel, this))
  }
}

So, your probably thinking that this was not the class that I created an instance of during the screencast – and you’d be right. Essentially we still need a wrapper class to mask our dispatcher; the listener proper.

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.

The postman…

So now that you know how the example listens for messages, lets see the posting code…


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

  /**
   * Salute the rabbit!
   */
  def salute = amqp ! AMQPMessage("hey there!")
}

Little explanation needed here – essentially the string sender is just an actor that knows how to respond to AMQPMessage…. it couldn’t be simpler! I hope this has proved helpful and a good overview of the lift-amqp module.

If you would like to download the source code, you can get it from here

Its been a long time since I posted my original application for iPhone – iDashboard – to control XMPie uProduce on the move. I’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!

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&D build of Marketing Console; so right now you’ll have to wait before you can monitor your own campaigns on the move!

If you have feedback, just leave a comment at the bottom of the article. Enjoy…

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.

The Problem

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):


macbookpro:~ timperrett$ sudo rabbitmqctl status
Status of node rabbit@macbookpro ...
{badrpc,nodedown}
...done.

The Solution

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:


rabbit@macbookpro

However, whilst I could ping the host “macbookpro” from terminal, it appears that Rabbit MQ needed it defined in the /etc/hosts file in order to work correctly.

Both strange and annoying, perhaps this will save someone some time!

With my on-going effort to write more documentation and articles for Lift I’ve decided to write a walk through of Lifts dispatching and rewriting mechanisms.

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 this article – it should fill you in on all the particulars.

Application Boot

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:


class Boot {
  def boot {
    // where lift will look for snippets
    LiftRules.addToPackages("eu.getintheloop.tutorial")
  }
}

Ok, so not a great deal going on there… 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:


/product/some-product-link

/** maps onto **/

./webapp/product-display.html

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.

Adding a Rewrite

Pretty much all of application configuration within Lift is done through the LiftRules 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.


import _root_.net.liftweb.http.LiftRules

Next, add the following code below the snippet package definition:


LiftRules.rewrite.prepend(NamedPF("ProductExampleRewrite") {
  case RewriteRequest(
      ParsePath("product" :: product :: Nil, _, _,_), _, _) => 
    RewriteResponse(
      "product-display" :: Nil, Map("product" -> product)
  )
})

Rewrite matching in detail

So lets step through this part by part… we already know about the LiftRules object and what its for, and one of its var properties is “rewrite” – 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.

List[String] is used to match the incoming path – lets take a closer look at our request object and the parameters we pass. From the scaladocs, we can see that RewriteRequest object has the following signiture:


/**
 * 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

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:


/**
 * example 1.
 * matches: GET /some/demo/path
 */

RewriteRequest(
  ParsePath("some" :: "demo" :: "path" :: Nil, "", true, false), 
  GetRequest, _
)

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

RewriteRequest(
  ParsePath("some" :: "image" :: Nil, "png", true, false), 
  PutRequest, _
)

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

RewriteRequest(
  ParsePath("some" :: "demo" :: Nil, "", true, true), _, _
)

/**
 * example 4.
 * matches: GET /product/<item>/details
 */

RewriteRequest(
  ParsePath("product" :: item :: "details" :: Nil, "", true, true), 
    GetRequest, _
)

So far we’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.

The RewriteRequest object has several overload apply methods to keep the verbosity of your code to a minimum – namely, these overloads are:


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])

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:


/**
 * rewrite to a html file in webapp/show.html with no params
 */

RewriteResponse("show" :: Nil)

/**
 * rewrite to a html file in webapp/show.html with 
 * a paramater called "product" from
 * a parameter placeholder called product
 */

RewriteResponse("show" :: Nil, Map("product" -> product))

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

RewriteResponse("example" :: Nil, "pdf")

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:


S.param("product").openOr("fail over product")

By now I presume you are a rewriting guru!... that might be a bit overboard, but I hope you found this guide informative and useful.

Overview

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’ve seen some fairly ugly abuse of scala.xml._ within Lift snippets… 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!

All the code snippets below presume the following imports:


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}

Also, all the methods are a part of the snippet class “Demo”.

Basic Binding

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’ll just create a text input and populate its value.

Scala Snippet


var tempValue: String = "" 

def exampleOne(xhtml: NodeSeq): NodeSeq = bind("example", xhtml,
  "item_one" -> SHtml.text(
   tempValue, // the "read" value
   tempValue = _), // the "write" function
  "submit" -> SHtml.submit("Submit", () => Log.info(tempValue))
)

So, lets just review quickly. We’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.

XHTML Code


<lift:demo.example_one form="post">
  <p>Sample input: <example:item_one example:id="demo_id" /></p>
  <p><example:submit /></p>
</lift:demo.example_one>

You can see how the prefix we specified in the bind function (“example”) is now used in the markup body of the snippet. Also, note how the actual snippet call uses snake_case (“example_one”) when our method is called “exampleOne” – Lift is clever enough to know what method you are trying to use… this ensures your designers dont moan about camel cased markup!

Binding++

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.

Before we begin lets assume that we have a model class called “User”, and it has the fields:

  • first_name – MappedString
  • last_name – MappedString
  • email – MappedEmail
  • display_email – MappedBoolean

In this fictional form, users just enter their details and a new database user row is added.

Scala Snippet


def exampleTwo(xhtml: NodeSeq): NodeSeq = {
  var user: User = new User
  def submitHandler() = {
    if(user.saveMe){
      S.redirectTo("thank-you")
    }
  }
  bind("example",xhtml,
    "first_name" -> SHtml.text(user.first_name, user.first_name(_)),
    "last_name" -> SHtml.text(user.last_name, user.last_name(_))
    "users_email" -> SHtml.text(user.email, user.email(_)),
    "display_email" -> SHtml.checkbox(false, user.display_email(_)),
    "submit" -> SHtml.submit("Submit", submitHandler _)
  )
}

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.

XHTML Code


<lift:demo.example_two form="post">
  <p>
    <label for="first_name">
      User name <example:first_name example:id="first_name" />
    </label>
  </p>
  <p>
    <label for="last_name">
      Last name <example:last_name example:id="last_name" />
    </label>
  </p>
  <p>
    <label for="users_email">
      Email <example:users_email example:id="users_email" />
    </label>
  </p>
  <p>
    Display your email? <example:display_email />
  </p>
  <p><example:submit /></p>
</lift:demo.example_two>

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… there is no crazy magic binding going on between the names of the bind placeholders and what you put in them… its purely a convention thing / coincidence that they are called the same. You are free to call them whatever you feel appropriate.

Advanced Binding

Its when you need advanced binding that lift really comes into play – lets take the oh-so common idiom of one article having many “tags”; as you are reading this on my blog i’ll assume you are familiar with the notion.

So, assuming we have a Article model object with the appropriate fields, and we have a Tag model object that has a MappedForeignKey field relating back to the Article model object. We’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:


 article.tags.flatMap(tag => ....)

Lets get down to business:

Scala Snippet


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

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 the lift wiki) – we can the bind the contents of that model object and also iterate over the list of tags associated with that article.

The new stuff here is both the nested bind, and the chooseTemplate(...) 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’ll see this working in the view code below.

XHTML Code


<lift:demo.example_three>
  <p><a:body /></p>
  <p>Tagged with: <a:tags> 
  <tag:list>
    | <t:name /> |
  </tag:list>
</a:tags></p>
</lift:demo.example_three>

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 “t” 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.

This concludes the tutorial – I hope this has been useful for someone :-)

I was just looking at the Lift’s StreamingResponse and was a bit bemused by the structural type being used for the first parameter. After some fiddling around I realized that:



data: {def read(buf: Array[Byte]): Int}

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 Lift’s StreamingResponse and thinking “what the hell”, 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!

A sample implementation might look like:



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

So, to recap, structural types are awesome!

Recently I’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?

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.

Rhino Ball

For example, lets take Rhino Ball – 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.

Perhaps this is just a prime example of marketing depts. blowing budgets for the simple reason “its cool”.

I just committed new functionality into lift master for handling the abstraction of i18n ResourceBundles’ that are powered by custom sources – for example, database driven localization, or hooking into some translation service.

Now, you can do:



    LiftRules.resourceBundleFactories.prepend { 
      case (_, locale) if locale.getISO3Language == "eng" 
         => new MyResources
      case (_, locale) if locale.getISO3Language == "swe" 
         => new MyResources_sv
      case (_, locale) => new DBResourceLoader(locale)
    }

In this example we assume that you have fictional java.util.ResourceBundle subclasses called “MyResources” and “MyResources_sv”. Furthermore, if the ISO 639-3 code is not either “eng” or “swe”, then it attempts to load it from another fictional ResourceBundle subclass “DBResourceLoader”.

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 :-)

NB: What follows is pure opinion and based on no actual metric

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.

For a lot of organizations, open source software is generally seen as too much of a “risk” 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.

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 “why”...

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…? or something they already made in their spare time for that OSS framework or such?

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 “leaking in through the backdoor” 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.

Whatever happens – I for one really do hope that SME and Corporate companies open their eyes to what comunity powered development has to offer.

Stop seeing the risk, and start appreciating the possibilities :-)

Over and out.

I have recently been working on some API automation for XMPie uProduce and after some head scratching, realized that the username paramater has now changed format.

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:

Customer Name: ABC
User Name: badger
Password: 123456

You would need to present the username in your API call like so:

ABC\badger

I hope this save someone, somewhere, some time!