Skip to content

Instantly share code, notes, and snippets.

@gburgett
Created January 28, 2012 21:07
Show Gist options
  • Save gburgett/1695753 to your computer and use it in GitHub Desktop.
Save gburgett/1695753 to your computer and use it in GitHub Desktop.
jpropel linq and groovy
package propel.groovy.utils
import lombok.Functions;
/**
* This groovy class is an example of how to interface between the groovy 'closure' concept
* and Lombok's Functions. It provides a groovy way to call into JPropel's LINQ functions.
* Right now this is just a proof of concept, as I use more of the LINQ functions I'll add
* them to this gist.
* @author gordon burgett
*/
class Linq {
static void Register(){
Iterable.metaClass{
select << {
Closure selector -> Linq.select(delegate, selector)
}
}
}
static <TSource, TResult> Iterable<TResult> select(final Iterable<TSource> values,
Closure selector)
{
return propel.core.utils.Linq.select(values,
[apply:{ selector(it) }] as Functions.Function1<TSource, TResult>);
}
}
/*
* An example groovy script performing LINQ queries on a list of strings in three different ways,
* showing that each of the LINQ classes in this gist works.
*/
package main
import propel.groovy.utils.*;
def names=['gordon', 'guy', 'morepeople']
//The standard java way of calling into a static method, passes a closure to the groovy Linq class
println "select using groovy Linq w/closure"
def result = propel.groovy.utils.Linq.select(names,
{
x -> x.substring(2);
});
result.each{println it}
//the standard java way of calling into a static method, passes a closure to a pure java Linq class
println "select using java LINQ w/closure"
def result2 = propel.groovy.utils.LinqJava.select(names,
{
x -> x.substring(2);
});
result2.each{println it}
//Uses groovy categories to pull the Java linq class in as extensions
println "select using groovy categories"
use(propel.groovy.utils.LinqJava){
def result3 = names.select({
x -> x.substring(2);
});
result3.each{println it}
}
//Uses the ExpandoMetaClass of Iterable to attach extension methods
println "select using groovy expando meta class"
//perhaps the lombok @ExtensionMethod class could do the registering?
Linq.Register();
def result4 = names.select({
x -> x.substring(2);
});
result4.each{println it}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package propel.groovy.utils;
import groovy.lang.Closure;
import lombok.Functions;
/**
* A Java-only version of propel.groovy.utils.Linq, it does not provide extension
* of the ExpandoMetaClass but it can accept groovy closures.
* @author gordon
*/
public class LinqJava {
public static <TSource, TResult> Iterable<TResult> select(final Iterable<TSource> values,
final Closure selector)
{
return propel.core.utils.Linq.select(values,
new Functions.Function1<TSource,TResult>(){
@Override
public TResult apply(TSource t1) {
return (TResult)selector.call(t1);
}
});
}
}
@gburgett
Copy link
Author

This gist is simply a proof of concept for calling into jpropel's Linq (https://github.com/nicholas22/jpropel) from groovy. Groovy already has some nice syntactic sugar for iterables, but does not provide the deferred-execution functionality of Linq. Having access to Linq from groovy would allow Linq queries to be created using closures similar to C#'s anonymous methods.

The example script shows 3 separate ways of calling Linq queries with closures. I would appreciate some help with a better way to extend Iterable through the ExpandoMetaClass than having to call Register, perhaps some kind of annotation could do that? I may investigate lombok's @ExtensionMethod annotation to see if it can be used to do this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment