Entries Tagged 'jvm' ↓

Add Map, Reduce, and Filter to Groovy with an Extension Module

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.

Groovy Invoke Dynamic Support

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

Clojure Soundex

In need of a quick program to force myself to dive in to clojure, I chose to implement a soundex program that I at one time had written in C++. It was a fun exercise to step back and look at how my thought process changed based on the language I used. Hope you find this useful.

 

;steps
;1 keep first letter
;2 replace consonants
;3 remove w and h
;4 two adjacent are same, letters with h or w separating are also the same
;5 remove vowels
;6 continue until 1 letter 3 nums
(use 'clojure.contrib.str-utils)

(defn trnsfrm[ word]
  (->>
    (re-gsub #"(?i)[fbvp]" "1" word)
    (re-gsub #"(?i)[cgjkqsxz]" "2" ,,) 
    (re-gsub #"(?i)[dt]" "3" ,,) 
    (re-gsub #"(?i)[l]" "4" ,,)
    (re-gsub #"(?i)[mn]" "5" ,,)
    (re-gsub #"(?i)[r]" "6" ,,)))

(defn replace-adjacent [word] 
  (->> (re-gsub  #"(?i)[wh]" "" word ) 
  	trnsfrm 
  	(re-gsub #"(?i)([a-z0-9])\1+" "$1" )))  	

(defn pad [word](subs (str word "0000") 0 4))  	

(defn do-soundex [word]
    (pad ( str (first word)(re-gsub #"[aeiouy]"  "" (subs (replace-adjacent word) 1)))))

Update Refactored version
Not quite happy with the above example, I decided to see if I could refactor my code. Below is what I came up with(4 less lines code).

(use 'clojure.contrib.str-utils)

(def re-map{ #"(?i)[fbvp]" "1",#"(?i)[cgjkqsxz]" "2",#"(?i)[dt]" "3",#"(?i)[l]" "4",#"(?i)[mn]" "5",#"(?i)[r]" "6" })

(defn trns [word] (map #(re-gsub (key %1) (val %1) word) re-map))

(defn pad [word](subs (str word "0000") 0 4))

(defn rm1 [word] (apply str(drop 1 word)))

(defn do-soundex [word]
    (pad(str (first word) (->>
        (re-gsub #"(?i)[^aeiou\d]" "" (apply str (apply interleave (trns word ))))
        (re-gsub #"(?i)([a-z\d])\1+" "$1" )
        rm1
        (re-gsub #"(?i)[a-z]" "" )))))

 

Now for the test cases

;;;Start test
(=(do-soundex  "Ashcroft") "A261")
(=(do-soundex  "Ashcraft") "A261")
(=(do-soundex  "Tymczak") "T522")
(=(do-soundex  "Pfister") "P236")
(=(do-soundex"lukaskiewicz")"l222")
(=(do-soundex"Rubin")"R150")
(=(do-soundex"Rupert")"R163")
(=(do-soundex"Robert")"R163")
(=(do-soundex "Vazquez")"V220")

;;;end test

Simple Groovy project using Gradle

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.

POP3 Gmail access with Clojure and JavaMail

I recently had the need to access gmail using Clojure. I used JavaMail to accomplish this via pop3. Below is some code that I wrote to help me get emails. Hope you find it useful Enjoy :)


(use '[clojure.contrib.duck-streams])
(def props (System/getProperties))
; Get the default Session object.
(def session (javax.mail.Session/getDefaultInstance props))

; Get a Store object that implements the specified protocol.
(def store (.getStore session "pop3s"))

;Connect to the current host using the specified username and password.
(.connect store "pop.gmail.com" "username@gmail.com" "password")

;Create a Folder object corresponding to the given name.
(def folder (. store getFolder "inbox"))

; Open the Folder.
(.open folder (javax.mail.Folder/READ_ONLY ))
; Get the messages from the server
(def messages (.getMessages folder))

(defn getFrom [message](javax.mail.internet.InternetAddress/toString (.getFrom message)))
(defn getReplyTo [message] (javax.mail.internet.InternetAddress/toString (.getReplyTo message)) )
(defn getSubject [message] (.getSubject message))

;print out the body of the message
(for [m messages] (read-lines(.getInputStream m)) )

;;;;;code for sending an email

(def props (System/getProperties))
(. props put "mail.smtp.host", "smtp.gmail.com")
(. props put "mail.smtp.port", "465")
(. props put "mail.smtp.auth", "true")
(. props put "mail.transport.protocol", "smtps")

(def session (javax.mail.Session/getDefaultInstance props nil))
(def msg (javax.mail.internet.MimeMessage. session))
(. msg setFrom (javax.mail.internet.InternetAddress. "sender@gmail.com"))
(. msg addRecipients javax.mail.Message$RecipientType/TO
"receiver@gmail.com")

(. msg setSubject "i am the subject")
(. msg setText "I am the body!!!")

(. msg setHeader "X-Mailer", "msgsend")
(. msg setSentDate (java.util.Date.))

; send the email
(def transport (. session getTransport))
(. transport connect "smtp.gmail.com" 465 "sender@gmail.com" "password")
(. transport sendMessage msg (. msg getRecipients javax.mail.Message$RecipientType/TO))
(. transport close)

Writing a PayPal SOAP client with Java 6

I have always been mystified on the inner workings of SOAP. That was until I learned about the “wsimport” utility that comes with Java 6. It makes the entire process very easy. Below is an example of writing a SOAP client for PayPal’s Sandbox. This code will execute the SetExpressCheckout API call.

Just enter the following on your command line to generate the com.javazquez package

wsimport -keep -XadditionalHeaders -Xnocompile -p com.javazquez http://www.sandbox.paypal.com/wsdl/PayPalSvc.wsdl

open your favorite java editor(I used eclipse) and add the package(“com.javazquez”..created in the above command) to your new project

next, write some code to test out the APIs

package com.javazquez;

import javax.xml.ws.Holder;
public class TestEC {

public static void main(String[] args) {
SetExpressCheckoutReq req = new SetExpressCheckoutReq();
SetExpressCheckoutRequestType reqType = new SetExpressCheckoutRequestType();
SetExpressCheckoutRequestDetailsType details = new SetExpressCheckoutRequestDetailsType();
AddressType addr = new AddressType();
addr.cityName = "omaha";
addr.street1 = "123 main";
addr.country = CountryCodeType.US;
addr.name = "joe tester";

details.address = addr;
details.orderTotal = new BasicAmountType();
details.orderTotal.currencyID = CurrencyCodeType.USD;
details.orderTotal.value = "1.00";
details.cancelURL = "http://javazquez.com/cancel";
details.returnURL = "http://javazquez.com/return";

reqType.setVersion("2.10");

reqType.setExpressCheckoutRequestDetails = details;
req.setSetExpressCheckoutRequest(reqType);

UserIdPasswordType user = new UserIdPasswordType();
user.username = "XXX";
user.password = "XXXX";
user.signature = "XXXX";

PayPalAPIInterfaceService pp = new PayPalAPIInterfaceService();
PayPalAPIAAInterface pinterface = pp.getPayPalAPIAA();
Holder security = new Holder(new CustomSecurityHeaderType());
security.value.setCredentials(user);
try{
SetExpressCheckoutResponseType resp = pinterface.setExpressCheckout(req, security);
System.out.println(resp.token);
System.out.println(resp.correlationID);
for(ErrorType msg: resp.errors){
System.out.println(msg.longMessage);
}
}
catch(Exception ex){
System.out.println(ex.getMessage());

}
}

}

(def Bonjour-Clojure “Welcome to functional programming”)

After the briefest of introductions to functional programming in college(a la Lisp) and dabbling with Scala, I took the functional plunge and started using Clojure recently. At this point, I have only written a couple of small programs and haven’t formed much of an opinion on where it stacks against my current favorite language at the moment(Groovy). This post will follow my usual getting started with a language snippets. I plan to write more entries as I get more familiar with the language. On to the code!


;binding
user=> (def Bonjour-Clojure “Welcome to functional programming”)
#’user/Bonjour-Clojure
user=> Bonjour-Clojure
“Welcome to functional programming”

;items in a list can be seperated via a comma or white space..
user=> (= [ 1 2 3] [1,2,3])
true

;count the number of consonants in a string
(defn count-consonants [string] (count ( re-seq #”[^aeiouAEIOU\s]” string )))
user=> (count-consonants “writing code is fun”)
10

;count the number of vowels in a string
(defn count-vowels [string] (count ( re-seq #”[aeiouAEIOU\s]” string )))
user=> (count-vowels “lukaskiewicz”)
5

;read a file into a list.. any suggestions on other ways are welcome :)
;usage (file-lines “string_path_to_file”) or to read a webpage ((file-lines “http://javazquez.com”)
(defn file-lines [file] (with-open [rdr (clojure.java.io/reader file)] ( set ( line-seq rdr))))

;view objects class
user=>(class “Im a string”)
java.lang.String

;length of string
user=>(count “I am 18 chars long”)
18

user=>(range 1 9)
(1 2 3 4 5 6 7 8 )

;repeat a digit
user=>(repeat 4 3)
(3 3 3 3)

;list comprehension
user=>(for [fruit ["apple" "orange" "grape"] ] (str fruit))
(“apple” “orange” “grape”)

;use map to create a new list… #() is a shortcut for an anonymous
user=>(map #(* 2 %1) [1 2 3 4])
(2 4 6 8 )

; also an anonymous function
user=> (map (fn [item](* 2 item)) [1 2 3 4])
(2 4 6 8 )

;simple fiter example on a list using odd?
user=> (filter odd? [1, 2,3,4,5])
(1 3 5)

;factorial using reduce
user=> (reduce * [1 2 3])
6

;if statement
user=> (if true (str “i am true”)(str “i am false”))
“i am true”