Entries Tagged 'Groovy' ↓
February 5th, 2013 — code, Gradle, Groovy, jvm
Having just read Michał Mally’s blog that was posted on Google+,
I was intrigued with two benefits listed in the blog:
- The idea of being able to augment Groovy with changes that would behave as “if they were a part of original GDK”
- support from your IDE like code completion shall be available out-of-the-box
In order to get my head around how Extension modules worked, I used the following as references
Creating an extension module
Groovy Goodness: Adding Extra Methods Using Extension Modules
Groovy Extension Modules
Cédric Champeau had this to say after I asked about the benefits of Extension Modules over using MetaClass/Expando/Category
@Juan: extension modules are automatically loaded and made available globally. You don’t have to bother with metaclasses (and potential issues with external changes). As well, categories are lexically scoped, although extension modules are global (meaning that they can be used anywhere in the code as long as the extension module is found on classpath).
Last but not least, extension modules are compatible with type checking and static compilation
To solidify my new understanding of Groovy’s Extension Modules, I decided that I needed to write some code. The example I came up with was to have the functional names (map, reduce, filter ) that I had come familiar with in using Clojure added to Groovy. These “extended methods” are using Groovy’s built-in collect, inject, and grep under the hood.
Source code can be found here
Here is the code for the new aliases found in the FuncProgUtilExtension.groovy class
package com.javazquez;
public class FuncProgUtilExtension {
public static Collection filter(Collection self, Closure clozure) {
return self.grep(clozure)
}
public static Collection map(Collection self, Closure clozure) {
return self.collect(clozure)
}
public static Object reduce(Collection self, Closure clozure) {
return self.inject(clozure)
}
public static Object reduce(Collection self, String operator) {
switch(operator){
case '+' :
self.inject({acc, val -> acc + val})
break
case '-' :
self.inject({acc, val -> acc - val})
break
case'*' :
self.inject({acc, val -> acc * val})
break
case '/':
self.inject({acc, val -> acc / val})
break
case'**':
self.inject({acc, val -> Math.pow(acc, val)})
break
default:
throw new IllegalArgumentException()
break
}
}
}
In a file named ‘org.codehaus.groovy.runtime.ExtensionModule’ located in ‘src/main/resources/META-INF/services/’
I have the following
moduleName=JavazquezFuncProgTest
moduleVersion=1.0
extensionClasses=com.javazquez.FuncProgUtilExtention
Using spock, I wrote the following tests :
package com.javazquez
import spock.lang.Specification
class FuncProgUtilSpec extends Specification{
def "test map"(){
expect:
[ 1 ,2 ,3 ,4].map{it*2} == [ 1 ,2 ,3 ,4].collect{ it*2 }
}
def "test reduce "(){
expect:
[ 1 ,2 ,3].reduce('*') == 6
[ 1 ,2 ,3,4].reduce('+') == 10
[ '1' ,'2' ,'3','4'].reduce('+') == '1234'
[ 1 ,2 ,3].reduce('-') == -4
[ 2, 2 ,2].reduce('**') == 16
[ 1 ,2 ,3].reduce({acc, val -> acc + val}) ==[ 1 ,2 ,3].inject { acc, val -> acc + val}
}
def "test invalid argument"(){
when:
[ 1 ,2 ,3,4].reduce('%')
then:
thrown(IllegalArgumentException)
}
def "test filter"(){
expect:
[1,2,3,4,5,6,7,8,9].filter { it % 2 ==0 } == [2,4,6,8]
[1,2,3,4,5,6,7,8,9].filter { it > 2 } == [3,4,5,6,7,8,9]
"Juan Vazquez".toList().filter { it ==~ /[aeiou]/} == ['u','a','a','u','e']
}
}
My biggest obstacle was getting the directory structure correct. It is amazing how little code was required to accomplish my goal. I hope my example project and listed references will help in your understanding of this powerful feature. My next step with this project going to be to make evaluation lazy.
January 26th, 2013 — code, Groovy, java, jvm
The release of Groovy 2.1 comes with full Invoke Dynamic Support. Initially I had issues with trying to get a working example up and running as seen by the following message.
>groovy –indy mergesort.groovy
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
General error during class generation: Cannot use invokedynamic, indy module was excluded from this build.
I checked the groovy version to make sure that I had Java 7 loaded as seen here
groovy -version
Groovy Version: 2.1.0 JVM: 1.7.0_11 Vendor: Oracle Corporation OS: Mac OS X
In order to get things working, I read that I needed to get the “indy” jar on my classpath. I added the following to my .bash_profile and restarted my terminal and the error cleared up
export CLASSPATH=$HOME/.gvm/groovy/current/indy/groovy-2.1.0-indy.jar
Hope this helps and a huge thanks to the Groovy Core Team for this latest update!
-Juan
September 8th, 2012 — Groovy, python
Here is a quick example of faking python generators with Groovy. Please update the comments if you have a better approach.
def (a,b,sent,acc) = [0,1,null,0]
def fib={
(a,b) = [b,a+=b]
a
}
while(true){
currFibValue = fib()
if( currFibValue > 4000000) break
else if( currFibValue % 2 ==0) acc += currFibValue
}
println acc
November 15th, 2011 — code, Gradle, Groovy, java, jvm, Uncategorized
Hello fellow Groovyists
I have been kicking the tires on using Gradle for my Groovy projects. I had a few stumbles along the way and wanted to share what I came up with for getting a very simple example working.
build.gradle
apply plugin: 'groovy'
version = "1.0-${new Date().format('yyyyMMdd')}"
manifest.mainAttributes("Main-Class" : "com.javazquez.HelloThere")
repositories {
mavenCentral()
mavenRepo urls: "http://groovypp.artifactoryonline.com/groovypp/libs-releases-local"
}
dependencies {
groovy group: 'org.codehaus.groovy', name: 'groovy-all', version: '1.8.4'
groovy group: 'org.mongodb', name: 'mongo-java-driver', version: '2.6.5'
groovy group: 'com.gmongo', name: 'gmongo', version: '0.9.1'
testCompile "org.spockframework:spock-core:0.5-groovy-1.8"
}
jar {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
below is the the HelloThere.groovy file located src/main/groovy/com/javazquez/HelloThere
package com.javazquez
public class HelloThere {
public static void main(String []args) {
println "Hello coders!"
}
}
after running gradle build, I can navigate to the build/libs directory and run java -jar HelloThere-1.0-20111115.jar and get the following ouptut
Hello coders!
Gradle is a fantastic tool and I hope this article helps show the ease of getting a project set up.
October 12th, 2011 — Groovy
I have been working with Activiti lately and needed to test the REST API included with the demo. Below are the GET and POST requests I whipped up using Groovy. Hope you find this useful
//---Get Request
@Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.0' )
import groovyx.net.http.RESTClient
def client = new RESTClient('http://localhost:8080/activiti-rest/service/process-engine')
println client.get(headers:[Authorization:"Basic ${'kermit:kermit'.bytes.encodeBase64()}"]).data
// output
[name:default, exception:null, version:5.7, resourceUrl:jar:file:/Users/juanvazquez/Documents/activiti-5.7/apps/apache-tomcat-6.0.32/webapps/activiti-rest/WEB-INF/lib/activiti-cfg.jar!/activiti.cfg.xml]
// POST request
@Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.0' )
import static groovyx.net.http.ContentType.JSON
def jsonObj = new groovy.json.JsonBuilder()
jsonObj{
userId 'kermit'
password 'kermit'
}
def client = new groovyx.net.http.RESTClient('http://localhost:8080/activiti-rest/service/login')
def response = client.post(contentType: JSON, body:jsonObj.toString() )
println response.data
//output
[success:true]
November 1st, 2010 — Administration, apache, code, Groovy, Uncategorized
Hey there fellow Groovyists! I was recently in need of performing Basic Authentication on Apache using Groovy for a proof of concept. Below is what I was able to quickly put together.
//Here is a quick groovy 1.7.4 Basic Auth Example
@Grab(group=’org.codehaus.groovy.modules.http-builder’, module=’http-builder’, version=’0.5.0′ )
def authSite = new groovyx.net.http.HTTPBuilder( ‘http://10.110.201.115/~juanvazquez/basicAuth/’ )
authSite.auth.basic ‘user’, ‘pwd’
println authSite.get( path:’testAuth.html’ )
April 18th, 2009 — code, Groovy, java, Windows
I find myself doing a lot of file parsing on my Windows XP machine lately. I decide to write a quick utility that would allow me to drag and drop files and search for the key words that I have identified. The utility doesn’t have the logic for searching using regex’s yet, but it should be really easy to add this functionality.
I hacked some Groovy Code with some Java Code and came up with the following script. Hope it is useful.
DISCLAIMER:
As the title suggests, I have only been able to get this to work on my Windows XP machine, OS X didn’t like the javax.swing.TransferHandler and it appears some other operating systems have a hard time with this also.
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.awt.BorderLayout;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.TransferHandler.*;
class FileDropHandler extends TransferHandler {
private static final long serialVersionUID = 1L;
def wordsToFind =[]
JTextArea output
private JLabel errorMsg;
private String fileText = "";
private boolean test = false;
private boolean same = true;
public boolean canImport(TransferSupport supp) {
/* for the demo, we'll only support drops (not clipboard paste) */
if (!supp.isDrop()) {
return false;
}
/* return false if the drop doesn't contain a list of files */
if (!supp.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
return false;
}
boolean copySupported = (COPY & supp.getSourceDropActions()) == COPY;
if (copySupported) {
supp.setDropAction(COPY);
return true;
}
return false;
}
public boolean importData(TransferSupport supp) {
if (!canImport(supp)) {
return false;
}
/* get the Transferable */
Transferable t = supp.getTransferable();
try {
Object data = t.getTransferData(DataFlavor.javaFileListFlavor);
List fileList = (List) data;
for (int j = 0; j < fileList.size(); j++) {
File file = (File) fileList.get(j);
//file.getAbsolutePath()
def tmpfh = new File("FileParser.txt")
println wordsToFind.inspect()
new File(file.getAbsolutePath()).eachLine{line->
wordsToFind.each{ if(line =~ "${it}" ){
println "${line}"
tmpfh.append(line)
tmpfh.append("\n\n")
this.output.setText(this.output.getText()+line+"\n")
}
}
}//end for
tmpfh.close()
}
} catch (UnsupportedFlavorException e) {
return false;
} catch (IOException e) {
return false;
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
public void setOutput(JTextArea jta) {
this.output = jta;
}
public void setOutput(JLabel jta) {
errorMsg = jta;
}
public String getText() {
return fileText;
}
public void clearAll() {
fileText = "";
test = false;
same = true;
}
}
class AL implements ActionListener{
public JTextField jtf
public FileDropHandler dh
public AL(JTextField jtf,FileDropHandler dh){
this.jtf = jtf
this.dh =dh
}
public void actionPerformed(ActionEvent actionEvent){
println "${this.jtf.getText()}"
dh.wordsToFind= this.jtf.getText().split(' ')
}
}
JTextArea dTextArea = new JTextArea("Drop on me");
FileDropHandler dh = new FileDropHandler()
dh.setOutput(dTextArea)
JTextField jta = new JTextField("Enter words seperated by spaces")
dh.wordsToFind= jta.getText().split(' ')
JButton jb =new JButton("Update Word List")
jb.addActionListener( new AL(jta ,dh ))
dh.setOutput(dTextArea);
dTextArea.setDragEnabled(true);
dTextArea.setTransferHandler(dh);
JPanel p =new JPanel(new BorderLayout());
JFrame f = new JFrame()
p.add(jta, BorderLayout.NORTH)
p.add(dTextArea, BorderLayout.CENTER)
p.add(jb, BorderLayout.SOUTH)
f.getContentPane().add(p)
f.setSize(400,400)
f.setVisible(true)
March 30th, 2009 — code, Groovy, java
A long time ago I wanted to write a desktop GUI interface for Flickr. At the time I had just learned Java and thought it would be really cool to write it using swing. Little did I know how not cool working with swing would be
About halfway through the project I heard about a cool new dynamic way to write Java code called Groovy. From that day on Groovy has been making my life a whole lot easier. I didn’t need all the functionality in the flickrj library, so I decide to write a few methods for my app using Groovy. The hardest part of the whole thing was figuring out how to post images to Flickr, for that, I used the flickrj code as a reference. If that source code was not available, I don’t think I would have ever figured it out. So a big thanks to all the folks working on that project!
This is not a complete API for Flickr, but should provide enough to get started.
Link to my GitHub Repo
January 24th, 2009 — code, Grails, Groovy
Here is a quick post on how to upload images within your Grails project to your file system(rather than your database). It seems simple enough, but I ran into a few snags as I was working on one of my projects. Just wanted to provided a working example for those that are entering the Grails territory for the first time. Happy Coding!
I am using the imageTools plugin which you can read more about here
NOTE: The imageTools plugin has been criticized for its low quality of output. ImageMagick may be a better fit for you project(s). My particular project didn’t call for high quality pictures. A quick google search for “imagemagick for grails” should get you started on your way.
I am using version 1.0.3 in the example below
to install, I ran the following command from my grails application’s root directory
grails install-plugin http://www.arquetipos.co.cr/blog/files/grails-image-tools-1.0.3.zip
Domain-Class
class Picture {
byte[] imagefile
//Any other stuff you want to track
}
Controller Code for Saving an image
def save = {
def downloadedfile = request.getFile('imagefile')
def pictureInstance = new Picture(params)
def imageTool = new ImageTool()
if(downloadedfile && pictureInstance.save()){
String imagepath = grailsAttributes.getApplicationContext().getResource("images/").getFile().toString() + File.separatorChar + "${pictureInstance.id}.jpg"
downloadedfile.transferTo(new File(imagepath))
imageTool.load(imagepath)
imageTool.thumbnail(140)
imageTool.writeResult(imagepath, "JPEG")
imageTool.square()
flash.message = "Picture ${pictureInstance.id} created"
redirect(action:show,id:pictureInstance.id)
}
else {
render(view:'create',model:[pictureInstance:pictureInstance])
}
}
Code for displaying the image in both the ‘show’ and ‘list’ views
<td><img src="${createLinkTo(dir:'images', file: pictureInstance.id+'.jpg' )}" /> </td>
January 3rd, 2009 — code, Erlang, Groovy, python, Ruby
The other day I was flipping through an algorithms book and came across a section on sorting. I remembered that I had a blast writing them c++ during my undergrad and thought it would be fun to write them in a couple of different languages. I settled on writing a quicksort, and mergesort.
Interesting notes:
1) Python(2.5) returns a None type when appending a value to an empty list which forced me to use ‘+’
>>> ex= [].append()
>>> print ex
>>>None
2) Groovy gave me a java.util.ConcurrentModificationException when I transcribed my Ruby code to Groovy. Because of the fact that I was deleting items from a list that I would read in later(while loop which checks size of left and right), I got this error. Accounting for that, the groovy code is pretty nasty.(anyone that would like to provide a better example without relying on the built in Collections.sort(list) would be welcome)
Here is my code… enjoy!
# javazquez.com
==========MERGE SORT========
-------------RUBY----------------
def merge_sort(ary)
return ary if (ary.length <= 1)
half = ary.length/2
left = merge_sort(ary[0...half])
right = merge_sort(ary[half..ary.length-1])
result =[]
#compare first left and first right
while left.length > 0 and right.length > 0
result << (left[0] < right[0] ? left.shift : right.shift)
end
result.concat((left.length > 0 ? left : right))
return result
end
ary=[1,5,14,3,2,45,2,0,01,-1]
p merge_sort(ary)
-----------Python Mergesort-------------
def merg_sort(lst):
if(len(lst) <= 1): return lst
left = merg_sort(lst[:len(lst)/2])
right = merg_sort(lst[len(lst)/2:len(lst)])
result = []
while len(left) > 0 and len(right)> 0:
if( left[0] > right[0]):
result.append(right.pop(0))
else:
result.append(left.pop(0))
if(len(left)>0): result.extend(merg_sort(left))
else: result.extend(merg_sort(right))
return result
print merg_sort([8,7,43,2,5])
--------Erlang Mergesort-------------
-module(mergesort).
-export([ms/1,msTestSuite/1]).
ms(Lst)->break(Lst).
break([]) -> [];
break([L]) -> [L];
break(List) ->
{Left, Right} = lists:split(length(List) div 2, List),
merge(break(Left),break(Right)).
merge(L, []) -> L;
merge([], R) -> R;
merge([Lh|Ltail],[Rh|Rtail])->
if
Lh < Rh -> [Lh | merge(Ltail,[Rh|Rtail])];
Lh >= Rh -> [Rh | merge(Rtail,[Lh|Ltail])]
end.
%to test, run mergesort:msTestSuite(run).
msTestSuite(run)->
[mstest1(run),mstest2(run),
mstest3(run),mstest4(run),
mstest5(run)].
mstest1(run)-> ms([3,2,1]).
mstest2(run)-> ms([3,3,3,1]).
mstest3(run)-> ms([]).
mstest4(run)-> ms([1]).
mstest5(run)-> ms([123,0,-1,23,2,34,5,678,7,5,8]).
-------------GROOVY MERGESORT--------
def ms(lst){
if(lst.size() <= 1){return lst}
def sz=lst.size()
int half = (int)(sz/2)
def l = lst [ 0 .. < half]
def r = lst [ half.. < sz]
def lft = ms(l)
def rht = ms(r)
def result = []
def rcnt = 0
def lcnt = 0
while( lcnt < lft.size() && rcnt < rht.size()){
if(lft[lcnt] < rht[rcnt]){
result += lft[lcnt++]
}
else{
result += rht[rcnt++]
}
}
if(lcnt < lft.size()){
result += ms(lft[lcnt..< lft.size()])
}
else{
result += ms(rht[rcnt..< rht.size()])
}
return result
}
sl=[3,88,5,3,2,1,-2,2]
println ms(sl)
# javazquez.com
========QUICKSORT========
-----RUBY----------------
def quick_sort(ary)
return ary if(ary.length <= 1)
greater,less = [],[]
pos = rand(ary.length)
pivot = ary[pos]
ary.delete_at(pos)
ary.each{|item|
(item < pivot) ? less << item :greater << item}
return (quick_sort(less) << pivot).concat(quick_sort(greater))
end
ary=[1,5,14,3,2,45,2,0,01,-1]
p quick_sort(ary)
----------Python Quicksort--------------
import random
def quickSort(lst):
if(len(lst) <= 1):return lst
greater = []
less = []
pivot = lst.pop(random.randint(0,len(lst)-1))
for item in lst:
if(item < pivot): less.append(item)
else: greater.append(item)
return quickSort(less)+[pivot]+quickSort(greater)
ary=[1,5,14,3,2,45,2,0,01,-1]
----------Erlang Quicksort--------------
-module(quicksort).
-export([qsort/1]).
qsort([]) ->[];
qsort([Pivot|T]) ->
lists:append( [qsort([X || X <- T, X < Pivot]),
[Pivot], qsort([X || X <- T, X >= Pivot]) ).
-------GROOVY QUICKSORT--------------
def quickSort(lst){
if(lst.size() <= 1){return lst}
def greater = []
def less = []
def pivot = lst.remove(new Random().nextInt(lst.size()))
lst.each{item->
if(item < pivot){ less.add(item)}
else{greater.add(item)}
}
return quickSort(less)+[pivot]+quickSort(greater)
}
print quickSort([1,5,14,3,2,45,2,0,01,-1])