Groovy 1.0 hits the streets


E’rybody get’cha groove on! MY favorite development language just turned one yesterday. It’s been under development for a while and the results are that you get a full featured general purpose programming language with the expressivity of a scripting language, an optional compiler, meta programming for folding the language to meet domain specific tasks, and a boat load of extra niceties. Here’s some of the features you won’t see advertised on too many other programming language home sites.

COM Scripting
Sure we all write Java so that we can run on any platform. Blah, blah, WORA, blah, blah, bleh. What if you’re on a Windows machine and you just don’t care about that stuff? Why should you put up with limited feature-lacking custom 100% Java knock offs of the functionality that your VB5 writing cousing has been spoiled with since day one? Suppose you just want to get into a Windows object without rifling through off by one documentation?

import org.codehaus.groovy.scriptom.ActiveXProxy

//Open Excel
new ActiveXProxy("Excel.Application").Visible = true

//Goto the Jakarta derivative work and tell'em you can do it easier
// instantiate Internet Explorer
def explorer = new ActiveXProxy("InternetExplorer.Application")

// set its properties
explorer.Visible = true
explorer.AddressBar = true

// navigate to a site
explorer.Navigate("http://jakarta.apache.org/poi/")
Thread.sleep(1000)
explorer.StatusText = "Why would you read these docs?"


// showing the current directory
def cmd = new ActiveXProxy("Scripting.FileSystemObject")
println cmd.GetAbsolutePathName(".").value

// choosing a folder from a native windows directory chooser
def folder = new ActiveXProxy("Shell.Application").BrowseForFolder(0, "Choose a folder", 0)
println folder.Items().Item().Path.value

// show some key from the registry
def key = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\User Agent"
println new ActiveXProxy("WScript.Shell").RegRead(key).value

def net = new ActiveXProxy("WScript.Network")
// prints the computer name
println net.ComputerName.value

// invoke some VBScript from Groovy and get the results!
def sc = new ActiveXProxy("ScriptControl")
sc.Language = "VBScript"
println sc.Eval("1 + 1").value

(No disrespect intended to the POI project. The prior example is illustrative of a ficticious naive developer stuck in the world of Win-d’ohs and serves as an example of how Groovy can help even the simple minded among us.)

Gant – Groovy Ant builds
Gant scratches that itch we all get when working in Ant XML hell. You know that one simple thing you want to do which would be a simple string manipulation in a for loop in [insert-language-of-choice-here] but explodes into a complicated series of XML tags using complicated tasks that bear no resemblance to the task at hand. (Eg. setting the library dependancies in the “Class-Path” attribute of the MANIFEST.MF of your jar file.) Yeah, you could break out the script tag and add the required scripting Jar to Ant-lib but what if you didn’t have to confuse your tags? What if you could just use a programming language that inherited all of the features of your tag language? What if your build file just flowed like it should?

includeTargets << org.codehaus.groovy.gant.targets.Clean
cleanPattern << [ '**/*~' ,  '**/*.bak' ]
cleanDirectory << 'build'

task ( 'default' : 'The default target.' ) {
  println ( 'Default' )
  depends ( clean )
  Ant.echo ( message : 'A default message from Ant.' )
  otherStuff ( )
}

task ( otherStuff : 'Other stuff' ) {
  println ( 'OtherStuff' )
  Ant.echo ( message : 'Another message from Ant.' )
  clean ( )
}

(Nuff respect to Russ for persuing this work of art even after I repeatedly told him how stoopid he was and that we should all just use Maven2 for everything. yeah, yeah. I was dumb and he is brilliant. Now let’s get on with the next thing, can we?)

Gram
You got a bunch of Java source with hibernate annotations right? (Don’t argue, just agree for the sake of argument.) You got a Gant build and you wanna do something with these annotations right? For now we’ll just print them. Later on you can get fancy and color every other Hibernated class pink.

def persistentClasses = classes.findAll { it.getAnnotation("hibernate.class") != null }

println "Found ${persistentClasses.size()} instances out of ${classes.size()}"

persistentClasses.each { c ->
    println c.simpleName

    for (p in c.properties) {
        println "  property: ${p.simpleName}"
    }
}

And we run with our Gant code:

includeTargets << org.codehaus.groovy.gant.targets.Clean
cleanPattern << [ ’**/*~’ ,  ’**/*.bak’ ]
cleanDirectory << ’build’

task ( ’default’ : ’The default target.’ ) {   println ( ’Default’ )   depends ( clean )   Ant.echo ( message : ’A default message from Ant.’ )   otherStuff ( ) }
task(seeHibernatedClasses: 'Print out all of our Hibernate stuff' ) {    Ant.java(classname:'org.codehaus.gram.Gram' fork:true) {       classpath(refid:'tool.classpath')
      // the directory where the source code lives       arg(value:'src/java')
      // the groovy script that processes the annotations       arg( value:'src/script/MyGram.groovy')    } }

(The above Gant snippet has not been test and is most likely garaunteed not to work. It is a rough guess at what the example ant snip from the linked page would look like under Gant. It is also a wild stab in the dark at putting some of the ideas from the Groovy home page together.)

GSql
ORM is nice with the Springframework but it gets even better when you remove the shackles of Java framework intrusion. What’s left is the stuff that matters.

import groovy.sql.Sql

class GroovyJDBCCustomerRepository  implements CustomerRepository {    def sql = Sql.newInstance("jdbc:mysql://localhost:3306/db", "mysqluser", getPassword(),        "com.mysql.jdbc.Driver")
      def getCustomersRegisteredAfter(def dateSelected) {          def customers = []          sql.eachRow("Select cus_name, cus_addr, cus_register_date from customer where cus_register_date >= ${dateSelected}") { row ->             customers << new Customer( name: row.cus_name, address: row.cus_addr, registerDate: row.cus_register_date )       }       return customers    } }

Groovy XML
If you thought you were ripping through XML before with your fancy TrAX API and your SAXXmlTranformerFactory and all of your fancy pull/push processing magic, you ain’t seen nuttin’ yet! Groovy steps upon the scene with a lean and a mean XMLParser full of sheen! Picture this XML

<programming-languages>
   <language name="RPG">
      <compiled>true</compiled>
      <platforms>
         <platform os="true">
            <name>OS/400</name>
         </platform>
      </platforms>
   </language>
   <language name="C#">
      <compiled>true</compiled>
      <platforms>
         <platform os="false">
            <name>CLR</name>
         </platform>
         <platform os="true">
            <name>Windows</name>
         </platform>
         <platform os="true">
            <name>Linux</name>
         </platform>
      </platforms>
   </language>
   <language name="Java">
      <compiled>true</compiled>
      <platforms>
         <platform os="false">
            <name>JVM</name>
         </platform>
         <platform os="true">
            <name>OS/400</name>
         </platform>
         <platform os="true">
            <name>Windows</name>
         </platform>
         <platform os="true">
            <name>Linux</name>
         </platform>
      </platforms>
   </language>
</programming-languages>

Now lets rip through it:

def languages = new XmlSlurper().parseText(PROGRAMMING_LANGUAGES_XML)

//The second platform of the third language is OS/400 assert 'OS/400' == languages.language[2].platforms.platform[1].name.text()

With Groovy you get all that and much more. I wish I had time to ramble on but WordPress was down and out for a good chunk of time and now I have to wrap up. If you feelin’ my flow head over to Codehaus and get’cha Groove on! Holla back…

Leave a Reply

Fill in your details below or click an icon to log in:

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