Created
January 28, 2012 21:07
-
-
Save gburgett/1695753 to your computer and use it in GitHub Desktop.
jpropel linq and groovy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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); | |
} | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.