Groovy #1

Several years ago, when Java was still a toddler, probably around 2001, my brother had written a very functional downloader in Swing – it would read a text file of urls, and download each file one by one. It has been a while, that source code is gone, Swing is gone, Sun is gone, blah blah blah.

Sitting idly, I suddenly thought of that piece of code for no reason and said to myself why not rewrite that in groovy. And literally wrote this in a few minutes… The code is pretty self contained, it assumes defaults and there is even a test mode… Its been long journey with Java, yeah definitely feels like one.

Invoking is pretty easy:

groovy Download.groovy -fileName [urlsPerLineFile.txt]

import java.io.*;

class DownloadFile {

    def args = [:]
    def list2map = { list -> def map = [:]; 0.step(list.size(),2) { i -> map[list[i] - "-"] = list[i+1] }; return map }
    def download(url) {
            def file = new FileOutputStream(url.tokenize("/")[-1])
            def out = new BufferedOutputStream(args.targetDir + file)
            out << new URL(url).openStream()
            out.close()
    }

    public DownloadFile(String[] _args) {
        args = this.list2map(_args)
        args.mode = args.mode ?: "test"
        args.targetDir = args.targetDir ?: "c:/downloads/files"
        println args
    }

    public void process() {
        new File(args.fileName).readLines().each {
            println "downloading [$it]"
            if (args.mode != "test") {
                download(it)
            }
        }
    }
}

new DownloadFile(this.args).process()

While the code is simple, there are two things I really like about it. First is the closure for conversion from list to map.

def list2map = { list -> def map = [:]; 0.step(list.size(),2) { i -> map[list[i] – “-“] = list[i+1] }; return map }

This converts a command-line invoke with arguments with a hyphen character into a map of key-value. For eg:

Download.groovy -mode test -targetDir c:/downloads

will yield a map of [mode:test, targetDir:c:/downloads] Neat isn’t it? Think of how complicated a conversion of list to map in Java is.

Another is the expando, see the keys of the map are used like properties: args.mode, args.targetDir instead of args.getKey(“mode”) or args.getKey(“targetDir”).

The above feature comes very handy especially when trying to deserializing xml into objects. You just don’t do deserialization xml to java bean objects! Use directly. That way if xml changes, you do not have to generate code again (think jaxb!). Just modify your code to use the new xml tags!

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: