<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2726786215957001832</id><updated>2011-12-21T09:56:07.885Z</updated><category term='Swing'/><category term='yaml'/><category term='Tomcat'/><category term='Scala'/><category term='Ivy'/><category term='soy'/><category term='guice'/><category term='appengine'/><category term='java'/><category term='JMX'/><category term='groovy'/><category term='html'/><category term='gdata'/><category term='Processing'/><category term='YQL'/><category term='maven'/><category term='ScalaVsGroovy'/><category term='Spring'/><category term='exif'/><category term='Ant'/><category term='google'/><category term='gnome'/><title type='text'>Froth &amp; Java</title><subtitle type='html'>Java, Groovy, Scala, Etc</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.frothandjava.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>33</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-1712719351653943714</id><published>2011-05-16T09:06:00.015Z</published><updated>2011-05-16T10:35:41.642Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='JMX'/><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><title type='text'>Using a Tomcat Engine JMX Proxy Bean With Spring</title><content type='html'>Recently, I needed to determine which Tomcat server in a load balanced environment an application was running on. One way to to do this is to look at the jvmRoute property of the running Tomcat Engine. If you're in a load balanced environment you'll probably see the jvmRoute appended to the session id. What I wanted to do was to get that value directly, without any reference to a session. Here's how I did it.&lt;br /&gt;&lt;br /&gt;One quick note before I begin - obviously, this ties your application to Tomcat so you might want to look at ways of abstracting this out if server portability is a concern.&lt;br /&gt;&lt;br /&gt;The first thing you need to do is make sure that a jvmRoute value is being set. This is as simple as adding something like -DjvmRoute=jvm1 to your VM arguments.&lt;br /&gt;&lt;br /&gt;Next up is adding a &lt;a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/jmx/access/MBeanProxyFactoryBean.html"&gt;MBeanProxyFactoryBean &lt;/a&gt;to your application context. To inject a proxy for the &lt;a href="http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/Engine.html"&gt;Engine&lt;/a&gt;, you need&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;br /&gt;&amp;lt;bean id="tomcatEngineProxy" class="org.springframework.jmx.access.MBeanProxyFactoryBean"&gt;&lt;br /&gt;  &amp;lt;property name="objectName" value="Catalina:type=Engine" /&gt;&lt;br /&gt;  &amp;lt;property name="proxyInterface" value="org.apache.catalina.Engine" /&gt;&lt;br /&gt;  &amp;lt;property name="useStrictCasing" value="false" /&gt;&lt;br /&gt; &amp;lt;/bean&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You may or may not need to play about with the objectName value depending on how you have configured your Engine in server.xml - have a look &lt;a href="http://tomcat.apache.org/tomcat-6.0-doc/funcspecs/mbean-names.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Setting useStrictCasing to false is especially important. For some reason Spring's default behaviour is to set useStrictCasing to true. What this means is that when you access a property via a getter (in our case, getJvmRoute) causing the proxy to ask for the property value over JMX, by default it ignores normal Javabean style conventions and asks for the "JvmRoute" property. Apache is expecting to be asked for the "jvmRoute" property and you'll be on the receiving end of a "cannot find property" error. Setting useStrictCasing to false makes Spring ask for "jvmRoute" instead. I'd really like to know why useStrictCasing is set to true by default, as it seems to violate the principle of least surprise.&lt;br /&gt;&lt;br /&gt;Now that we have a proxy for the Tomcat Engine in the context, we can autowire it where it's needed -&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;@Autowired private Engine engine;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and getting the jvmRoute is as simple as&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;engine.getJvmRoute()&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Thanks go out to &lt;a href="http://stackoverflow.com/users/40342/joachim-sauer"&gt;Joachim Sauer on stackoverflow&lt;/a&gt; for &lt;a href="http://stackoverflow.com/questions/5961888/how-to-programmatically-determine-which-load-balanced-tomcat-server-the-webapp"&gt;pointing me in the right direction&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-1712719351653943714?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/1712719351653943714/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=1712719351653943714' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/1712719351653943714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/1712719351653943714'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2011/05/using-tomcat-engine-jmx-proxy-bean-with.html' title='Using a Tomcat Engine JMX Proxy Bean With Spring'/><author><name>Scot</name><uri>http://www.blogger.com/profile/01366131922305820386</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-8459206366760540625</id><published>2010-08-26T21:48:00.006Z</published><updated>2010-08-26T23:04:18.714Z</updated><title type='text'>Google App Inventor and node.js</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;p&gt;My invite to Google's new, easy to use &lt;a href="http://appinventor.googlelabs.com/about/"&gt;App Inventor for Android&lt;/a&gt; came through recently and within minutes I had hello world running. Even better, after a few more minutes of playing with the programming toybox I had an easy to use tool.&lt;/p&gt;&lt;p&gt;For awhile now I've wanted a simple tool that would let me go around scanning the barcodes of books that I own and saving them into a text file for importing into &lt;a href="http://www.librarything.com/"&gt;LibraryThing&lt;/a&gt; but I haven't had the spare time to learn enough Android programming to build one. A combination of a simple client built with App Inventor and a simple server written with Node and I had the tool I've been wanting in a matter of minutes.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The AppInventor Client&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;AppInventor comes in two parts - an "Interface Builder" website and a visual coding environment where you connect up blocks of code (that sits on top of the Kawa dialect of Scheme - which makes App Inventor coding a lot like a combintation of Lego and Lisp). I quickly added a label (to display the scanned ISBN number), a button (to start the scan) and then two non-visible components: a barcode scanner and a TinyWebDB. Once the UI was done it was off to the coding environment to wire everything up.&lt;/p&gt;&lt;p&gt;The only not quite straightforward part of all this is the TinyWebDB component as it's App Inventor's only built in way of accesing a web service (other than Twitter, which has it's own component). However, TinyWebDB isn't a generic web service client, it's meant for storing and retreiving simple key/value pairs so I needed to write my server with that in mind.&lt;/p&gt;&lt;p&gt;As the coding environment is visual, it really doesn't lend itself to a blog post. Fortunately, you can download the app source code in a zip file and marvel at the underlying code. The meat of the app is:&lt;/p&gt;&lt;pre class="brush: clojure"&gt;&lt;br /&gt;&lt;com.google.youngandroid.runtime&gt;;;; Screen1&lt;br /&gt;(do-after-form-creation (set-and-coerce-property! Screen1 'Title "Screen1" 'text)&lt;br /&gt;)&lt;br /&gt;;;; Label1&lt;br /&gt;(add-component Screen1 Label Label1 (set-and-coerce-property! Label1 'Text "Text for Label1" 'text)&lt;br /&gt;)&lt;br /&gt;;;; Button1&lt;br /&gt;(add-component Screen1 Button Button1 (set-and-coerce-property! Button1 'Text "Scan" 'text)&lt;br /&gt;)&lt;br /&gt;(define-event Button1 Click()&lt;br /&gt;(call-component-method 'BarcodeScanner1 'DoScan (list)&lt;br /&gt;*no-coercion*)&lt;br /&gt;&lt;br /&gt;)&lt;br /&gt;;;; BarcodeScanner1&lt;br /&gt;(add-component Screen1 BarcodeScanner BarcodeScanner1 )&lt;br /&gt;(define-event BarcodeScanner1 AfterScan( result )&lt;br /&gt;(call-component-method 'TinyWebDB1 'StoreValue (list "isbn" (get-property BarcodeScanner1 Result)&lt;br /&gt;)&lt;br /&gt;'( text any)&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;(set-and-coerce-property! Label1 'Text (get-property BarcodeScanner1 Result)&lt;br /&gt;'text)&lt;br /&gt;&lt;br /&gt;)&lt;br /&gt;;;; TinyWebDB1&lt;br /&gt;(add-component Screen1 TinyWebDB TinyWebDB1 (set-and-coerce-property! TinyWebDB1 'ServiceURL "http://192.168.1.101:8765" 'text)&lt;br /&gt;)&lt;br /&gt;(init-runtime  #f)&lt;br /&gt;&lt;/com.google.youngandroid.runtime&gt;&lt;/pre&gt;&lt;br /&gt;While that's not quite the entire source, it does give some idea of what goes on underneath.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Node(.js)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;TinyWebDB will post a key/value pair to whatever server you want. So I needed a simple server that would sit there, extract the value and output to stdout (which will then get piped into a file). This seemed like the perfect opportunity to try Node (I can't tell if it's supposed to be called node or node.js), which is a Javascript execution environment based on the V8 engine for writing network programs. A quick and dirty Javascript hack produced:&lt;br /&gt;&lt;pre class="brush: js"&gt;&lt;br /&gt;var http = require('http');&lt;br /&gt;http.createServer(function (request, response) {&lt;br /&gt;request.on('data', function(chunk) {&lt;br /&gt;    var b = chunk.toString('ascii', 0, chunk.length);&lt;br /&gt;    var v = b.split("&amp;amp;")[1];&lt;br /&gt;    var vv = v.split("=")[1];&lt;br /&gt;    var vvv = vv.replace("%22", "");&lt;br /&gt;    var vvvv = vvv.replace("%22", "");&lt;br /&gt;    console.log(vvvv);&lt;br /&gt;});&lt;br /&gt;response.writeHead(200, {'Content-Type': 'text/plain'});&lt;br /&gt;response.end('Hello, World\n');&lt;br /&gt;}).listen(8765);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Undoubtedly a regexp could have been used, but would have required more mental effort than I really wanted. In case you're wondering about the response, TinyWebDB apparently essentially disregards it, so sending back Hello, World doesn't hurt.&lt;br /&gt;&lt;/p&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In a matter of minutes I had a useful (at least to me) tool. I have a feeling that this is what App Inventor will mostly be used for - simple apps that satisfy a single person's needs. It's not going cause the "Animated Cat App Apocalypse" in the Android Market that some commentators have worried about. I have no idea if it will be of any use as the "Logo for the modern age" that was the original reason for it's existence (there are still references to "Young Android" in the generated code and the application icons are of an adult and child robot). I would call it the "Visual Basic for the modern age" except that it feels wrong comparing something that "&lt;span style="font-style: italic;"&gt;is part of an ongoing movement in computers and education that began with the work of Seymour Papert and the MIT Logo Group in the 1960s&lt;/span&gt;" with Visual Basic.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-8459206366760540625?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/8459206366760540625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=8459206366760540625' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/8459206366760540625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/8459206366760540625'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2010/08/google-app-inventor-and-nodejs.html' title='Google App Inventor and node.js'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-5299089528224116706</id><published>2010-02-09T14:45:00.007Z</published><updated>2010-02-09T15:49:19.053Z</updated><title type='text'>Using Scala To Configure Spring's DispatcherServlet</title><content type='html'>After reading Francois Armand's post about "&lt;a href="http://fanf42.blogspot.com/2010/01/scala-and-spring-3-javaconfig.html"&gt;Scala and Spring 3 JavaConfig&lt;/a&gt;", I was inspired to try and use Scala to replace some servletname-servlet.xml Spring config files.&lt;br /&gt;&lt;br /&gt;I have a small Scala/Spring MVC project that at the moment uses two DispatcherServlets, one for each controller. There was a historical reason for this (I needed two different Velocity configurations) and while I can now probably get away with a single DispatcherServlet, what I'm going to try to do is move one of the servlets over to a Scala based configuration and leave one using xml based configuration.&lt;br /&gt;&lt;br /&gt;Of the two configurations, I'm going to move the simplest one over. It does nothing more than define a root controller bean. So the Scala config should be as simple as&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;@Configuration&lt;br /&gt;class CalendarConfig {&lt;br /&gt; @Bean def rootController = new CalendarController()&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And a quick change to my web.xml&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;...&lt;br /&gt;    &amp;lt;servlet&amp;gt;&lt;br /&gt;        &amp;lt;servlet-name&amp;gt;calendars&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;        &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;        &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;&lt;br /&gt;        &amp;lt;!-- Configure DispatcherServlet to use JavaConfigWebApplicationContext&lt;br /&gt;             instead of the default XmlWebApplicationContext --&amp;gt;&lt;br /&gt;        &amp;lt;init-param&amp;gt;&lt;br /&gt;            &amp;lt;param-name&amp;gt;contextClass&amp;lt;/param-name&amp;gt;&lt;br /&gt;            &amp;lt;param-value&amp;gt;&lt;br /&gt;                org.springframework.web.context.support.AnnotationConfigWebApplicationContext&lt;br /&gt;            &amp;lt;/param-value&amp;gt;&lt;br /&gt;        &amp;lt;/init-param&amp;gt;&lt;br /&gt;        &amp;lt;!-- Again, config locations must consist of one or more comma- or space-delimited&lt;br /&gt;             and fully-qualified @Configuration classes --&amp;gt;&lt;br /&gt;        &amp;lt;init-param&amp;gt;&lt;br /&gt;            &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;            &amp;lt;param-value&amp;gt;com.maethorechannen.calendars.CalendarConfig&amp;lt;/param-value&amp;gt;&lt;br /&gt;        &amp;lt;/init-param&amp;gt;&lt;br /&gt;    &amp;lt;/servlet&amp;gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I started my app up in my local development Google App Engine server and it failed to start up, thanks to "java.lang.IllegalStateException: CGLIB is required to process @Configuration classes. Either add CGLIB to the classpath or remove the following @Configuration bean definitions: [calendarConfig]". I added cglib-nodep-2.2 (available from &lt;a href="http://sourceforge.net/projects/cglib/files/"&gt;here&lt;/a&gt; if you're not using something like maven or ivy) to my library of jars and it started to work. &lt;br /&gt;&lt;br /&gt;In case anyone's interested - I pushed it to App Engine and it still worked (occasionally, what works locally doesn't work when on the Big G's servers). One thing I'm really interested in seeing is what (if any) sort of impact on startup times programmatic configuration has compared to XML configuration. When using GAE every millisecond of startup time counts and I would think Scala based configuration should be quicker.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;What's interesting to note (at least to me) is that I didn't need to create a global WebApplicationContext or move everything over to Java(Scala) based configuration, which is something I wasn't sure about after reading the &lt;a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#context-create"&gt;documentation from SpringSource&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-5299089528224116706?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/5299089528224116706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=5299089528224116706' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/5299089528224116706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/5299089528224116706'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2010/02/using-scala-to-configure-springs.html' title='Using Scala To Configure Spring&apos;s DispatcherServlet'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-3220426905916474484</id><published>2010-02-09T11:55:00.006Z</published><updated>2010-02-09T13:58:38.106Z</updated><title type='text'>Scala + Spring + Templates - Velocity</title><content type='html'>Next up on my list of template engines to try with Scala &amp;amp; Spring - Velocity. Unlike FreeMarker, I had actual success in getting it to work. Unsurprisingly, "Native" Scala object support needed to be added in - fortunately the way Velocity was designed makes that easy.&lt;br /&gt;&lt;br /&gt;Velocity uses introspection/reflection to access properties and methods on an object and this is where the Scala customizations fit in. The first thing to create is a subclass of &lt;a href="http://velocity.apache.org/engine/releases/velocity-1.6.2/apidocs/org/apache/velocity/util/introspection/UberspectImpl.html"&gt;UberspectImpl&lt;/a&gt; which does two things - return a java.util.Iterator for iterable objects and return a &lt;a href="http://velocity.apache.org/engine/releases/velocity-1.6.2/apidocs/org/apache/velocity/util/introspection/VelPropertyGet.html"&gt;VelPropertyGet&lt;/a&gt; object for getting access to an object's properties. There is a third thing that could also be done - returning a &lt;a href="http://velocity.apache.org/engine/releases/velocity-1.6.2/apidocs/org/apache/velocity/util/introspection/VelPropertySet.html"&gt;VelPropertySet&lt;/a&gt; object to support setting properties from Velocity but I haven't implemented this as I don't need that functionality at the moment.&lt;br /&gt;&lt;br /&gt;Getting a Java Iterator is fairly straightforward (with Scala 2.7.7 - I'm not sure what, if any, changes will be needed with 2.8)&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;   override def getIterator(obj: java.lang.Object, i: Info): JavaIterator[_] = {&lt;br /&gt;     def makeJavaIterator(iter: Iterator[_]) =  new JavaIterator[AnyRef] {&lt;br /&gt;        override def hasNext() = iter.hasNext&lt;br /&gt;        override def next() = iter.next().asInstanceOf[AnyRef]&lt;br /&gt;           override def remove() = throw new java.lang.UnsupportedOperationException("Remove not supported")&lt;br /&gt;       }&lt;br /&gt;    &lt;br /&gt;     obj match {&lt;br /&gt;       case i: Iterable[_] =&gt; makeJavaIterator(i.elements)&lt;br /&gt;       case i: Iterator[_] =&gt; makeJavaIterator(i)&lt;br /&gt;       case _ =&gt; super.getIterator(obj, i)&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The method to return a VelPropertyGet object is almost as simple - but it also shows that we need two more classes - one for accessing Scala properties and one for accessing Scala Map members like they're properties.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt; override def getPropertyGet(obj: java.lang.Object, identifier: String, i: Info): VelPropertyGet = {&lt;br /&gt;   if (obj != null) {&lt;br /&gt;     val claz = obj.getClass()&lt;br /&gt;&lt;br /&gt;        val executor = obj match {&lt;br /&gt;       case m: Map[_, _] =&gt; new ScalaMapGetExecutor(log, claz, identifier)        &lt;br /&gt;       case _ =&gt; new ScalaPropertyExecutor(log, introspector, claz, identifier)&lt;br /&gt;         &lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;        if (executor.isAlive) {&lt;br /&gt;          new VelGetterImpl(executor)&lt;br /&gt;        } else {&lt;br /&gt;          super.getPropertyGet(obj, identifier, i)&lt;br /&gt;        }&lt;br /&gt;   } else {&lt;br /&gt;     null&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(You can get the full source code &lt;a href="http://github.com/3below/verla/raw/master/src/main/scala/info/threebelow/verla/mvc/view/velocity/ScalaUberspect.scala"&gt;here&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;To access Scala style properties I'll need a Scala specific subclass of PropertyExecutor. The code to access properties from Scala objects is once again trivial. In fact, because of the way Scala generates it's getter methods the code to access Scala properties is simpler than the code to access JavaBean style properties. (&lt;a href="http://github.com/3below/verla/raw/master/src/main/scala/info/threebelow/verla/mvc/view/velocity/ScalaPropertyExecutor.scala"&gt;source&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;override def discover(clazz: java.lang.Class[_], property: String) = {&lt;br /&gt;     val params = Array[java.lang.Object]()&lt;br /&gt;  setMethod(introspector.getMethod(clazz, property, params))&lt;br /&gt;  if(!isAlive()) {&lt;br /&gt;    super.discover(clazz, property)&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Compare that to the code in the &lt;a href="http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/PropertyExecutor.java?view=co"&gt;parent class&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class"java"&gt;&lt;br /&gt; protected void discover(final Class clazz, final String property)&lt;br /&gt;    {&lt;br /&gt;        /*&lt;br /&gt;         *  this is gross and linear, but it keeps it straightforward.&lt;br /&gt;         */&lt;br /&gt;&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;            Object [] params = {};&lt;br /&gt;&lt;br /&gt;            StringBuffer sb = new StringBuffer("get");&lt;br /&gt;            sb.append(property);&lt;br /&gt;&lt;br /&gt;            setMethod(introspector.getMethod(clazz, sb.toString(), params));&lt;br /&gt;&lt;br /&gt;            if (!isAlive())&lt;br /&gt;            {&lt;br /&gt;                /*&lt;br /&gt;                 *  now the convenience, flip the 1st character&lt;br /&gt;                 */&lt;br /&gt;&lt;br /&gt;                char c = sb.charAt(3);&lt;br /&gt;&lt;br /&gt;                if (Character.isLowerCase(c))&lt;br /&gt;                {&lt;br /&gt;                    sb.setCharAt(3, Character.toUpperCase(c));&lt;br /&gt;                }&lt;br /&gt;                else&lt;br /&gt;                {&lt;br /&gt;                    sb.setCharAt(3, Character.toLowerCase(c));&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                setMethod(introspector.getMethod(clazz, sb.toString(), params));&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        /**&lt;br /&gt;         * pass through application level runtime exceptions&lt;br /&gt;         */&lt;br /&gt;        catch( RuntimeException e )&lt;br /&gt;        {&lt;br /&gt;            throw e;&lt;br /&gt;        }&lt;br /&gt;        catch(Exception e)&lt;br /&gt;        {&lt;br /&gt;            String msg = "Exception while looking for property getter for '" + property;&lt;br /&gt;            log.error(msg, e);&lt;br /&gt;            throw new VelocityException(msg, e);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It took me a little while to get Maps working (even though there's not much code to show for it). &lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;class ScalaMapGetExecutor(val llog: Log, val clazz: java.lang.Class[_], val property: String) extends MapGetExecutor(llog, clazz, property) {&lt;br /&gt; override def isAlive = true&lt;br /&gt;&lt;br /&gt; override def execute(o: AnyRef) = o.asInstanceOf[Map[String, AnyRef]]&lt;br /&gt;                                 .getOrElse[AnyRef](property, null).asInstanceOf[java.lang.Object]&lt;br /&gt;      &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;All that's left to do now is configure Velocity from Spring so that it uses the Scala specific Uberspector instead of the default. So, in my servletname-servlet.xml file I needed to add the following&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" style="xml"&gt;&lt;br /&gt;&amp;lt;bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer"&amp;gt;&lt;br /&gt;  &amp;lt;property name="resourceLoaderPath" value="/WEB-INF/views/"/&amp;gt;&lt;br /&gt;    &amp;lt;property name="velocityProperties"&amp;gt;&lt;br /&gt;    &amp;lt;props&amp;gt;&lt;br /&gt;      &amp;lt;prop key="runtime.introspector.uberspect"&amp;gt;info.threebelow.verla.mvc.view.velocity.ScalaUberspect&amp;lt;/prop&amp;gt;&lt;br /&gt;    &amp;lt;/props&amp;gt;&lt;br /&gt;  &amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-3220426905916474484?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/3220426905916474484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=3220426905916474484' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/3220426905916474484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/3220426905916474484'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2010/02/scala-spring-templates-velocity.html' title='Scala + Spring + Templates - Velocity'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-1951521854835417334</id><published>2010-01-23T18:09:00.003Z</published><updated>2010-01-25T20:58:13.572Z</updated><title type='text'>Scala + Spring + Templates - the story so far</title><content type='html'>I've been writing a fairly simple web app with Scala and Spring that will be running on Google's App Engine. I've been trying to decide which template language (or even languages) to write my views in. I'll be rendering a lot of non-HTML and non-XML and over the years I've noticed some template engines are better at this than others. Also, I'm looking for first class Scala support (so anything you can do with a Java Bean you can do with a Scala object) - ideally built in and at worst trivial to add. Here's what I've come across so far:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Closure Templates&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I like Google's Closure Template, but there's no "out of the box" support for it in Spring. If I can't find another template engine I like then I will come back and look at how to add some support.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;FreeMarker&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I will start at the point where my experiments ended - apparently &lt;a href="http://sourceforge.net/tracker/?func=detail&amp;amp;aid=2921112&amp;amp;group_id=794&amp;amp;atid=100794"&gt;FreeMarker doesn't currently work on GAE&lt;/a&gt;, as FreeMarker uses some swing classes that aren't available in GAE. This is a show stopper. I didn't run in to this during my experiments as it was working on the local dev server and I wasn't aware of this problem until I was submitting a bug for another problem I found.&lt;br /&gt;&lt;br /&gt;During my experiments, I found several other issues, one of which calls into question using FreeMarker with Spring and Java, let alone Scala.&lt;br /&gt;&lt;br /&gt;First, there isn't built in object wrapping for Scala objects. By default, FreeMarker will treat Scala objects as Java objects, but as plain Scala objects don't follow JavaBeans conventions access to getters ceases to be trivial. I was able to whip up a Scala specific FreeMarker Model and ObjectWrapper with relative ease, but then I ran into another problem - there doesn't appear to be an easy way in Spring to configure FreeMarker with an alternative ObjectWrapper.&lt;br /&gt;&lt;br /&gt;The answer was to create a subclass of org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer and modifying one of the Configuration related methods to return a Configuration with an ObjectWrapper property set to my Scala specific ObjectWrapper. However, I then ran into a problem that I eventually traced to what appears to be a bug in FreeMarker. When Spring sends a model to FreeMarker it uses FreeMarker's AllHttpScopesHashModel - unfortunately &lt;a href="http://freemarker.svn.sourceforge.net/viewvc/freemarker/trunk/freemarker/src/freemarker/ext/servlet/AllHttpScopesHashModel.java?revision=799&amp;amp;view=markup"&gt;AllHttpScopesHashModel's constructor &lt;/a&gt;doesn't let it's super class know about the ObjectWrapper that was passed in (it just stores it in a final variable that is private to AllHttpScopesHashModel). This means inherited methods fall back to using Fremarker's default ObjectWrapper - so Scala objects don't work. While working with the FreeMarker source code to make sure this is what was going wrong (it was), I ran into two more issues with FreeMarker.&lt;br /&gt;&lt;br /&gt;As I was using the trunk from FreeMarker's SVN repository I assume I was using what will be the 2.4 release of FreeMarker. The first problem I ran into with this was that Spring's &lt;a href="https://src.springframework.org/svn/spring-framework/trunk/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerView.java"&gt;FreeMarkerView&lt;/a&gt; imports freemarker.core.ParseException, unfortunately ParseException has been moved to &lt;a href="http://freemarker.svn.sourceforge.net/viewvc/freemarker/trunk/freemarker/src/freemarker/core/parser/ParseException.java?revision=894&amp;amp;view=markup"&gt;freemarker.core.parser.ParseException&lt;/a&gt; which obviously breaks Spring 3. As I said above, I have doubts about about using FreeMarker with Spring and any language - this is the reason why. At some point this backwards incompatible API change is going cause someone, somewhere a lot of pain and I don't want to be that person.&lt;br /&gt;&lt;br /&gt;While mucking about with FreeMarker's source, I ran into another problem. FreeMarker 2.4 will have some new security features which seemed to cause no end of trouble with GAE. While you should be able turn these features off in the Configuration object, setting the secure property to false had no impact on getting FreeMarker to work with GAE. While I had pretty much given up on FreeMarker by this point, I still wanted to make sure that the reason why my ObjectWrapper wasn't working was because of AllHttpScopesHashModel's constructor so I commented out some security related lines in FreeMarker and eventually got it all working.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Summary&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I won't be using FreeMarker. There are still a few more template engines to look at before I'll fall back to forcing Closure Templates to work with Spring (I would be astounded if it doesn't work GAE). So, I'll carry on my search (Velocity is probably next).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-1951521854835417334?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/1951521854835417334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=1951521854835417334' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/1951521854835417334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/1951521854835417334'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2010/01/scala-spring-templates-story-so-far.html' title='Scala + Spring + Templates - the story so far'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-5781860735991552035</id><published>2009-12-22T21:44:00.004Z</published><updated>2009-12-22T22:39:23.012Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='Ant'/><category scheme='http://www.blogger.com/atom/ns#' term='Ivy'/><title type='text'>A Basic Ant+Ivy+Scala Setup</title><content type='html'>I've decided that for my latest project I'd give Ant with Ivy a go as my build system. To start with, I'm going to try for the simplest possible setup necessary in order to compile my project (so at this stage, it's not even rolling the output up into a jar - I can fix that later). At it's most basic level, this means that I'll need two XML files to get everything to build:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;ivy.xml&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ivy.xml contains information about the dependencies needed to build the project. To compile scala source, I'll need to add two dependencies - scala-library and scala-compiler.&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;ivy-module version="2.0"&amp;gt;&lt;br /&gt;    &amp;lt;info organisation="com.maethorechannen" module="snow-core"/&amp;gt;&lt;br /&gt;    &amp;lt;dependencies&amp;gt;&lt;br /&gt;  &amp;lt;dependency org="org.scala-lang" name="scala-library" rev="2.7.7"/&amp;gt;&lt;br /&gt;  &amp;lt;dependency org="org.scala-lang" name="scala-compiler" rev="2.7.7"/&amp;gt;&lt;br /&gt;         &amp;lt;!-- other dependecies --&amp;gt;&lt;br /&gt;    &amp;lt;/dependencies&amp;gt;&lt;br /&gt;&amp;lt;/ivy-module&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you've used Maven then this will look vaguely familiar yet more compact - groupId becomes org, artifactId becomes name and version becomes rev. As by default Ivy uses Maven's repositories, you can use the same values as you would in Maven.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;build.xml&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My build.xml will need to do 3 things:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;download ivy&lt;/li&gt;&lt;br /&gt;&lt;li&gt;setup scala&lt;/li&gt;&lt;br /&gt;&lt;li&gt;compile&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Strictly speaking, the first item is not technically required if I manually install Ivy into Ant. For the moment, it seems easier if I just set it up so that Ivy gets automagically installed if need be. Fortunatly, the &lt;a href="https://svn.apache.org/repos/asf/ant/ivy/core/trunk/src/example/go-ivy/build.xml"&gt;ivy-go example build.xml file&lt;/a&gt; shows us how to do this.&lt;br /&gt;&lt;br /&gt;The Scala side of things is also fairly straightforward. The scala-lang.org page on &lt;a href="http://www.scala-lang.org/node/98"&gt;Scala Ant Tasks&lt;/a&gt; gave me a fairly good idea of what needed to be done, however I had to make a few changes:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;make the init target depend on the install-ivy target&lt;/li&gt;&lt;br /&gt;&lt;li&gt;modify init so that it executes ivy:retrieve (which downloads the dependencies) and modify the way init generates the build classpath so that it includes jars from the lib directory&lt;/li&gt;&lt;br /&gt;&lt;li&gt;modify the taskdef that imports the scala tasks (also in the init target) so that it finds scala-compiler and scala-library in the lib directory and not in scala.home&lt;/li&gt;&lt;br /&gt;&lt;li&gt;modify the build target, so that it compiles all scala source files in the src/main/scala directory and subdirectories&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;As the build.xml file is a bit big for a blog post, you can &lt;a href="http://sites.google.com/site/frothandjava/home/code/build.xml?attredirects=0&amp;d=1"&gt;find it here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-5781860735991552035?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/5781860735991552035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=5781860735991552035' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/5781860735991552035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/5781860735991552035'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2009/12/basic-antivyscala-setup.html' title='A Basic Ant+Ivy+Scala Setup'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-3478029001561236360</id><published>2009-12-18T18:49:00.006Z</published><updated>2009-12-19T00:20:31.952Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='YQL'/><title type='text'>Accessing BBC Listen Again data with YQL</title><content type='html'>The BBC have had &lt;a href="http://www.bbc.co.uk/blogs/radiolabs/2008/09/xml_feeds_for_listen_again_con.shtml"&gt;for a while&lt;/a&gt; now XML feeds detailing their "Listen Again" content. For some reason, today I decided it would be fun to access that data from YQL.&lt;br /&gt;&lt;br /&gt;The quickest way is to just use&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;select * from xml where url='http://www.bbc.co.uk/radio/aod/availability/radio4.xml'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;However, I wanted to try out Open Data Tables, and this seemed like a good a time as any. Describing an Open Data Table is surprisingly easy. It's just an XML file, with some metadata about the table and then some binding information that tells YQL where to get the repeating data from.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;&amp;lt;table xmlns="http://query.yahooapis.com/v1/schema/table.xsd"&amp;gt;&lt;br /&gt;  &amp;lt;meta&amp;gt;&lt;br /&gt;    &amp;lt;author&amp;gt;Scot McSweeney-Roberts&amp;lt;/author&amp;gt;&lt;br /&gt;    &amp;lt;documentationURL&amp;gt;http://froth-and-java.blogspot.com/accessing-bbc-listen-again-data-with-yql&amp;lt;/documentationURL&amp;gt;&lt;br /&gt;    &amp;lt;sampleQuery&amp;gt;select entry from {table} where station="radio4" and entry.parents.parent.pid="b006qfvv"&amp;lt;/sampleQuery&amp;gt;&lt;br /&gt;  &amp;lt;/meta&amp;gt;&lt;br /&gt;  &amp;lt;bindings&amp;gt;&lt;br /&gt;   &amp;lt;select itemPath="schedule.entry" produces="XML"&amp;gt;&lt;br /&gt; &amp;lt;urls&amp;gt;&lt;br /&gt;         &amp;lt;url env="all"&amp;gt;http://www.bbc.co.uk/radio/aod/availability/{station}.xml&amp;lt;/url&amp;gt;&lt;br /&gt; &amp;lt;/urls&amp;gt;&lt;br /&gt; &amp;lt;inputs&amp;gt;&lt;br /&gt;  &amp;lt;key id="station" type="xs:string" paramType="path" default="radio4" /&amp;gt;&lt;br /&gt; &amp;lt;/inputs&amp;gt; &lt;br /&gt;    &amp;lt;/select&amp;gt;&lt;br /&gt;  &amp;lt;/bindings&amp;gt;&lt;br /&gt;&amp;lt;/table&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You'll have noticed the "station" key - the BBC has a separate feed for each service, so Radio 1's feed is at radio1.xml, Radio 4's is at radio4.xml, Radio Scotland is at radioscotland.xml, etc. By using a key and inserting its value into the select URL I can use a single Open Data Table definition and access whichever feed I want. The reason why I called it station and not service is that service is a child element of each entry element, so to keep things simple I called the key "station".&lt;br /&gt;&lt;br /&gt;One reason for using an Open Data Table is that makes it slightly easier to query - for example, a query to select all &lt;a href="http://www.bbc.co.uk/programmes/b006qfvv"&gt;Shipping Forecasts&lt;/a&gt; on Radio 4 without using an Open Data Table is&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;select * from xml where url="http://www.bbc.co.uk/radio/aod/availability/radio4.xml" and itemPath="schedule.entry" and parents.parent.pid="b006qfvv"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With an Open Data Table, it's&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;USE "http://sites.google.com/site/frothandjava/home/code/bbc_aod_open_table.xml"AS aod;&lt;br /&gt;SELECT * FROM aod where station="radio4" and parents.parent.pid="b006qfvv"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(It's not really much of a difference though - I think table definitions come into their own when you use them to insert data in to a web service)&lt;br /&gt;&lt;br /&gt;One of the more useful elements in the feed are the "mediaselector" links. A mediaselector link is a link to yet another XML file, but this file contains links to the available media for a particular programme. Some of the links aren't particularly useful, as they're internal iPlayer links, but some are useful as they're the links to WMA and Real Audio streams (though the BBC are dropping support for Real Audio at some point in the future).&lt;br /&gt;&lt;br /&gt;Again, as it's XML it's easy to access from YQL&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;select * from xml where url='http://www.bbc.co.uk/mediaselector/4/mtis/stream/b00p6w2c'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(note, that query will probably not work after lunchtime on the 19th December, 2009 as that particular episode falls out of it's listen again window)&lt;br /&gt;&lt;br /&gt;However, there is a bit of a problem at the moment for UK users of this data while accessing it through YQL - the BBC are currently sending a slightly different mediaselector file depending on where the request came from. As Yahoo's YQL servers are located outside the UK, we get the "international" version of the file and not the one containing UK data. Not only does this mean that we can't get access to the higher quality UK only versions of the streams, but I've noticed that the international WMA streams don't seem to be working in the UK (but the RA ones do). Apparently, this will be solved "at some point in the new year".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-3478029001561236360?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/3478029001561236360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=3478029001561236360' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/3478029001561236360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/3478029001561236360'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2009/12/accessing-bbc-listen-again-data-with.html' title='Accessing BBC Listen Again data with YQL'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-7526432190216829968</id><published>2009-11-23T18:24:00.011Z</published><updated>2009-11-23T19:47:13.659Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='guice'/><category scheme='http://www.blogger.com/atom/ns#' term='soy'/><title type='text'>Extending Soy Templates</title><content type='html'>One of the more interesting features of Soy templates is that you can extend the templating system. While working with Soy from JavaScript, I found that I needed to do exactly that.&lt;br /&gt;&lt;br /&gt;In order to avoid some confusion as to how you can extend the template system in Scala, even though you will be using the templates from JavaScript, I'll quickly explain how Soy templates work when you're using JavaScript. Essentially, you precompile your .soy file into a .js file using a template compiler (which is written in Java). It's the compiler that you're extending and it's output is what you use in your web app. So you don't directly use the template from JavaScript.&lt;br /&gt;&lt;br /&gt;What I wanted to do was something like this:&lt;br /&gt;&lt;br /&gt;{switch typeof($msgparm)}&lt;br /&gt; {case 'number'}&lt;br /&gt;       &amp;lt;i4&amp;gt;{$msgparm}&amp;lt;/i4&amp;gt;&lt;br /&gt; {case 'string'}&lt;br /&gt;           &amp;lt;string&amp;gt;{$msgparm}&amp;lt;/string&amp;gt;  &lt;br /&gt;{/switch}&lt;br /&gt;&lt;br /&gt;Unfortunatly, there is no typeof function "out of the box" so I needed to write my own in a plugin. As I was only interested in using this function in templates that I'm going to use in JavaScript, I needed to  write a class that implements a single interface - SoyJsSrcFunction. If I wanted to use this function from Java, I'd need to implement SoyToFuFunction instead. There are only 3 methods to implement, 2 of which are one-liners in Scala. In this instance, all three are one liners, but computeForJsSrc could be more complicated, depending on what you're doing.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;@Singleton&lt;br /&gt;class TypeOfFunction @Inject() extends SoyJsSrcFunction {&lt;br /&gt;   def getName = "typeof"&lt;br /&gt; &lt;br /&gt;   def getValidArgsSizes: java.util.Set[Integer] = ImmutableSet.of[Integer](1);&lt;br /&gt;&lt;br /&gt;   def computeForJsSrc(args: java.util.List[JsExpr]): JsExpr = new JsExpr("typeof(" + args.get(0).getText() + ")", Integer.MAX_VALUE)&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://sites.google.com/site/frothandjava/home/code/TypeOf.scala?attredirects=0&amp;d=1"&gt;Scala Source Code&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As you can probably tell, all this does is use JavaScript's typeof operator to implement the functionality I was looking for.&lt;br /&gt;&lt;br /&gt;You might notice the @Singleton and @Inject annotations - Soy uses &lt;a href="http://code.google.com/p/google-guice/"&gt;Google Guice&lt;/a&gt; for dependency injection. This means that we're not done yet - we also need to write a subclass of Guice's AbstractModule so that our extension can be injected into Soy. Fortunately it's trivial and XML-free:&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;class ExtendedFunctionsModule extends AbstractModule {&lt;br /&gt;  def configure() = {&lt;br /&gt;   val soyFunctionsSetBinder = Multibinder.newSetBinder(binder(), classOf[SoyFunction])&lt;br /&gt;   soyFunctionsSetBinder.addBinding().to(classOf[TypeOfFunction])&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://sites.google.com/site/frothandjava/home/code/ExtendedFunctionsModule.scala?attredirects=0&amp;d=1"&gt;Scala Source Code&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To use the extension all I need to do is add my Module class to the template compiler's pluginModules option:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;java -cp typeof.jar:scala-library.jar:SoyToJsSrcCompiler.jar com.google.template.soy.SoyToJsSrcCompiler --pluginModules com.maethorechannen.widgets.ExtendedFunctionsModule --outputPathFormat rpc.js rpc.soy&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-7526432190216829968?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/7526432190216829968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=7526432190216829968' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/7526432190216829968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/7526432190216829968'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2009/11/extending-soy-templates.html' title='Extending Soy Templates'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-3888547013912508904</id><published>2009-11-23T18:00:00.007Z</published><updated>2009-11-23T18:17:11.703Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='yaml'/><category scheme='http://www.blogger.com/atom/ns#' term='soy'/><title type='text'>Consice Java Maps in Scala</title><content type='html'>This post is a follow up to my previous post on using &lt;a href="http://froth-and-java.blogspot.com/2009/11/using-googles-closure-templates-in.html"&gt;Closure Templates in Scala&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;One of the things that bugged me in the Scala example was how verbose it was compared to the Groovy version. So I had an idea - use &lt;a href="http://yaml.org/"&gt;YAML&lt;/a&gt; and the &lt;a href="http://code.google.com/p/snakeyaml/"&gt;snakeyaml&lt;/a&gt; library to generate a Java Map with my data. While it's still a couple lines longer than the Groovy version, it's a lot simpler than the Scala original.&lt;br /&gt;&lt;br /&gt;The biggest change is this:&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;val y = """widget: {&lt;br /&gt;name: Widget Name,&lt;br /&gt;display: {&lt;br /&gt;  width: 240,&lt;br /&gt;  height: 320&lt;br /&gt;}&lt;br /&gt;}"""&lt;br /&gt;&lt;br /&gt;val yaml = new Yaml()&lt;br /&gt;val map = yaml.load(y).asInstanceOf[java.util.Map[String, _]]         &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://sites.google.com/site/frothandjava/home/code/soytest2.scala?attredirects=0&amp;amp;d=1"&gt;&lt;br /&gt;Scala Source Code&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-3888547013912508904?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/3888547013912508904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=3888547013912508904' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/3888547013912508904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/3888547013912508904'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2009/11/consice-java-maps-in-scala.html' title='Consice Java Maps in Scala'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-1684649548393085738</id><published>2009-11-23T15:26:00.013Z</published><updated>2009-11-23T17:05:55.808Z</updated><title type='text'>Using Google's Closure Templates in Scala and Groovy</title><content type='html'>Google recently released it's &lt;a href="http://code.google.com/closure/"&gt;Closure Tools&lt;/a&gt; - which is made up of a JavaScript compiler, a JavaScript framework and a templating system which can be used from both Java and JavaScript. I'm guessing from the package names that Closure Templates are actually called Soy templates internally at Google, and that's what I'm going to call them for the rest of this post.&lt;br /&gt;&lt;br /&gt;I'm not going to go into the syntax of Soy templates - if you've ever used a templating system like FreeMarker or Django Templates then you shouldn't have any trouble using Soy templates (though you should be aware that Soy eats white space, so your output might not be what you expect if you don't use special character commands to put whitespace into the output).&lt;br /&gt;&lt;br /&gt;Here's an example template (that I saved as "&lt;a href="http://sites.google.com/site/frothandjava/home/code/widget.soy?attredirects=0&amp;amp;d=1"&gt;widget.soy&lt;/a&gt;"):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;{namespace com.maethorechannen.widgets}&lt;br /&gt;&lt;br /&gt;/** Widget template&lt;br /&gt;* @param widget Widget Data&lt;br /&gt;*/&lt;br /&gt;{template .widget}&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;{\n}&lt;br /&gt;&amp;lt;widget&amp;gt;{\n}&lt;br /&gt;{\t}&amp;lt;widgetname&amp;gt;{$widget.name}&amp;lt;/widgetname&amp;gt;{\n}&lt;br /&gt;{\t}&amp;lt;width&amp;gt;{$widget.display.width}&amp;lt;/width&amp;gt;{\n}&lt;br /&gt;{\t}&amp;lt;height&amp;gt;{$widget.display.height}&amp;lt;/height&amp;gt;{\n}&lt;br /&gt;&amp;lt;/widget&amp;gt;&lt;br /&gt;{/template}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Using the templates from Scala:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;At a minimum, you'll need the following imports:&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;import com.google.template.soy.SoyFileSet&lt;br /&gt;import com.google.template.soy.data.SoyMapData&lt;br /&gt;import com.google.template.soy.tofu.SoyTofu&lt;br /&gt;import java.io.File&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To pass your data to the ToFu rendering engine, you'll need to have your data in either a SoyMapData object or in a plain old Java Map object. As I wanted to use Scala's sugar for quickly building up a Map, I needed to write up an implicit def from Scala's Map to a SoyMapData (quick aside - the sort of thing that stops me from loving Scala is having to do something like this - the impedence mismatch between Java collections and Scala collections is still too big). This function isn't complete, but it will convert the values I was using:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;implicit def mapToSoy(m: Map[String, _]): SoyMapData = {&lt;br /&gt;val sm = new SoyMapData()&lt;br /&gt;m.keys.foreach {k =&gt;&lt;br /&gt;val v: Any = m(k)&lt;br /&gt;v match {&lt;br /&gt;   case s: String =&gt; sm.put(k,s)&lt;br /&gt;   case mm: Map[String, _] =&gt; sm.put(k, mapToSoy(mm))&lt;br /&gt;   case i: Int =&gt; sm.put(k, i)&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;return sm&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here's the Map I'm passing in:&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;val map = Map[String, Any](&lt;br /&gt;"widget" -&gt; Map[String, Any](&lt;br /&gt;"name" -&gt; "Scala Test",&lt;br /&gt;"display" -&gt; Map[String, Any](&lt;br /&gt;    "width"-&gt; 240,&lt;br /&gt;    "height" -&gt; 320)))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To actually use the template, I need to load the template into a SoyFileSet, and then compile the template to a rendering object&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;val sfs = (new SoyFileSet.Builder()).add(new File("widget.soy")).build();&lt;br /&gt;val tofu = sfs.compileToJavaObj()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Finally, I render the template with my data&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;println(tofu.render("com.maethorechannen.widgets.widget", map, null));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Which renders the following:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;widget&amp;gt;&lt;br /&gt;     &amp;lt;widgetname&amp;gt;Scala Test&amp;lt;/widgetname&amp;gt;&lt;br /&gt;     &amp;lt;width&amp;gt;240&amp;lt;/width&amp;gt;&lt;br /&gt;     &amp;lt;height&amp;gt;320&amp;lt;/height&amp;gt;&lt;br /&gt;&amp;lt;/widget&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://sites.google.com/site/frothandjava/home/code/soytest.scala?attredirects=0&amp;amp;d=1"&gt;Scala Source Code&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Using the templates from Groovy:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Using Soy from Groovy is almost identical to using Soy from Scala, but without the need for the implicit def (as Groovy Map sugar returns a Java Map).&lt;br /&gt;&lt;pre name="code" class="groovy"&gt;&lt;br /&gt;import com.google.template.soy.SoyFileSet&lt;br /&gt;import com.google.template.soy.data.SoyMapData&lt;br /&gt;import com.google.template.soy.tofu.SoyTofu&lt;br /&gt;&lt;br /&gt;def map = [widget: [&lt;br /&gt;name: "Widget Name",&lt;br /&gt;display: [&lt;br /&gt;width: 240,&lt;br /&gt;height: 320&lt;br /&gt;]&lt;br /&gt;]]&lt;br /&gt;&lt;br /&gt;def sfs = (new SoyFileSet.Builder()).add(new File("widget.soy")).build();&lt;br /&gt;def tofu = sfs.compileToJavaObj()&lt;br /&gt;println(tofu.render("com.maethorechannen.widgets.widget", map, null));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://sites.google.com/site/frothandjava/home/code/soytest.groovy?attredirects=0&amp;amp;d=1"&gt;Groovy Source Code&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-1684649548393085738?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/1684649548393085738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=1684649548393085738' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/1684649548393085738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/1684649548393085738'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2009/11/using-googles-closure-templates-in.html' title='Using Google&apos;s Closure Templates in Scala and Groovy'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-3655711950051863118</id><published>2009-07-15T15:27:00.005Z</published><updated>2009-07-15T16:14:41.836Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='YQL'/><title type='text'>Musical Fun With YQL</title><content type='html'>&lt;a href="http://www.vernianprocess.com/"&gt;Vernian Process&lt;/a&gt; have released a large amount of their back catalog available for free download from &lt;a href="http://www.last.fm/music/Vernian+Process"&gt;last.fm&lt;/a&gt; (63 mp3 files worth)&lt;sup&gt;1&lt;/sup&gt;. As someone who never says no to free dark ambient, I thought I would quickly screen scrape the free download urls from the 6 month chart page and feed them into wget instead of manually downloading them&lt;sup&gt;2&lt;/sup&gt;. &lt;br /&gt;&lt;br /&gt;For the screen scraping, I turned to &lt;a href="http://developer.yahoo.com/yql/"&gt;Yahoo's YQL service&lt;/a&gt;. In effect, YQL makes the web "programmable" with a SQL-like language. One of YQL's features is that it can use any webpage as a data source (it also supports various web APIs, like flickr's, but all I need for this is it's html ability). Here's the YQL query:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;select * from html &lt;br /&gt;where url="http://www.last.fm/music/Vernian+Process/+charts?rangetype=6month&amp;subtype=tracks"&lt;br /&gt;and xpath="//a[starts-with(@href, 'http://freedownloads.last.fm')]"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That will return all the free download anchors contained on the page.&lt;br /&gt;&lt;br /&gt;It was then a single command to download all the tracks (thanks to curl and wget)&lt;br /&gt;&lt;code&gt;&lt;br /&gt;curl "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22http%3A%2F%2Fwww.last.fm%2Fmusic%2FVernian%2BProcess%2F%2Bcharts%3Frangetype%3D6month%26subtype%3Dtracks%22%20and%20xpath%3D%22%2F%2Fa%5Bstarts-with(%40href%2C%20'http%3A%2F%2Ffreedownloads.last.fm')%5D%22&amp;format=xml" | wget --force-html -i -&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;small&gt;1. They've done it because they've &lt;strike&gt;improved&lt;/strike&gt; changed styles and have gone more Industrial.&lt;/small&gt;&lt;br /&gt;&lt;br /&gt;&lt;small&gt;2. In case you're wondering, I used the Chart and not the Free Tracks page as the Free Tracks page only had 4 of the freely downloadable tracks.&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-3655711950051863118?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/3655711950051863118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=3655711950051863118' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/3655711950051863118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/3655711950051863118'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2009/07/musical-fun-with-yql.html' title='Musical Fun With YQL'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-2964382756060248812</id><published>2009-06-29T14:28:00.004Z</published><updated>2009-06-29T14:45:42.081Z</updated><title type='text'>Sieve of Eratosthenes</title><content type='html'>This is my response to the Scala slide in the "&lt;a href="http://fupeg.blogspot.com/2009/06/javaone-talk-performance-comparisons-of.html"&gt;JavaOne Talk: Performance Comparisons of Dynamic Languages on the Java Virtual Machine&lt;/a&gt;" presentation. In particular, the Scala example seemed quite verbose and "unscalalike", so I thought I would see what I could quickly knock up. It's the Sieve of Eratosthenes (sort of - it's recursive and it doesn't bother with Step 5 of the algorithm on the &lt;a href="http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes"&gt;Wikipedia page&lt;/a&gt;, so it does more work than is needed).&lt;br /&gt;&lt;br /&gt;It's quick and dirty and could stand to be improved - my main motivation was to show that it could be done quickly and in a lot fewer lines in Scala than was shown on the presentation slide so it's not the greatest example of code ever written. I've put it up here because blogger's commenting system nukes source code layout.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;def primes(n: Int): List[Int] = {&lt;br /&gt;        def nomults(s: Int, xs: Seq[Int]): List[Int] = (for (x &lt;- xs if x % s != 0) yield x).toList&lt;br /&gt;        def sieve(xs: List[Int]): List[Int] = {&lt;br /&gt;                if (xs.isEmpty) xs&lt;br /&gt;                else {&lt;br /&gt;                        val p = xs.first&lt;br /&gt;                        val nxs = nomults(p, xs drop 1)&lt;br /&gt;                        p :: sieve(nxs)&lt;br /&gt;                }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        val odds = nomults(2, 2 to n)&lt;br /&gt;        2 :: sieve(odds)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;println( primes(100) )&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-2964382756060248812?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/2964382756060248812/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=2964382756060248812' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/2964382756060248812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/2964382756060248812'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2009/06/sieve-of-eratosthenes.html' title='Sieve of Eratosthenes'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-6354038062186940804</id><published>2009-04-20T14:08:00.002Z</published><updated>2009-04-20T14:11:33.501Z</updated><title type='text'>Oracle To Buy Sun</title><content type='html'>&lt;a href="http://www.nytimes.com/2009/04/21/technology/companies/21sun.html"&gt;Article at the NY Times&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.sun.com/third-party/global/oracle/index.jsp"&gt;Sun's Press Release&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;My first impression is that this should be good for Java, less good for MySQL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-6354038062186940804?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/6354038062186940804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=6354038062186940804' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/6354038062186940804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/6354038062186940804'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2009/04/oracle-to-buy-sun.html' title='Oracle To Buy Sun'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-685896966894537020</id><published>2009-04-08T21:00:00.007Z</published><updated>2009-04-08T21:15:17.922Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='appengine'/><title type='text'>Scala on the Google AppEngine</title><content type='html'>&lt;p&gt;Good News - It was fairly trivial to use Scala with the new Java support in AppEngine.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I used a text editor and ant instead of mucking about with Eclipse. It was pretty much a case of following the docs for Java, just using Scala instead of Java for writing the servlet. The main difference between using Java and Scala is that you need to merge some Scala specific items into the build.xml file. Here's my build.xml &lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;project&amp;gt;&lt;br /&gt;  &amp;lt;property name="scala.home" location="../scala-2.7.3.final" /&amp;gt;&lt;br /&gt;  &amp;lt;property name="sdk.dir" location="../appengine-java-sdk-1.2.0" /&amp;gt;&lt;br /&gt;  &amp;lt;property name="sources.dir" value="${base.dir}/src" /&amp;gt;&lt;br /&gt;  &amp;lt;property name="build.dir" value="${base.dir}/build"/&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;import file="${sdk.dir}/config/user/ant-macros.xml" /&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;path id="project.classpath"&amp;gt;&lt;br /&gt;    &amp;lt;pathelement path="war/WEB-INF/classes" /&amp;gt;&lt;br /&gt;    &amp;lt;fileset dir="war/WEB-INF/lib"&amp;gt;&lt;br /&gt;      &amp;lt;include name="**/*.jar" /&amp;gt;&lt;br /&gt;    &amp;lt;/fileset&amp;gt;&lt;br /&gt;    &amp;lt;fileset dir="${sdk.dir}/lib"&amp;gt;&lt;br /&gt;      &amp;lt;include name="shared/**/*.jar" /&amp;gt;&lt;br /&gt;    &amp;lt;/fileset&amp;gt;&lt;br /&gt;  &amp;lt;/path&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;target name="init"&amp;gt;&lt;br /&gt;    &amp;lt;property&lt;br /&gt;      name="scala-library.jar"&lt;br /&gt;      value="${scala.home}/lib/scala-library.jar"&lt;br /&gt;       /&amp;gt;&lt;br /&gt;    &amp;lt;path id="build.classpath"&amp;gt;&lt;br /&gt;      &amp;lt;pathelement location="${scala-library.jar}"   /&amp;gt;&lt;br /&gt; &lt;br /&gt;      &amp;lt;pathelement location="${build.dir}"   /&amp;gt;&lt;br /&gt;    &amp;lt;/path&amp;gt;&lt;br /&gt;    &amp;lt;taskdef resource="scala/tools/ant/antlib.xml"&amp;gt;&lt;br /&gt;      &amp;lt;classpath&amp;gt;&lt;br /&gt;        &amp;lt;pathelement location="${scala.home}/lib/scala-compiler.jar"   /&amp;gt;&lt;br /&gt;        &amp;lt;pathelement location="${scala-library.jar}"   /&amp;gt;&lt;br /&gt;      &amp;lt;/classpath&amp;gt;&lt;br /&gt;    &amp;lt;/taskdef&amp;gt;&lt;br /&gt;  &amp;lt;/target&amp;gt;&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;    &amp;lt;target name="copyscala"&lt;br /&gt;      description="Copies the App Engine JARs to the WAR."&amp;gt;&lt;br /&gt;    &amp;lt;copy&lt;br /&gt;        todir="war/WEB-INF/lib"&lt;br /&gt;        flatten="true"&amp;gt;&lt;br /&gt;      &amp;lt;fileset dir="${scala.home}/lib"&amp;gt;&lt;br /&gt;        &amp;lt;include name="**/scala-library.jar" /&amp;gt;&lt;br /&gt;      &amp;lt;/fileset&amp;gt;&lt;br /&gt;    &amp;lt;/copy&amp;gt;&lt;br /&gt;  &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;target name="copyjars"&lt;br /&gt;      description="Copies the Scala JARs to the WAR."&amp;gt;&lt;br /&gt;    &amp;lt;copy&lt;br /&gt;        todir="war/WEB-INF/lib"&lt;br /&gt;        flatten="true"&amp;gt;&lt;br /&gt;      &amp;lt;fileset dir="${sdk.dir}/lib/user"&amp;gt;&lt;br /&gt;        &amp;lt;include name="**/*.jar" /&amp;gt;&lt;br /&gt;      &amp;lt;/fileset&amp;gt;&lt;br /&gt;    &amp;lt;/copy&amp;gt;&lt;br /&gt;  &amp;lt;/target&amp;gt;&lt;br /&gt;  &lt;br /&gt;    &amp;lt;target name="compile" depends="copyscala, copyjars, init"&lt;br /&gt;      description="Compiles Scala source and copies other source files to the WAR."&amp;gt;&lt;br /&gt;    &amp;lt;mkdir dir="war/WEB-INF/classes" /&amp;gt;&lt;br /&gt;    &amp;lt;copy todir="war/WEB-INF/classes"&amp;gt;&lt;br /&gt;      &amp;lt;fileset dir="src"&amp;gt;&lt;br /&gt;        &amp;lt;exclude name="**/*.scala" /&amp;gt;&lt;br /&gt;      &amp;lt;/fileset&amp;gt;&lt;br /&gt;    &amp;lt;/copy&amp;gt;&lt;br /&gt;    &amp;lt;scalac&lt;br /&gt;        srcdir="src"&lt;br /&gt;        destdir="war/WEB-INF/classes"&lt;br /&gt;        classpathref="project.classpath"&lt;br /&gt;         /&amp;gt;&lt;br /&gt;  &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;  &amp;lt;target name="runserver" depends="compile"&lt;br /&gt;      description="Starts the development server."&amp;gt;&lt;br /&gt;    &amp;lt;dev_appserver war="war" /&amp;gt;&lt;br /&gt;  &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-685896966894537020?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/685896966894537020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=685896966894537020' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/685896966894537020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/685896966894537020'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2009/04/scala-on-google-appengine.html' title='Scala on the Google AppEngine'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-1213930298316892794</id><published>2009-04-08T09:21:00.002Z</published><updated>2009-04-08T09:24:11.899Z</updated><title type='text'>Java Coming To Google AppEngine</title><content type='html'>&lt;a href="http://code.google.com/appengine/docs/java/gettingstarted/"&gt;The docs&lt;/a&gt; are up on Google's AppEngine site!&lt;br /&gt;&lt;br /&gt;I've been playing with the python version (though I haven't released anything) - now it's time to look at using Java (and hopefully Scala and Groovy).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-1213930298316892794?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/1213930298316892794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=1213930298316892794' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/1213930298316892794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/1213930298316892794'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2009/04/java-coming-to-google-appengine.html' title='Java Coming To Google AppEngine'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-1796888216291095233</id><published>2009-03-03T23:17:00.008Z</published><updated>2009-03-03T23:36:31.321Z</updated><title type='text'>Starbucks (UK) Vs Linux</title><content type='html'>&lt;p&gt;I can't believe how braindead Starbucks' UK website is. If you're running Linux and trying to register your Starbucks card you'll get this message:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Browser error   &lt;br /&gt;&lt;br /&gt;We're sorry, your browser doesn't support the Starbucks Card registration pages of this website.&lt;br /&gt;&lt;br /&gt;Please update your browser to Internet Explorer version 5.0 or above, or Netscape Navigator version 6.0 or above.&lt;br /&gt;&lt;br /&gt;Thank you.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Here I was thinking Firefox 3 was above Netscape 6.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Of course, if you switch the User Agent to say that you're running Windows, all works well. 1999 called - they want thier browser detection back.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Maybe it has something to do with having headquaters in Seattle.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-1796888216291095233?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/1796888216291095233/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=1796888216291095233' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/1796888216291095233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/1796888216291095233'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2009/03/starbucks-uk-vs-linux.html' title='Starbucks (UK) Vs Linux'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-4344609660692339732</id><published>2008-07-31T12:32:00.013Z</published><updated>2008-08-01T16:31:25.754Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Stupid Scala Trick: Injecting Methods With Spring</title><content type='html'>I'm not sure why I came up with this idea, but it occurred to me that since functions are first class objects in Scala then I should be able to inject them as dependencies using the Spring framework. So I decided to give it a try (using constructor injection to make life simple).&lt;br /&gt;&lt;br /&gt;First, I need a class that will have a method injected -&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;class User(val f: String =&gt; String) {&lt;br /&gt;&lt;br /&gt;def b() = {f("hello")}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So, this class will have a method named f (which takes a String and returns a String) injected into it. It also has a method called b, which will use f.&lt;br /&gt;&lt;br /&gt;Next up, a function that will be injected. &lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;object func1 extends Function1[String, String] {&lt;br /&gt;        def apply(s: String): String = {s.toUpperCase()}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is essentially the same as &lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;def func1(s: String): String = {s.toUpperCase()}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, the Spring bean definition xml (which I'll save in a file called app.xml)&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;beans xmlns="http://www.springframework.org/schema/beans"&lt;br /&gt;       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;       xsi:schemaLocation="http://www.springframework.org/schema/beans&lt;br /&gt;           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;bean id="user" class="User"&amp;gt;&lt;br /&gt;        &amp;lt;constructor-arg&amp;gt;&lt;br /&gt;          &amp;lt;bean class="func1$"/&amp;gt;&lt;br /&gt;        &amp;lt;/constructor-arg&amp;gt;&lt;br /&gt;  &amp;lt;/bean&amp;gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Finally, a small application to fire up spring and test that injection worked&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;import org.springframework.context.support._&lt;br /&gt;&lt;br /&gt;object SpringTest {&lt;br /&gt;&lt;br /&gt;        def main(args: Array[String]) = {&lt;br /&gt;                &lt;br /&gt;                val context  = new ClassPathXmlApplicationContext(Array[String]("app.xml"));&lt;br /&gt;                val user = context.getBean("user").asInstanceOf[User]&lt;br /&gt;                println(user.b())&lt;br /&gt;                println(user.f("world"))&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And here's the output (minus some log4j warnings)&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;HELLO&lt;br /&gt;WORLD&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-4344609660692339732?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/4344609660692339732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=4344609660692339732' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/4344609660692339732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/4344609660692339732'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2008/07/stupid-scala-trick-injecting-methods.html' title='Stupid Scala Trick: Injecting Methods With Spring'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-8320158360617414877</id><published>2008-07-18T16:55:00.006Z</published><updated>2008-08-01T16:29:04.759Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>maven &amp; build-helper</title><content type='html'>I ran into a little issue with maven and the build-helper plugin today.&lt;br /&gt;&lt;br /&gt;The background is as follows - I was part-mavenizing a project (long, boring work related story) and I needed to generate some source code using JAXB (which was a trial in and of itself - we're compiling on Java 1.4 and JAXB hates Java 1.4 - in the end I needed to use antrun to run the 1.0.0 version of xjc) and then have it compile as part of the main compile process. So build-helper to the rescue. The documentation states that you just add the plugin to the build- &lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;...&lt;br /&gt;     &amp;lt;plugin&amp;gt;&lt;br /&gt;        &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;&lt;br /&gt;        &amp;lt;artifactId&amp;gt;build-helper-maven-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;        &amp;lt;version&amp;gt;1.1&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;executions&amp;gt;&lt;br /&gt;          &amp;lt;execution&amp;gt;&lt;br /&gt;            &amp;lt;id&amp;gt;add-source&amp;lt;/id&amp;gt;&lt;br /&gt;            &amp;lt;phase&amp;gt;generate-sources&amp;lt;/phase&amp;gt;&lt;br /&gt;            &amp;lt;goals&amp;gt;&lt;br /&gt;              &amp;lt;goal&amp;gt;add-source&amp;lt;/goal&amp;gt;&lt;br /&gt;            &amp;lt;/goals&amp;gt;&lt;br /&gt;            &amp;lt;configuration&amp;gt;&lt;br /&gt;              &amp;lt;sources&amp;gt;&lt;br /&gt;                &amp;lt;source&amp;gt;some directory&amp;lt;/source&amp;gt;&lt;br /&gt;                ...&lt;br /&gt;              &amp;lt;/sources&amp;gt;&lt;br /&gt;            &amp;lt;/configuration&amp;gt;&lt;br /&gt;          &amp;lt;/execution&amp;gt;&lt;br /&gt;        &amp;lt;/executions&amp;gt;&lt;br /&gt;      &amp;lt;/plugin&amp;gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note the "some directory" for the source. I was trying to place the generated code into /target/generated-code/java, seeing as the generated code was output and output ends up in /target. It wouldn't work. I tried several variations on a theme, but as long as I kept trying to compile source that lived in target, maven would not see it. In the end, I placed the code in {$basedir}/src/generated/java (ie, in src, not target), pointed build-helper to it and it started to work.&lt;br /&gt;&lt;br /&gt;While it works, it does mean I have more work ahead in order to get clean to work as expected.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-8320158360617414877?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/8320158360617414877/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=8320158360617414877' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/8320158360617414877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/8320158360617414877'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2008/07/maven-build-helper.html' title='maven &amp; build-helper'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-567476900232150197</id><published>2008-07-17T19:46:00.008Z</published><updated>2008-08-01T16:36:46.710Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='Processing'/><category scheme='http://www.blogger.com/atom/ns#' term='Swing'/><title type='text'>Processing/Scala Improvement</title><content type='html'>I've come up with an improvement to my Processing/Scala combination. Instead of using appletviewer, I've created an application object that fires up Swing and embeds the PApplet.&lt;br /&gt;&lt;br /&gt;I first turned to the latest preprint of Programming in Scala which has a chapter dedicated to Scala Swing applications and then rapidly ran into issues. First, it doesn't mention that scala.swing isn't in the standard library (at least, not yet), so I had to track down a jar of version 0.3 and then add it to the classpath. Second, the example code in the book still doesn't work (it complains that += is not a member of Seq[Component] on the code that adds items to the main frame). So I gave up on using scala.swing and turned to the &lt;a href="http://scala.sygneca.com/code/hello-swing"&gt;Scala wiki&lt;/a&gt; to see how to drive Swing directly. The result is &lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;import javax.swing._&lt;br /&gt;&lt;br /&gt;object TestRunner extends JFrame( "Test" ) &lt;br /&gt;{    &lt;br /&gt;    def main( args: Array[String] ) = &lt;br /&gt;    {&lt;br /&gt;        setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;        val t = new Test()&lt;br /&gt;        add( t );&lt;br /&gt;        t.init()&lt;br /&gt;        pack()&lt;br /&gt;        setVisible( true );&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-567476900232150197?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/567476900232150197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=567476900232150197' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/567476900232150197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/567476900232150197'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2008/07/processingscala-improvement.html' title='Processing/Scala Improvement'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-7341423693284344628</id><published>2008-07-16T21:24:00.007Z</published><updated>2008-07-16T21:40:34.742Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='Processing'/><title type='text'>Combining Scala With Processing</title><content type='html'>I recently bought a copy of &lt;a href="http://benfry.com/"&gt;Ben Fry&lt;/a&gt;'s "&lt;a href="http://oreilly.com/catalog/9780596514556/"&gt;Visualizing Data&lt;/a&gt;", which explores data visualization (unsurprising, considering the title) using Processing. So, I got the idea of combining Processing with Scala, in order to get Scala's more advanced language features with Processing's easy to use graphics.&lt;br /&gt;&lt;br /&gt;The key to combining the two is page 249 of Visualizing Data, which describes how to use Java instead of Processing's own Java like language. It was fairly trivial to convert the Java to Scala -&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;import processing.core._&lt;br /&gt;&lt;br /&gt;class Test extends PApplet {&lt;br /&gt; val bg = 0xFFEECC00&lt;br /&gt; &lt;br /&gt; override def setup = {&lt;br /&gt; &lt;br /&gt;  size(400,400)&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; override def draw = {&lt;br /&gt; &lt;br /&gt;  background(bg)&lt;br /&gt;  line(mouseX, mouseY, width/2.0f, height/2.0f)&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;When you compile the code with scalac, you'll need to include Processing's core.jar on the classpath.&lt;br /&gt;&lt;br /&gt;As you can probably tell from the processing base class, you end up with a good old fashioned Java applet. As it's been over 10 years since the last time I played with applets, it took a few minutes to get it to work. To cut a long story short, I did the following:&lt;br /&gt;&lt;br /&gt;1) jar Test.class&lt;br /&gt;2) copy core.jar from Processing into the current directory&lt;br /&gt;3) copy scala-library.jar from Scala into the current directory&lt;br /&gt;4) create a HTML file with the following:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;APPLET CODE=Test.class WIDTH=500 HEIGHT=500 ARCHIVE="Test.jar, core.jar, scala-library.jar"&amp;gt;&lt;br /&gt;&amp;lt;/APPLET&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;5) finally, start appletviewer:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;appletviewer test.html&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I'm certain there's a better way to package it all up, but like I said, it's been years since I played with applets.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-7341423693284344628?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/7341423693284344628/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=7341423693284344628' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/7341423693284344628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/7341423693284344628'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2008/07/combining-scala-with-processing.html' title='Combining Scala With Processing'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-5121243168325032897</id><published>2008-02-22T16:24:00.004Z</published><updated>2009-05-24T17:18:05.181Z</updated><title type='text'>A TCP/IP Echo Server in Scala</title><content type='html'>I thought I'd see what low level (for Java) network programming would be like in Scala and at the same time get used to using Scala's Actors for concurrency.&lt;br /&gt;&lt;br /&gt;Starting with the basics, I've implemented an Echo server (which seems to be the "hello, world" of network programming). It's quite simple - wait for a connection, read a single line of text, send the text straight back and close the connection. Here's what I've come up with (I'm certain it could be made more concise, but then in Scala "there's always a more consise way to do it")&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;import java.net._&lt;br /&gt;import java.io._&lt;br /&gt;&lt;br /&gt;import scala.actors._&lt;br /&gt;import scala.actors.Actor._&lt;br /&gt;&lt;br /&gt;case class Echo(socket: Socket)&lt;br /&gt;&lt;br /&gt;object Service extends Actor {&lt;br /&gt;&lt;br /&gt; implicit def inputStreamWrapper(in: InputStream) =&lt;br /&gt;  new BufferedReader(new InputStreamReader(in))&lt;br /&gt;&lt;br /&gt; implicit def outputStreamWrapper(out: OutputStream) =&lt;br /&gt;  new PrintWriter(new OutputStreamWriter(out))&lt;br /&gt;&lt;br /&gt; def echo(in: BufferedReader, out: PrintWriter) {&lt;br /&gt;   val line = in.readLine()&lt;br /&gt;   out.println(line)&lt;br /&gt;   out.flush()&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; def act() {&lt;br /&gt;  loop {&lt;br /&gt;   receive {&lt;br /&gt;    case Echo(socket) =&gt;&lt;br /&gt;     actor {&lt;br /&gt;      echo(socket.getInputStream(), socket.getOutputStream())&lt;br /&gt;      socket.close&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object EchoServer {&lt;br /&gt; Service.start&lt;br /&gt;&lt;br /&gt; val serverSocket = new ServerSocket(12111)&lt;br /&gt; &lt;br /&gt; def start() {&lt;br /&gt;  while(true) {&lt;br /&gt;   println("about to block")&lt;br /&gt;      val clientSocket = serverSocket.accept()&lt;br /&gt;   Service ! Echo(clientSocket)&lt;br /&gt;   println("back from actor")&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;EchoServer.start&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-5121243168325032897?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/5121243168325032897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=5121243168325032897' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/5121243168325032897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/5121243168325032897'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2008/02/tcpip-echo-server-in-scala.html' title='A TCP/IP Echo Server in Scala'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-4002293636691400593</id><published>2008-02-12T13:55:00.000Z</published><updated>2008-02-12T14:16:52.851Z</updated><title type='text'>New Toy - Asus Eee PC</title><content type='html'>Sorry for the lull in my Scala vs Groovy posts - I bought a new toy a couple weeks back and it's been sucking up my free time. I've got three posts mostly finished and they should be out soon. The funny thing is that I bought the thing to become more productive.&lt;br /&gt;&lt;br /&gt;As for the device itself - it's fantastic. I ended up buying the 2G Surf model (512 meg of RAM, 2 gig SSD), basically because it was available and I wanted one right then and there (unsurprisingly the 4Gs were few and far between). While I'd recommend the 4G version to anyone buying one (as there's at least a chance that you can upgrade the memory in the 4G, it's got a better battery and isn't as underclocked), the 2G is fine for what I wanted (as I was going to install Xubuntu to a SDHC card no matter what model I was going to get).&lt;br /&gt;&lt;br /&gt;Xubuntu installed fine (though a very small amount of extra work was needed to get WiFi and sound working), Java's running fine (though I've yet to test Scala and Groovy), mplayer's runs (though I think it'll run better with the underclocking switched off, yet another item on the to do list). Firefox runs and Google Reader's offline mode makes for a great way to pass the time on the tube to work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-4002293636691400593?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/4002293636691400593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=4002293636691400593' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/4002293636691400593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/4002293636691400593'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2008/02/new-toy-asus-eee-pc.html' title='New Toy - Asus Eee PC'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-5129837045937869003</id><published>2008-01-15T19:59:00.000Z</published><updated>2008-01-15T19:45:04.593Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ScalaVsGroovy'/><title type='text'>Scala vs Groovy: Lists (Part 1)</title><content type='html'>Before looking at the syntactic sugar Scala and Groovy have for strings, I'm going to have a quick look at how they handle lists. Collection classes are fairly important in both languages, so I'll have a more in depth look later.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Lists in Groovy&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In Groovy, Lists come straight out of the Java collection classes but with added syntactic sugar.&lt;br /&gt;&lt;br /&gt;The easiest way to create a list is:&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0); font-family: Courier,monospace;"&gt;&lt;br /&gt;def myList = [1, 2, 3]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;An empty list can be created by using []&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0); font-family: Courier,monospace;"&gt;&lt;br /&gt;def myEmptyList = []&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;As Groovy's List is a java.util.List, you can use all the methods on the java.util.List interface. An example would be add:&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0); font-family: Courier,monospace;"&gt;&lt;br /&gt;myList.add(4)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;which will add 4 to the end of the list.&lt;br /&gt;&lt;br /&gt;You can add an element (or even the contents of another list) to the end of a list with the += operator&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0); font-family: Courier,monospace;"&gt;&lt;br /&gt;myList += 5&lt;br /&gt;myList += [6,7]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;will result in myList containing [1, 2, 3, 4, 5, 6, 7]. The + operator works much as you would expect:&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0); font-family: Courier,monospace;"&gt;&lt;br /&gt;def anotherList = [1,2,3] + [4,5,6]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;results in [1, 2, 3, 4, 5, 6]. One interesting thing to note is that:&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0); font-family: Courier,monospace;"&gt;&lt;br /&gt;def yetAnotherList = [1, 2, 3]&lt;br /&gt;yetAnotherList.add([4, 5, 6])&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;results in [1, 2, 3, [4, 5, 6]] and not [1, 2, 3, 4, 5, 6]&lt;br /&gt;&lt;br /&gt;To access a particular element of a list, you use square brackets:&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0); font-family: Courier,monospace;"&gt;&lt;br /&gt;println(myList[0])&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;will print the number 1.&lt;br /&gt;&lt;br /&gt;You can an also slice a list using a range:&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0); font-family: Courier,monospace;"&gt;&lt;br /&gt;def subList = myList[2..4]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;results in subList containing [3,4,5].&lt;br /&gt;&lt;br /&gt;If you create two different lists and they both contain the same elements, == works as you expect:&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0); font-family: Courier,monospace;"&gt;&lt;br /&gt;def list1 = [1,2,3]&lt;br /&gt;def list2 = [1,2,3]&lt;br /&gt;&lt;br /&gt;list1 == list2&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;returns true.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As you have seen, lists in Groovy are mutable - you can add, remove and change the elements to your hearts content. Scala is different.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Lists (and Arrays) in Scala&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Unlike Groovy, Scala has both Lists and Arrays. The main difference between them (at least for the purposes of this post) is mutability - Arrays are mutable, Lists are not.&lt;br /&gt;&lt;br /&gt;Scala doesn't have a special syntax for either lists or arrays (though it does use a language feature so that you don't need to use new). So, to create a list (or an array) in Scala, you can use:&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255);font-family: Courier,monospace;"&gt;&lt;br /&gt;val myList = List(1, 2, 3)&lt;br /&gt;val myArray = Array(4, 5, 6)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;As arrays are mutable, you may wish to create an empty array and populate later:&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255);font-family: Courier,monospace;"&gt;&lt;br /&gt;val myEmptyArray = new Array[Int](3)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;which creates an array of size 3 that contains integers. There are a couple of ways to set the values in this array:&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255);font-family: Courier,monospace;"&gt;&lt;br /&gt;myEmptyArray.update(0, 10)&lt;br /&gt;myEmptyArray(1) = 11&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;myEmptyArray will now contain [10, 11, 0] - when the array was created, each value was initialized to the default "empty" value for that type, which in this case is 0 for Ints.&lt;br /&gt;&lt;br /&gt;With lists in Scala, you can't add elements to the list  (or delete or change elements either), in the same way that you can't add, delete or change characters in a string. But just like with strings, you can still perform operations on lists, it's just that you get an entirely new list as a result of the operation. We'll start by looking at adding elements:&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255);font-family: Courier,monospace;"&gt;&lt;br /&gt;var aList = List(1, 2, 3)&lt;br /&gt;aList = 0 :: aList&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;results in aList containing [0, 1, 2, 3]. You'll note how I used var and not val - val would not have worked as we are creating a new list and changing aList to reference the new list. You'll also notice the :: "operator"&lt;sup&gt;1&lt;/sup&gt; , which is called "cons". Cons creates a new list with the the object on the left hand side of cons as the first element of the new list and the elements of the list on the right hand side making up the rest of the new list.&lt;br /&gt;&lt;br /&gt;Scala has a special "shorthand" for creating an empty list, "Nil"&lt;br /&gt;&lt;br /&gt;You can use Nil to build up lists. For example:&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255);font-family: Courier,monospace;"&gt;&lt;br /&gt;var bList = 0 :: 1 :: 2 :: 3 :: Nil&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;results in bList containing [0, 1, 2, 3]. One interesting thing to note is that&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255);font-family: Courier,monospace;"&gt;&lt;br /&gt;aList == bList&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;will return true, as both lists contain [0, 1, 2, 3].&lt;br /&gt;&lt;br /&gt;There is also a ::: operator, which will combine 2 lists into a single new list&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255);font-family: Courier,monospace;"&gt;&lt;br /&gt;var cList = List(1, 2, 3)&lt;br /&gt;var dList = 4 :: 5 :: 6 :: Nil&lt;br /&gt;var longList = cList ::: dList&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;will result in a list containing [1, 2, 3, 4, 5, 6]&lt;br /&gt;&lt;br /&gt;If we wanted to slice longList and get a sub list of elements:&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255);font-family: Courier,monospace;"&gt;&lt;br /&gt;var sliced = longList.slice(2, 4)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;results in a list contain [3, 4] and not [3, 4, 5] that the Groovy slice above (using (2..4)) returns.&lt;br /&gt;&lt;br /&gt;Conclusion&lt;br /&gt;&lt;br /&gt;I've left a lot (and I mean a lot) of info about Lists in both Groovy and Scala out in this post. The reason why I'm introducing them now is that both languages give Strings list-like syntactic sugar. As I've barely scratched the surface of Lists (let alone the rest of the collection classes) I will get back to them in greater detail later.&lt;br /&gt;&lt;br /&gt;Footnotes:&lt;br /&gt;&lt;sup&gt;1&lt;/sup&gt;Why operator is in double quotes will be the subject of a future comparison of operators and operator overloading&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-5129837045937869003?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/5129837045937869003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=5129837045937869003' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/5129837045937869003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/5129837045937869003'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2008/01/scala-vs-groovy-lists-part-1.html' title='Scala vs Groovy: Lists (Part 1)'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-7331728384859950806</id><published>2008-01-11T22:54:00.000Z</published><updated>2008-01-12T00:39:34.838Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ScalaVsGroovy'/><title type='text'>Scala vs Groovy: Strings (Part 1)</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Single Line Strings&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I'm going to start the comparison of string handling in Scala and Groovy with a look at single line strings - the sort of string found in Java.&lt;br /&gt;&lt;code style="color: rgb(255, 0, 0);font-family: Courier,monospace;"&gt;&lt;br /&gt;String s = "Hello, Java!";&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Scala's basic string handling is just like Java (but with Scala's syntax and type inference):&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255);font-family: Courier,monospace;"&gt;&lt;br /&gt;var s: String = "Hello, Scala!"&lt;br /&gt;var s2 = "Hello Type Inferer!"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Groovy has both Java-esque strings that are enclosed in double quotes as well as strings that are enclosed in single quotes.&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0);font-family: Courier,monospace;"&gt;&lt;br /&gt;def s = "Groovy's double quoted String"&lt;br /&gt;def s2 = 'A "single quoted" Groovy String'&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Groovy also has a third syntax for strings, using forward slashes&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0);font-family: Courier,monospace;"&gt;&lt;br /&gt;def s3 = /Slashy String/&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;All of the above are java.lang.String - however in Groovy, double quoted strings can become "GStrings". GStrings contain an expression contained in a ${ } block (something that will be familiar to anyone who has written JSP pages). For example:&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0);font-family: Courier,monospace;"&gt;&lt;br /&gt;def x = 4&lt;br /&gt;def gs = "the value of x is: ${x}"&lt;br /&gt;println gs&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;will print:&lt;br /&gt;&lt;br /&gt;the value of x is: 4&lt;br /&gt;&lt;br /&gt;Double quoted strings only get promoted to GStrings when they contain ${&lt;span style="font-style:italic;"&gt;some expression&lt;/span&gt;}. If they don't, then they're plain old java.lang.String strings.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;Multi-line Strings&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Both Scala and Groovy support multi-line strings. Both use a similar syntax - the triple quote:&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255);font-family: Courier,monospace;"&gt;&lt;br /&gt;var ms = """This is&lt;br /&gt;a Scala multi-line &lt;br /&gt;String"""&lt;br /&gt;&lt;/code&gt;&lt;code style="color: rgb(51, 204, 0);font-family: Courier,monospace;"&gt;&lt;br /&gt;def ms = """This is&lt;br /&gt;a Groovy ${lines}&lt;br /&gt;String""" &lt;br /&gt;&lt;/code&gt;&lt;br /&gt;You'll notice that in Groovy, multi-line strings get promoted to GStrings as well.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Character&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;While looking at Strings, we should also look at Character. In a manner not dissimilar to Java, a Character in Scala is defined by a single character in single quotes:&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255);font-family: Courier,monospace;"&gt;&lt;br /&gt;val c = 'd'&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;In Groovy, Characters can't be created directly. This:&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0);font-family: Courier,monospace;"&gt;&lt;br /&gt;def c = 'd'&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;creates a String, not a Character. Instead, you need to write this:&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0);font-family: Courier,monospace;"&gt;&lt;br /&gt;def c = 'd' as char&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;which will create a String and then use some dynamic magic to convert it to a Character&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;End of Part 1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;That's it for the basic comparison. However, both languages have syntactic sugar that gets layered onto strings, but that really should be a post on it's own.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-7331728384859950806?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/7331728384859950806/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=7331728384859950806' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/7331728384859950806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/7331728384859950806'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2008/01/scala-vs-groovy-strings-part-1.html' title='Scala vs Groovy: Strings (Part 1)'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-4747080799788586626</id><published>2008-01-11T12:39:00.000Z</published><updated>2008-01-11T22:47:21.506Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ScalaVsGroovy'/><title type='text'>Scala vs Groovy: Variable Definintion &amp; Optional Semicolons</title><content type='html'>Because Groovy is a dynamic language, when you declare a variable you don't have to specify a type for the variable because the run time will work out what the type is for you. To declare such an untyped variable, you use:&lt;br /&gt;&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0); font-family: Courier,monospace;"&gt;def s = "Hello, World!"&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;However, if you feel like declaring the type, you can:&lt;br /&gt;&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0); font-family: Courier,monospace;"&gt;String s = "Hello, World!"&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;One thing to note is that declaring the type might actually slow your code down (at least with the version of Groovy current at the time of writing).&lt;br /&gt;&lt;br /&gt;Unlike Groovy, Scala is a statically typed language, just like Java. Unlike Java, it can often work out what the type is supposed to be at compile time, and when it can you don't have to explicitly declare the type. In Scala, you use either the "var" keyword or the "val" keyword when you define a variable (I'll discuss the difference between var and val below)&lt;br /&gt;&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255); font-family: Courier,monospace;"&gt;var s = "Hello, World!"&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255); font-family: Courier,monospace;"&gt;val t = "Hello, World!"&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Just like in Groovy, you can also declare the variables type. Unlike Groovy, the way you do this does not look like Java:&lt;br /&gt;&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255); font-family: Courier,monospace;"&gt;var s: String = "Hello World"&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;You'll notice that you still need the var (or val) keyword and that the type comes after the variable name.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Vars and Vals&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What's the difference between var and val? Vars are mutable, vals are not. What this means is that you can change the value of var, but the value of a val is constant. Effectively:&lt;br /&gt;&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255); font-family: Courier,monospace;"&gt;val t = "Hi There!"&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;is the same as this in Java:&lt;br /&gt;&lt;br /&gt;&lt;code style="color: rgb(255, 0, 0); font-family: Courier,monospace;"&gt;static final String t = "Hi There!";&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;One thing to be aware of with vals is that if they reference an object, the properties of that object may be mutable - the val is really only a reference to the object, so it's only that reference that's guaranteed to never change.&lt;br /&gt;&lt;br /&gt;What all this means is that while you can do this:&lt;br /&gt;&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255); font-family: Courier,monospace;"&gt;&lt;br /&gt;var s = "Hello, World!"&lt;br /&gt;s = "Dominate, World!"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;You can't do this:&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255); font-family: Courier,monospace;"&gt;&lt;br /&gt;val t = "Hello, World!"&lt;br /&gt;t = "Dominate, World!"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I've found myself thinking of vals as "values" instead of variables because they don't vary.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Optional semicolons&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One thing to quickly point out, both Groovy and Scala have optional semicolons. You can still use them if you want to, but most of the time they can be left out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-4747080799788586626?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/4747080799788586626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=4747080799788586626' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/4747080799788586626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/4747080799788586626'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2008/01/scala-vs-groovy-variable-definintion.html' title='Scala vs Groovy: Variable Definintion &amp; Optional Semicolons'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-7936934243769431850</id><published>2008-01-11T12:22:00.000Z</published><updated>2008-01-11T22:47:50.078Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ScalaVsGroovy'/><title type='text'>Comparing Scala And Groovy</title><content type='html'>&lt;p&gt;As I've started to learn Scala, I've been thinking that it would be a good idea to compare Scala and Groovy. I'm going to assume that both are correctly installed and running.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I'll start by comparing comments:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;code style="color: rgb(51, 204, 0);font-family: Courier,monospace;"&gt;&lt;br /&gt;//This is a Groovy comment&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;It shows how I'll be using green to indicate Groovy code&lt;/span&gt;&lt;br /&gt;*/&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code style="color: rgb(51, 102, 255);font-family: Courier,monospace;"&gt;&lt;br /&gt;//This is a Scala comment&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;It shows how I'll be using blue for Scala code&lt;br /&gt;*/&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code style="color: rgb(255, 0, 0);font-family: Courier,monospace;"&gt;&lt;br /&gt;//This is a Java comment&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;It shows how I'll be using red if I ever need to show some Java code as well&lt;br /&gt;*/&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;p&gt;As you can see Groovy, Scala and Java all use the same style comments.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-7936934243769431850?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/7936934243769431850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=7936934243769431850' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/7936934243769431850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/7936934243769431850'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2008/01/comparing-scala-and-groovy.html' title='Comparing Scala And Groovy'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-7452308629588938737</id><published>2008-01-07T17:42:00.000Z</published><updated>2008-01-07T17:59:46.938Z</updated><title type='text'>Playing With Scala</title><content type='html'>Recently I've started playing with Scala, a mixed OO/functional language for the JVM. It's biggest selling point is that it looks and feels a lot like a dynamic (ie scripting) language, but it's statically typed and therefore about as fast as Java code.&lt;br /&gt;&lt;br /&gt;My biggest issue has been that a lot of the documentation about it has a very academic feel. One doc I read jumped almost straight into "Actors" (a rather advanced topic, especially for people who have never used Erlang) instead of introducing you to the language. I've been hearing that 2008 is the year Scala  will take off - but I think that will only happen if there is "documentation for the rest of us".&lt;br /&gt;&lt;br /&gt;Fortunately, that does appear to be coming. I broke down and bought the preprint of &lt;a href="http://www.artima.com/shop/forsale"&gt;Programming in Scala&lt;/a&gt;, which goes some way towards decent documentation (though some of the examples do stray into academic territory). Even though it's still in an early form, I highly recommend it to anyone who might be interested in looking into Scala and who doesn't want to feel that they're back on a Computer Science course. My first look at Scala was a couple months back and the lack of decent docs put me off, I thought I'd give it another shot now that this book is out and I haven't dropped Scala yet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-7452308629588938737?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/7452308629588938737/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=7452308629588938737' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/7452308629588938737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/7452308629588938737'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2008/01/playing-with-scala.html' title='Playing With Scala'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-3073372745415839267</id><published>2007-06-28T15:44:00.001Z</published><updated>2007-07-04T13:17:57.516Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='exif'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Fixing Photo Dates</title><content type='html'>I've recently realized that I've been taking photographs with the right day and month, but the wrong year (2006, not 2007). This means that some of the EXIF photo metadata is wrong and I want to correct it for each file.&lt;br /&gt;&lt;br /&gt;Reading EXIF appears easy under Java with Drew Noakes’s &lt;a href="http://www.drewnoakes.com/code/exif/"&gt;metadata-extractor&lt;/a&gt; but that library doesn't write EXIF data. There's the javax.imageio package, but that seems to be low level (ie, hard to use). I want a quick and dirty hack. So I'll use metadata-extractor to get the dates and call out to exiv2 to set the dates.&lt;br /&gt;&lt;br /&gt;Of course, Java often brings up things you can stumble over, and this was getting the exiv2 command  to run. I decided to use ProcessBuilder from java.lang (which, surprisingly, Groovy didn't seem to auto import), but it took a while to work out how to get it to launch an exiv2 command correctly (if at all). At a unix command line, in order to set the Original Date Time, you'd use something like:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;exiv2 -M"set Exif.Photo.DateTimeDigitized String 2007:03:27 07:53:16" ./photos/HPIM0059.JPG&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;It took ages to work out that I had to split the -M from the set command and that I should not quote the set command, so that the call to ProcessBuilder is along the lines of &lt;br /&gt;&lt;code&gt;&lt;br /&gt;Process p = new java.lang.ProcessBuilder("exiv2", "-M", "set Exif.Photo.DateTimeOriginal String 2007:03:27 07:53:16", "./photos/HPIM0059.JPG").start()&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Here's the code. Use at your own risk (remember, this script modifies files, so it could destroy something), and you'll proabably need to modify it to get it to work anyway.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;import com.drew.metadata.*&lt;br /&gt;import com.drew.imaging.jpeg.*&lt;br /&gt;import com.drew.metadata.exif.ExifDirectory&lt;br /&gt;import org.joda.time.*&lt;br /&gt;import org.joda.time.format.*&lt;br /&gt;&lt;br /&gt;DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy:MM:dd HH:mm:ss");&lt;br /&gt;&lt;br /&gt;photoDir = new File("photos")&lt;br /&gt;&lt;br /&gt;photoDir.eachFile { file -&gt;&lt;br /&gt;&lt;br /&gt; Metadata metadata = JpegMetadataReader.readMetadata(file);&lt;br /&gt;&lt;br /&gt; com.drew.metadata.exif.ExifDirectory exifDir = metadata.getDirectory(com.drew.metadata.exif.ExifDirectory)&lt;br /&gt;&lt;br /&gt; DateTime original = new org.joda.time.DateTime(exifDir.getDate(ExifDirectory.TAG_DATETIME_ORIGINAL))&lt;br /&gt;&lt;br /&gt; String newOriginal = fmt.print(original.plusYears(1))&lt;br /&gt;&lt;br /&gt; DateTime digitized = new org.joda.time.DateTime(exifDir.getDate(ExifDirectory.TAG_DATETIME_DIGITIZED))&lt;br /&gt; String newDigitized = fmt.print(digitized.plusYears(1))&lt;br /&gt;&lt;br /&gt; String fn = "~/projects/photo/fixdate/photos/${file.name}"&lt;br /&gt;&lt;br /&gt; String exiv2OCmd = "set Exif.Photo.DateTimeOriginal String ${newOriginal}"&lt;br /&gt;&lt;br /&gt; String exiv2DCmd = "set Exif.Photo.DateTimeDigitized String ${newDigitized}"&lt;br /&gt;&lt;br /&gt; println exiv2OCmd&lt;br /&gt; Process p = new java.lang.ProcessBuilder("exiv2", "-M", exiv2OCmd, fn).start()&lt;br /&gt; p.errorStream.eachLine {  println it }&lt;br /&gt;&lt;br /&gt; Process q = new java.lang.ProcessBuilder("exiv2", "-M", exiv2DCmd, fn).start()&lt;br /&gt; q.errorStream.eachLine {  println it }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//might as well set the last modified date&lt;br /&gt; file.setLastModified(original.plusYears(1).toDate().time)&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-3073372745415839267?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/3073372745415839267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=3073372745415839267' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/3073372745415839267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/3073372745415839267'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2007/06/fixing-photo-dates.html' title='Fixing Photo Dates'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-761990238460161116</id><published>2007-06-12T00:14:00.000Z</published><updated>2007-06-11T12:41:42.338Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Groovy and GNOME, Part 2</title><content type='html'>I've got an app up and running, though it doesn't do much.&lt;br /&gt;&lt;br /&gt;I created a simple UI with Glade. There's a built in "Gnome App" widget, which contains the beginnings as a main application window - menu bar, status bar and an area to place more widgets.&lt;br /&gt;&lt;br /&gt;With the glade file in hand I created 1 class and 1 script. The class is the backing for glade - it loads the glade file and handles it's events. I also added a show method to make the app display. At the moment, it only handles 2 events - the event from the File -&gt; Close menu item and the delete-event, which is sent when you click on the X button on the right hand corner.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;import org.gnu.glade.LibGlade;&lt;br /&gt;import org.gnu.gtk.Gtk;&lt;br /&gt;import org.gnu.gtk.event.GtkEvent;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class TestApp {&lt;br /&gt;&lt;br /&gt; private static final String GLADE_FILE = "TestApp.glade"&lt;br /&gt; private LibGlade libglade;&lt;br /&gt;&lt;br /&gt; public TestApp() {&lt;br /&gt;  libglade = new LibGlade(GLADE_FILE, this);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void show() {&lt;br /&gt;  libglade.getWidget("gnomeapp1").show()&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private quitApp(int res) {&lt;br /&gt;  Gtk.mainQuit()&lt;br /&gt;  System.exit(res)  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public on_FileQuit(GtkEvent event) {&lt;br /&gt;  this.quitApp(0)&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public on_DeleteEvent(GtkEvent event) {&lt;br /&gt;  this.quitApp(0)&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The script is a couple lines, enough to initialize Gnome (and, by extenision GTK), create an instance of the main application class, cause the main window to be shown and then enter the Gtk main loop&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;import org.gnu.gtk.Gtk;&lt;br /&gt;import org.gnu.gnome.Program;&lt;br /&gt;&lt;br /&gt;Program.initGnomeUI("TestApp", "0.1", args);&lt;br /&gt;TestApp gui = new TestApp()&lt;br /&gt;gui.show()&lt;br /&gt;&lt;br /&gt;Gtk.main()&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-761990238460161116?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/761990238460161116/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=761990238460161116' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/761990238460161116'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/761990238460161116'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2007/06/groovy-and-gnome-part-2.html' title='Groovy and GNOME, Part 2'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-5370437447791251091</id><published>2007-06-11T23:46:00.000Z</published><updated>2007-06-11T11:55:55.399Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Groovy and GNOME, Part 1</title><content type='html'>I've decided to write a small app in Groovy, but I plan to use Gtk/GNOME/Glade for the UI side of things.&lt;br /&gt;&lt;br /&gt;So far, I've installed Glade (version 3) and libglade-java. It looks like libglade-java depends on libgnome-java, so I'm hoping Synaptic has pulled in all the needed dependencies to get up and running.&lt;br /&gt;&lt;br /&gt;On Ubuntu, the jar files needed to start developing Gtk/GNOME apps live in /usr/share/java and need to get appended to the classpath. You also need to set LD_LIBRARY_PATH to include /usr/lib/jni as this is where the jni portion of the bindings live.&lt;br /&gt;&lt;br /&gt;I just wrap all of this, plus the setting up of GROOVY_HOME and such like, into a bash script.&lt;br /&gt;&lt;br /&gt;As I get on with the project, I'll post more&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-5370437447791251091?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/5370437447791251091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=5370437447791251091' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/5370437447791251091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/5370437447791251091'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2007/06/groovy-and-gnome-part-1.html' title='Groovy and GNOME, Part 1'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-7723159226942435903</id><published>2007-06-08T23:29:00.000Z</published><updated>2007-06-08T15:58:59.823Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='gdata'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>The GData API and "Web Content"</title><content type='html'>As mentioned &lt;a href="http://froth-and-java.blogspot.com/2007/06/html-screen-scraping-with-groovy.html"&gt;previously&lt;/a&gt;, recently I wrote a script to scrape the UV Index forecast for London off of the TEMIS website and then upload that data into Google Calendar as a bunch of events that have associated "web content", that way there will be a little coloured box on the top of each day, and hovering over the box will give the numerical value for the forecasted UV Index for that day.&lt;br /&gt;&lt;br /&gt;It was, for the most part, fairly straight forward (even though I used the "raw" Google Data Java API and not the sugared API that's available for groovy). The biggest issue I ran into was that the API doesn't like WebContent that doesn't have a content URL set. According to the &lt;a href="http://www.google.com/support/calendar/bin/answer.py?answer=48528"&gt;documentation at Google's Help Center&lt;/a&gt;, a content URL is optional. A content URL is the URL for content that will be displayed when the user clicks on the icon for the event, which isn't always necessary (such as with the weather forecast). However, trying to insert an event with WebContent using the Java API that doesn't have a content URL always resulted in 404 ResourceNotFound errors. Putting in a URL was the only way to get it working, so I quickly created an about.html that displays a copyright notice indicating that the data is from TEMIS (which is a good thing to have anyway).&lt;br /&gt;&lt;br /&gt;The coloured boxes were whipped up with &lt;a href="http://www.imagemagick.org/"&gt;ImageMagick&lt;/a&gt;, the colours are based on the colours used in the &lt;a href="http://en.wikipedia.org/wiki/UV_index"&gt;wikipedia article&lt;/a&gt; on the UV Index. The coloured box that gets displayed is dependent on the forecasted UV Index.&lt;br /&gt;&lt;br /&gt;The calendar can be found &lt;a href="http://www.google.com/calendar/ical/fme5bjmdgcc8glfeotr65oajhg%40group.calendar.google.com/public/basic.ics"&gt;here&lt;/a&gt;. If you add it to your own set of calendars, you'll probably have to hit the refresh button to get the boxes to display.&lt;br /&gt;&lt;br /&gt;One other thing, that I'm not sure is mentioned elsewhere, but the API needed the Java Mail API (javx.mail) on the classpath. So I had to download it from &lt;a href="http://java.sun.com/products/javamail/"&gt;Sun&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-7723159226942435903?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/7723159226942435903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=7723159226942435903' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/7723159226942435903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/7723159226942435903'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2007/06/gdata-api-and-web-content.html' title='The GData API and &quot;Web Content&quot;'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-3400488878417820425</id><published>2007-06-08T22:18:00.000Z</published><updated>2011-12-21T09:53:53.689Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>HTML Screen Scraping With Groovy</title><content type='html'>Recently, I wrote a script to scrape UV Index data from the &lt;a href="http://www.temis.nl/uvradiation/nrt/uvindex.php"&gt;Tropospheric Emission Monitoring Internet Service&lt;/a&gt; and then upload that data to Google Calendar as "Web Content". Here's how I went about scraping the data&lt;br /&gt;&lt;br /&gt;I used Groovy's &lt;a href="http://groovy.codehaus.org/Reading+XML+using+Groovy%27s+XmlSlurper"&gt;XmlSlurper&lt;/a&gt; to do the heavy lifting. XmlSlurper uses SAX underneath and, importantly, lets you choose a different SAXParser. As I wanted to parse HTML and not XML, I used &lt;a href="http://ccil.org/%7Ecowan/XML/tagsoup/"&gt;TagSoup&lt;/a&gt; as my SAXParser.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;slurper = new XmlSlurper(new org.ccil.cowan.tagsoup.Parser())&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Everytime I run the script (with cron, overnight), I'm going to want to use the latest data, so I created a URL object that had the URL for the UV Index data for London, and then used groovy's "withReader" enhancement to read and parse the data&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;url = new URL("http://blah/blah?blah")&lt;br /&gt;&lt;br /&gt;url.withReader { reader -&gt;&lt;br /&gt;&lt;br /&gt;    html = slurper.parse(reader)&lt;br /&gt;&lt;br /&gt;       //we should now have a parsed file&lt;br /&gt;&lt;br /&gt;    ...scrapeing code...&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;As the data I was looking for was conviently located in a table, all I had to do was find the path to the table (firebug comes in real handy here)&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  tbl = html.body.table.tr.td.dl.dd.table&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;That gives a table and we can use a closure to iterate over the rows&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;  tbl.tr.list().each { row -&gt;&lt;br /&gt;  &lt;br /&gt;   ... row parsing code ...&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Each row has a td list, so any particular cell of a row can then be accessed as row.td[X]. In order to get a row as a string, you'll need to use toString (so, to get the data of the first cell as a string, it's row.td[0].toString()).&lt;br /&gt;&lt;br /&gt;I came across an interesting issue with the trim function when I was trying to parse the first column into a DateTime (using the &lt;a href="http://joda-time.sourceforge.net/"&gt;Joda Time&lt;/a&gt; library. There were some non-breaking spaces in the String, and trim doesn't trim non breaking spaces, so I had to run a quick regular expression on the String to get rid of them&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  ds = row.td[0].toString().replaceAll(/\xA0/ , {""})&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;So putting it all together (though without the Google API code to do the uploading)&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;slurper = new XmlSlurper(new org.ccil.cowan.tagsoup.Parser());&lt;br /&gt;&lt;br /&gt;url = new URL('http://www.temis.nl/uvradiation/nrt/uvindex.php?lon=-0.07&amp;lat=51.30')&lt;br /&gt;&lt;br /&gt;url.withReader { reader -&gt;&lt;br /&gt; html = slurper.parse(reader);&lt;br /&gt;&lt;br /&gt; tbl = html.body.table.tr.td.dl.dd.table&lt;br /&gt;&lt;br /&gt; tbl.tr.list().each { row -&gt;&lt;br /&gt;&lt;br /&gt;  if (row.td.size() == 3) {&lt;br /&gt;   //trim doesn't work on a non breaking space&lt;br /&gt;   ds = row.td[0].toString().replaceAll(/\xA0/, {""}).trim()&lt;br /&gt;   uvi = row.td[1].toString().toFloat()&lt;br /&gt;&lt;br /&gt;   //now do something with the date and uv index&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;There is one thing to note here -it does a quick check to make sure that there a 3 columns (date, uv index and ozone column), this is because there will be an extra row at the start of the table that contains the city name, if TEMIS know what the city name is for a set of co-ordinates. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I ran into a couple of niggles with the Google side of things, but that's probably best left to a different post&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-3400488878417820425?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/3400488878417820425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=3400488878417820425' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/3400488878417820425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/3400488878417820425'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2007/06/html-screen-scraping-with-groovy.html' title='HTML Screen Scraping With Groovy'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2726786215957001832.post-87025696208739683</id><published>2007-06-08T11:07:00.000Z</published><updated>2007-06-08T15:21:41.982Z</updated><title type='text'>Welcome to Froth &amp; Java</title><content type='html'>Where I'm currently working, the catering company has recently changed, and the new company has brought in coffee cups with "Froth &amp; Java" written on them. I though that would be a great name for a blog, and as I was already thinking of having a separate blog for Java and Groovy related things I thought I might as well start now. So here it is.&lt;br /&gt;&lt;br /&gt;I might bring a few posts across from some of my old blogs, so if you see a post that's older than this welcome, then it's because that post pre-dates this blog.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2726786215957001832-87025696208739683?l=www.frothandjava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.frothandjava.com/feeds/87025696208739683/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2726786215957001832&amp;postID=87025696208739683' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/87025696208739683'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2726786215957001832/posts/default/87025696208739683'/><link rel='alternate' type='text/html' href='http://www.frothandjava.com/2007/06/welcome-to-froth-and-java.html' title='Welcome to Froth &amp; Java'/><author><name>Scot McSweeney-Roberts</name><uri>http://www.blogger.com/profile/05078277004789544258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
