Showing posts with label groovy. Show all posts
Showing posts with label groovy. Show all posts

Monday, April 2, 2012

Groovy - using a writer with FileIO

Groovy - using a writer with FileIO


public void writeToFile(def directory, def fileName, def extension, def infoList) {
new File("$directory/$fileName$extension").withWriter { out ->
infoList.each {
out.println it
}
}
}

Sunday, May 3, 2009

Set pojo properties with groovy sql row results

This is probably documented somewhere that you can do this with a Map and a regular typed Object, I just hadn't run across it and tried it to see what happens.

You can just pass in a Map of properties to an Object and as long as you don't have any properties in your Map that are not defined in the class, it'll work fine. As an example:


class Person {
String name
Integer age
String address
}

def map = [ name: "Joe", age: 4, address: "Somewhere"]

Person p = new Person(map)

println "Peson name: $p.name, address: $p.address"


This comes in real handy when want you want to populate some groovy sql results into a collection of typed objects. As an example:


def getPersons() {
def persons = []
sql.eachRow("Select * from Person") {
persons << new Person( it.toRowResult() )
}
return persons
}

Monday, April 6, 2009

Using Groovy @Delegate

Groovy 1.6 introduces some killer stuff!

I really like @Delegate.

For those that don't use Groovy much, what @Delegate does is best seen by an example. The one in the link above is pretty good dealing with Date in an Event, but as a real world example here's how I needed it....

groovy.sql is pretty cool and you can call toRowResult() on each groovy result set object, which lets you use those GroovyRowResult objects directly calling the column name as properties... for example..


def sql = Sql.newInstance("jdbc:jtds:sybase://.....I", "user", "passr", "net.sourceforge.jtds.jdbc.Driver")
def results = []
sql.eachRow("SELECT firstName, lastName FROM Person") {
results << it.toRowResult()
}


//print first and last names from results collected:
results.each {
println "firstName = $it.firstName lastName= $it.lastName"
}


Ok simple enough, but now what if you wanted to also get a "fullName" property? Ok simple enough we'll just make a Person object and create a method to create it. But wait, I still need access to all those other database fields. Now sure in many CRUD apps you'd already have a Person object with all the typical fields firstName, lastName etc... but in this case I only need display data and I'm perfectly happy with using the database field names for the property names so I want to just use my groovyRowResult directly but also want to be able to call "lastNam.". So in Java what would one do? I don't want to mess around trying to extend GroovyRowResult (if I even could?) or maybe my Person also needed to already extend another Base object as it is. Obviously you want to wrap row in an adapter and then in Java you'd have to use some reflection and proxy method/property calls to the wrapped row object if a call to a method/property wasn't found in Person. Sort of a pain to have to code that proxy stuff though. Granted not difficult and you can cut and paste it from other projects once you've done it once, but with Groovy it's even easier and much cleaner. for my sql example above...


class Person {
@Delegate(interfaces=false) GroovyRowResult row

def getFullName() {
return "${row.firstName} ${row.lastName}"
}
}

//...
sql.eachRow("SELECT firstName, lastName FROM Person") {
results << new Person( row: it.toRowResult() )
}

results.each {
println "firstName = $it.firstName" // finds firstName in delegate!!!!
println "lastName = $it.lastName"
}


Before using Delegate I was using propertyMissing, which would be fine in this case since I only have one delegate but things would be trickier if I had multiple nested objects (whereas using @Delegate it wouldn't be an issue - assuming you didn't have conflicting method/property names - in which case not sure what would happen.) Even using the old propertMissing in Groovy is quite cool:


//using propertyMissing
class Person {
@Delegate GroovyRowResult row

def getFullName() {
return "${row.firstName} ${row.lastName}"
}

def propertyMissing(String prop) {
def result = row."${prop}"
}
}

Monday, March 23, 2009

Leveraging propertyMissing and toRowResult() on resultSet

NOTE: Instead of using propertyMissing below, use @Delegate as described in this later post: http://reumann.blogspot.com/2009/04/using-groovy-delegate.html

The groovy documentation is good in some areas, and stinks in others. I wish they covered sql and jdbc stuff a bit more. This is probably basic for many of you, but I figure I'll post it anyway.

First off, when returning sql back using Sql.eachRow, I wanted to build a collection of objects I could use directly. You can't use the ResultSet items returned directly, but I did find you can generate a GroovyRowResult object by calling toRowResult on each object. So your eachRow could look like:


def results = []
sql.eachRow(query) {
results << it.toRowResult()
}


Of course the above assumes you want to work the column names as property names directly as they are returned from your sql. This was fine for me, but when dealing with the results, I wanted to call some other properties on each result that would be a composite or calculated from the resulting GroovyRowResult. As an example, I might be getting back firstName and lastName, but I also wanted a "fullName" property comprised of firstName + lastName.

There are probably a lot of ways to do this, but what seemed clean to me was to create a groovy object that I'd stuff each GroovyRowResult into and rely on overriding "propertyMissing" to help me out. My new object acts as an Adapter wrapping the GroovyRowResult. Here's an example:

//Employee.groovy

class Employee {

def row

Employee( row ) {
this.row = row
}

//look up missing property in GroovyRowResult:
def propertyMissing(String prop) {
def result = row."${prop}"
}

String getFullName() {
return this.firstName+" "+this.lastName
}
}


//Usage

def results = []
sql.eachRow("SELECT * FROM Employee") {
results << new Employee( it.toRowResult() )
}

//see it works:
println "first: ${results[0].firstName}"
println "full: ${results[0].fullName}"

Sunday, March 22, 2009

jQuery change select options when other select changes

A common thing to do, but figured I'd post how I do it here. (I wrote this initially for a sample at http://www.learntechnology.net/content/ajax/jquery_options.jsp. In the case below I'm retuning JSON from the server side component (in this case a Stripes actionBean.)

Import your jQuery javascript file. Then in your html or external script:


$(document).ready(function() {
$(function() {
$("select#companies").change(function() {
$.getJSON("Companies.action?emmployees=",{companyID: $(this).val(), ajax: 'true'}, function(j){
var options = '';
for (var i = 0; i < j.length; i++) {
options += '<option value="' + j[i].value + '">' + j[i].label + '</option>';
}
$("select#employees").html(options);
})
})
})
});


My initial select has an id "companies" (ie <select id="companies"). The select to populate is simply defined as:


<select name="employeeID" id="employees"></select>


The server side component just needs to return json with your employees objects with fields "label" and "value"

Wednesday, March 4, 2009

Maven2-Groovy-JUnit-Guice

Here's how I'm currently setting up my testing with groovy and maven, using Guice and JUnit. (I had trouble getting this all to work with TestNG, which is my preferred testing framework, so if someone gets it all working, please let me know.)

I'm usting AtUnit to help out with the Guice/JUnit integration. It makes things very simple.

In your pom.xml build plugins section:


<plugin>
<groupid>org.codehaus.groovy.maven</groupid>
<artifactid>gmaven-plugin</artifactid>
<version>1.0-rc-4</version>
<executions>
<execution>
<goals>
<goal>generateStubs</goal>
<goal>compile</goal>
<goal>generateTestStubs</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>


My groovy tests are located in src/test/groovy (Using Eclipse I then mark this as a source folder also so it's easier to use in a flattened package structure.)

When you look at the AtUnit examples, you'll see several ways to set things up. I like to use my existing Guice module class that I've already created, so I start out with a TestBase class that my tests will extend...


public class TestBase implements Module {

public void configure(Binder binder) {
binder.install(new MyGuiceModule());
}
}


If you don't want to use a Module, you can just do all your binding right in the configure method above and everything will work just fine (and this is the way they demonstrate on the AtUnit site example.)

Now one of my groovy tests:


@RunWith(AtUnit.class)
@Container(Container.Option.GUICE)
public class ExecutionLogTest extends TestBase {

@Inject @Unit ExecutionLogs execLogs;

@Test
public void testExeuctionLogs() {
println "testExeuctionLogs"
//... execLogs.find(... )
}
}


mvn clean install and that's it.

Blogger Syntax Highliter