// "favor composition over inheritance" ~Effective Java class Parent { def getAll() { String resp = "" 2.times { resp += get(it) } return resp } def get(def i) { "get PARENT $i\n" } } class Child1 extends Parent { def get(def i) { "get CHILD $i\n" // is used by parent's getAll } } class Child2 { @Delegate Parent p = new Parent() // decorated Parent instance def get(def i) { "get CHILD $i\n" // not used by parent's getAll } } Parent c1 = new Child1() assert c1.getAll() == "get CHILD 0\nget CHILD 1\n" // calls child's get() assert c1.get(0) == "get CHILD 0\n" //Parent c2 = new Child2() // Child2 is not a Parent! Child2 c2 = new Child2() assert c2.getAll() == "get PARENT 0\nget PARENT 1\n" // calls parent's get() assert c2.get(0) == "get CHILD 0\n"
Thursday, November 15, 2012
@Delegate vs. Extends
Monday, November 5, 2012
DNS lookup - timed
int maxTimeout = 30000 int minTimeout = 15000 List domainList = [ 'gmail.com', 'google.co.uk', 'google.com', 'bbc.co.uk', 'cnn.com', 'java.oracle.com', 'facebook.com', 'twitter.com', 'oracle.com', 'zen.co.uk', 'java.net', 'www.scala-lang.org', 'plus.google.com', 'guardian.co.uk', 'linkedin.com', 'www.typesafe.com', 'www.yahoo.com', 'www.ibm.com', 'www.apache.org', 'www.adobe.com', 'www.microsoft.com', 'www.stackoverflow.com', 'www.apple.com', 'groovy.codehaus.org', 'java.oracle.com', 'www.telegraph.co.uk', 'www.jroller.com', 'www.dell.com', 'www.samsung.com', 'www.amazon.co.uk', 'docs.oracle.com', 'www.infoq.com', 'www.devoxx.com', 'www.qconlondon.com', 'www.smashingmagazine.com', 'en.wikipedia.com' ] int count = 1 while (true) { int idx = (int)( Math.random() * domainList.size ) println "[$count] nslookup ${domainList[idx]}" def process = "nslookup ${domainList[idx]}".execute() println "Found text ${process.text}" int sleepTime = (int)( minTimeout + Math.random() * ( maxTimeout - minTimeout)) Thread.sleep( sleepTime ); ++count }
Monday, October 29, 2012
Resolve an HTTP Redirect
// source: https://gist.github.com/3899754 def findRealUrl(url) { HttpURLConnection conn = url.openConnection() conn.followRedirects = false conn.requestMethod = 'HEAD' if(conn.responseCode in [301,302]) { if (conn.headerFields.'Location') { return findRealUrl(conn.headerFields.Location.first().toURL()) } else { throw new RuntimeException('Failed to follow redirect') } } return url }
Wednesday, August 1, 2012
match/when implemented with Groovy's GEP-3
//WOW! https://gist.github.com/3002724 // No commas def a = 'tim' def nocom = match( a ) { when 'dave' 'Hi Dave' when 'tim' 'Hi Tim' otherwise 'none of the above' } assert nocom == 'Hi Tim' // Commas a = 'William' def com = match( a ) { when 'dave', 'Hi Dave' when 'tim', 'Hi Tim' otherwise 'none of the above' } assert com == 'none of the above' // Lists (can't use commas) a = [1,3] def list = match( a ) { when [1,2] 'One and two' when [1,3] 'One and three' when [2,1] 'Two and one' } assert list == 'One and three' // Wildcard Lists (can't use commas) a = [1,2,3] def wild = match( a ) { when [1,3,2] 'One, three and two' when [1,_] 'One and something' when [1,_,3] 'One, something and three' when [1,_,_] 'One, something and something' otherwise 'Something else' } assert wild == 'One, something and three' // Closures as the when/results String toRoman( int num ) { match( num ) { when { it >= 100 } { "C" + toRoman( num - 100 ) } when { it >= 90 } { "XC" + toRoman( num - 90 ) } when { it >= 50 } { "L" + toRoman( num - 50 ) } when { it >= 40 } { "XL" + toRoman( num - 40 ) } when { it >= 10 } { "X" + toRoman( num - 10 ) } when { it >= 9 } { "IX" + toRoman( num - 9 ) } when { it >= 5 } { "V" + toRoman( num - 5 ) } when { it >= 4 } { "IV" + toRoman( num - 4 ) } when { it >= 1 } { "I" + toRoman( num - 1 ) } otherwise "" } } assert "I" == toRoman( 1 ) assert "II" == toRoman( 2 ) assert "IV" == toRoman( 4 ) assert "V" == toRoman( 5 ) assert "VI" == toRoman( 6 ) assert "IX" == toRoman( 9 ) assert "X" == toRoman( 10 ) assert "XVII" == toRoman( 17 ) assert "XXXVIII" == toRoman( 38 ) assert "CCCXCIX" == toRoman( 399 ) /////////////////////////// // Implementation below... def match( v, c ) { new Matcher( var:v, closure:c ).match() } class Matcher { def var Closure closure Listcases = [] Otherwise otherwise def propertyMissing( name ) { if( name == '_' ) { new Any() } else { def w = new When() cases << w w } } def when( condition ) { cases << new When( condition:condition ) } def when( condition, result ) { cases << new When( condition:condition, result:result ) } def otherwise( result ) { this.otherwise = new Otherwise( result:result ) } public match() { closure.delegate = this closure.resolveStrategy = Closure.DELEGATE_ONLY closure() def ret = cases.find { it.condition instanceof Closure ? it.condition( var ) : it.condition == var }?.result ?: otherwise?.result ret instanceof Closure ? ret() : ret } } class When { def condition def result def getAt( List a ) { condition = a ; this } def call( result ) { this.result = result } def propertyMissing( String result ) { this.result = result } } class Otherwise { def result } class Any { boolean equals( other ) { true } } println 'DONE'
Sunday, July 15, 2012
GPars DataflowQueues
//source: http://jaxenter.com/tutorial-gpars-making-parallel-systems-groovy-and-java-friendly-43529-2.html //a sample code build process // //source: http://jaxenter.com/tutorial-gpars-making-parallel-systems-groovy-and-java-friendly-43529-2.html //a sample code build process // import static groovyx.gpars.dataflow.Dataflow.operator import groovyx.gpars.dataflow.* def _checkout = { String a -> Thread.sleep( (Long)Math.random() * 5 ); // a bit of random delay for fun println ">checking out...$a" return "checkout-$a" } def _compileSources = { a -> println ">compiling...$a" return "compileSources-$a" } def _generateAPIDoc = { a -> println ">api Docs...$a" return "generateAPIDoc-$a" } def _generateUserDocumentation = { a -> println ">user Docs...$a" return "generateUserDocumentation-$a" } def _packageProject = { project, api, doc -> println ">packaging...$project $api $doc" return "packageProject-$project $api $doc" } def _deploy = { a -> println ">deploying...$a" return (!!Math.round(Math.random())) } /* We need a Broadcaster and Queues to wire elements together */ def checkedOutProjects_B = new DataflowBroadcast() def urls_Q = new DataflowQueue() def compiledProjects_Q = new DataflowQueue() def apiDocs_Q = new DataflowQueue() def userDocs_Q = new DataflowQueue() def packages_Q = new DataflowQueue() def done_Q = new DataflowQueue() /* Here's the composition of individual build steps into a process */ operator(inputs: [urls_Q], outputs: [checkedOutProjects_B], maxForks: 3) { url -> bindAllOutputs _checkout(url) } operator([checkedOutProjects_B.createReadChannel()], [compiledProjects_Q]) { projectRoot -> bindOutput _compileSources(projectRoot) } operator(checkedOutProjects_B.createReadChannel(), apiDocs_Q) { projectRoot -> bindOutput _generateAPIDoc(projectRoot) } operator(checkedOutProjects_B.createReadChannel(), userDocs_Q) { projectRoot -> bindOutput _generateUserDocumentation(projectRoot) } operator([compiledProjects_Q, apiDocs_Q, userDocs_Q], [packages_Q]) { project, api, doc -> bindOutput _packageProject(project, api, doc) } def deployer = operator(packages_Q, done_Q) { packagedProject -> boolean ok = _deploy(packagedProject) println "! Deployed? $ok" bindOutput (ok) } /* add data, start the machine a rollin! */ 5.times { urls_Q << "url #$it" } 5.times { urls_Q << "url #${++it*5}" } /* Now we're set up, and can just wait for the build to finish */ println "==Starting the build process. This line MIGHT NOT be printed out first ...==" //deployer.join() //Wait for the last operator in the network to finish??
Thursday, July 12, 2012
GBench - easy code benchmarking
//source: http://nagaimasato.blogspot.jp/2012/07/gbench-031-released.html //requires Groovy 2.0.0+ @Grab('com.googlecode.gbench:gbench:0.3.1-groovy-2.0') import gbench.BenchmarkBuilder import groovy.transform.CompileStatic int fib(int n) { if (n < 2) return n return fib(n - 1) + fib(n - 2) } @CompileStatic int fib2(int n) { if (n < 2) return n return fib2(n - 1) + fib2(n - 2) } new BenchmarkBuilder().run { int n = 20 "Normal Version" { fib n } "@CompileStatic Version" { fib2 n } }.prettyPrint()
Wednesday, July 11, 2012
Conceptual Map/Reduce Example
//inspiration: http://hamletdarcy.blogspot.ca/2008/01/mapreduce-for-mere-mortals.html // general purpose function def mapReduceFunc = { data, mapFunction, reduceFunction -> def mappedData = data.collect(mapFunction) reduceFunction(mappedData) } // the data Map dictionary = [ abacus: "a device for making arithmetic calculations", arc: "any unbroken part of the circumference of a circle", beaver: "a large, amphibious rodent of the genus Castor" ] // the mapping function impl def startingCharacter = { pair -> pair.value = pair.key[0].toLowerCase() return pair } // the reducing function impl def countCharacters = { dataMap -> Map result = [:] ('a'..'z').each{ result[it] = 0 } dataMap.each { pair -> result[pair.value]++ } return result } // put it all together! def result1 = mapReduceFunc(dictionary, startingCharacter, countCharacters) println result1 //// TWEAK THE I/O FUNCS! //// // the mapping function impl startingCharacter = { pair -> return pair.key[0].toLowerCase() } // the reducing function impl countCharacters = { dataList -> Map result = [:] ('a'..'z').each{ result[it] = 0 } dataList.each { it -> result[it]++ } return result } // put it all together! def result2 = mapReduceFunc(dictionary, startingCharacter, countCharacters) println result2 assert result1 == result2
Saturday, June 23, 2012
MockFor
//http://groovy.codehaus.org/Using+MockFor+and+StubFor import groovy.mock.interceptor.* /*sample data class*/ class Movie { // Lots of expensive method calls, etc. } /*helper class*/ class MovieAnalyzer { def isGood( movie ) { if( movie.hasGalifinakis() ) return true; else if( movie.hasSparklyVampires() ) return false; return ( new Date().getTime() / 2 ) == 0 } } /*unit test the helper class by mocking the data class*/ def testTwitlightMovie(){ def mock = new MockFor(Movie) //StubFor is similar to MockFor except that //the expectaion of methods called is order independent ... mock.demand.hasGalifinakis { true } mock.demand.hasSparklyVampires( 0..1 ) { true } // demand the method 0 or 1 times mock.use { assert true == new MovieAnalyzer().isGood( new Movie() ) } } testTwitlightMovie()
Tuesday, May 22, 2012
Quartz Job Scheduler
//a better Groovy DSL example: https://gist.github.com/1505600 //Note: a simple timer implementation with runAfter(): http://mrhaki.blogspot.ca/2009/11/groovy-goodness-run-code-at-specified.html @Grapes( @Grab(group='org.quartz-scheduler', module='quartz', version='2.1.5') ) import org.quartz.* import org.quartz.impl.* import static org.quartz.JobBuilder.* import static org.quartz.TriggerBuilder.* import static org.quartz.SimpleScheduleBuilder.* class HelloJob implements Job { public void execute(JobExecutionContext context) { println "Hello "+(new Date().getTime()) } } try { // Grab the Scheduler instance from the Factory Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler() // Start it! scheduler.start() JobDetail job = newJob(HelloJob) .withIdentity("myJob"+(new Date().getTime()), "group1") .build() Trigger trigger = newTrigger() .withIdentity(new TriggerKey("myTrigger"+(new Date().getTime()), "group1")) .withSchedule(simpleSchedule() .withIntervalInSeconds(5) .repeatForever()) .startNow() .build() // Tell quartz to schedule the job using our trigger scheduler.scheduleJob(job, trigger) // Pause thread for 60 seconds Thread.sleep(60000) // End it! scheduler.shutdown() } catch (SchedulerException se) { se.printStackTrace() }
Beep Sound
java.awt.Toolkit.getDefaultToolkit().beep() // doesn't always work println ("\007"*3) //3 beeps
Tuesday, April 24, 2012
self-referenced tree, in one line!
//source: https://gist.github.com/2478499 def tree = { [:].withDefault{ owner.call() } } // ta-da! users = tree() users.harold.username = 'hrldcpr' users.yates.username = 'tim' users.with { al.username = 'al1' derek.username = 'skinnyk1d' frier.with { username = 'great1' password = 'changeme1' updatedOn = '4/26/2012' } bob.with { age = 4 isOld = false } } println new groovy.json.JsonBuilder( users ).toPrettyString()
CodeNarc bundle
Simple starter zip file for running CodeNarc (groovy static analysis) 0.17 inside a local groovy source code folder. (Windows .bat file) Generates html report page.
Wednesday, March 28, 2012
JRegex
@Grapes( @Grab(group='net.sourceforge.jregex', module='jregex', version='1.2_01') ) import jregex.* //http://jregex.sourceforge.net/gstarted-advanced.html#imatching String userNameChars="[\\w.\\-]+" //letters, dots, hyphens String alphaNums="\\w+" String dot="\\." Pattern email=new Pattern(userNameChars + "@" + "(?:"+ alphaNums + dot + ")*" + alphaNums) List ls = ['s@1.com','2@3.com','howdy@d.'] ls.each { println email.matcher(it).matches() } Pattern re=new Pattern("\\d\\d:\\d\\d") //two digits + colon + two digits println("Pattern: "+re) Matcher m=re.matcher() test(m,"") // true test(m,"1") // true test(m,"12") // true test(m,"1:2") // true test(m,"12:") // true test(m,"12:1") // true test(m,"12:12") // true test(m,"12:123") // true test(m,"1:") // false test(m,"123:1") // false void test(Matcher m1, String s) { m1.setTarget(s) println("\""+s+"\" : "+m1.matchesPrefix()) //note: .matchesPrefix() } ////*Pure Java/Groovy*//// //credit: http://glaforge.appspot.com/article/incomplete-string-regex-matching List inp = [ /12:/,/12:1/,/1/,/12:12/ //trues ,/1:/,/123:1/ //falses ] inp.each { def matcher = it =~ /\d{2}:\d{2}/ println matcher.matches() || matcher.hitEnd() } println 'done'
Sunday, March 4, 2012
Thread Pools
import java.util.concurrent.Callable import java.util.concurrent.Executors long ts // timer def pool = Executors.newFixedThreadPool(THREADS) def defer = { c -> pool.submit(c as Callable) } //PLAIN////////////////////////////////////////// ts = (new Date().time) doit = { n -> def left = { def slp = Math.random()*n*1000+500l as Long; Thread.sleep(slp); println Thread.currentThread().name + '!!left!!'+slp }() def right = { def slp = Math.random()*n*1000+500l as Long; Thread.sleep(slp); println Thread.currentThread().name + '!!right!!'+slp }() } (1..3).each{ n -> println "n=$n => ${doit(n)}" } println ((new Date().time)-ts) //POOLED////////////////////////////////////////////// ts = (new Date().time) THREADS = 3 fib = { n -> def left = defer{ def slp = Math.random()*n*1000+500l as Long; Thread.sleep(slp); println Thread.currentThread().name + '!!left!!'+slp } def right = defer{ def slp = Math.random()*n*1000+500l as Long; Thread.sleep(slp); println Thread.currentThread().name + '!!right!!'+slp } } (1..3).each{ n -> println "n=$n => ${fib(n)}" } pool.shutdown() while(!pool.isTerminated()) { Thread.sleep(100) } println ((new Date().time)-ts) //FIB////////////////////////////////////////////////// println "Calculating Fibonacci sequence in parallel..." CUTOFF = 12 // not worth parallelizing for small n THREADS = 10 serialFib = { n -> (n < 2) ? n : serialFib(n-1) + serialFib(n-2) } fib = { n -> if (n < CUTOFF) return serialFib(n) def left = defer{ println Thread.currentThread().name; fib(n-1) } def right = defer{ println Thread.currentThread().name; fib(n-2) } left.get() + right.get() } (11..16).each{ n -> println "n=$n => ${fib(n)}" } pool.shutdown()
Thursday, March 1, 2012
Jetty server
//src: http://www.redtoad.ca/ataylor/2012/02/simple-servlets-in-groovy/ @Grab(group='org.mortbay.jetty', module='jetty-embedded', version='6.1.26') import org.mortbay.jetty.Server import org.mortbay.jetty.servlet.* import groovy.servlet.*; import javax.servlet.http.*; import javax.servlet.ServletConfig; class SimpleGroovyServlet extends HttpServlet { def requestHandler def context void init(ServletConfig config) { super.init(config) context = config.servletContext } void service(HttpServletRequest request, HttpServletResponse response) { requestHandler.binding = new ServletBinding(request, response, context) use (ServletCategory) { requestHandler.call() } } static void run(int port, Closure requestHandler) { def servlet = new SimpleGroovyServlet(requestHandler: requestHandler) def jetty = new Server(port) def context = new Context(jetty, '/', Context.SESSIONS) context.addServlet(new ServletHolder(servlet), '/*') jetty.start() } } SimpleGroovyServlet.run(8080) { -> response.contentType = 'text/plain' println "hello world!" println "my path is ${request.pathInfo}" println "my params are $params" } //also try: groovy -l 8080 -e "println 'hello world'" //alternate: https://github.com/groovypp/gretty/wiki/Getting-Started
Wednesday, February 29, 2012
collate
//src: http://blog.bloidonia.com/post/18073244930/whats-new-in-groovy-1-8-6-the-collate-method //v1.8.6+// def list = 1..10 def listInFours = list.collate( 4 ) assert listInFours == [ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ], [ 9, 10 ] ] def listInFours2 = list.collate( 4, false ) // Notice the [ 9, 10 ] remainder has been dropped assert listInFours2 == [ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ] ] def gridList = list.collate( 3 ).collate( 2 ) assert gridList == [ [ [1, 2, 3], [4, 5, 6] ], [ [7, 8, 9], [10] ] ] def mph = [ 10, 26, 30, 32, 27, 14, 19, 22, 40, 14 ] def window = mph.collate( 3, 1, false ) assert window == [ [10, 26, 30], [26, 30, 32], [30, 32, 27], [32, 27, 14], [27, 14, 19], [14, 19, 22], [19, 22, 40], [22, 40, 14] ] def windowAvg = window*.sum()*.intdiv( 3 ) assert windowAvg == [22, 29, 29, 24, 20, 18, 27, 25] def items = [ 'ham', 30, 'cheese', 20, 'steak', 95 ] def itemMap = items.collate( 2 ).collectEntries() assert itemMap == [ ham:30, cheese:20, steak:95 ] def range = 1..20 def (odds,evens) = range.collate( 2 ).transpose() assert odds == (1..19).step( 2 ) // odd numbers 1 - 19 assert evens == (2..20).step( 2 ) // even numbers 2 - 20
Monday, February 27, 2012
Regex look-ahead/behind syntax
//http://groovy.codehaus.org/Regular+Expressions def r = /e+/ def str = 'me cheese please' def m = str =~ r assert m.size() == 5 println m*.toString() //[e, ee, e, e, e] ///////////////////////////// def r = /(This boy) is/ def str = 'This boy is 10. This boy wants chocolate. This boy is tall.' def m = str =~ r assert m.size() == 2 assert m.collect { it[1] } == ['This boy','This boy'] ///////////////////////////// assert "abc".replaceAll(/(a)(b)(c)/, "\$1\$3") == 'ac' //back references ///////////////////////////// //http://www.regular-expressions.info/captureall.html r = /((?:abc|123)+).*?/ str = '123abc 123abc123' m = str =~ r assert m.size() == 2 println m*.toString() print m[0][1..-1] println m[1][1..-1] ///////////////////////////// //password of 8 characters long and two non-letters def r1 = /.*[^a-zA-Z].*[^a-zA-Z].*(?<=.{7})/ //look-behind ?<= assert 'abc' !=~ r1 assert 'abcde12' !=~ r1 assert 'abcdef12' ==~ r1 assert 'abc1defgggg2' ==~ r1 assert 'abc1defgggg' !=~ r1 //word is foo$wrd*, store $wrd* def wrd = 'bar' def r2 = /foo((?=$wrd)[\w]+)/ //look-ahead ?= def foo = "foo${wrd}hellow" assert foo ==~ r2 def m = foo =~ r2 assert m[0][1] == "${wrd}hellow" // note: $wrd not consumed by check, is stored in result foo = 'foohellow' // no $wrd assert foo !=~ r2 //ADVANCED///////////////////////////// def churnText(String text) { def points = [[k: ~/(N|n)orth(E|e)ast(ern)?/ , v:'NE'], [k: ~/(?>(N|n)orth(W|w)est(ern|:)?)(?! Territories)/ , v:'NW'], [k: ~/(S|s)outheast(ern)?/ , v:'SE'], [k: ~/(?>(S|s)outh(\s)?(W|w)est(ern)?)(?! Hill| Bend)/ , v:'SW'], [k: ~/(?>(N|n)orth(ern)?|Upstate)(?! Carolina| Dakota| Platte| Neck| Mariana Islands| Bay|ridge)/ , v:'N' ], [k: ~/(E|e)ast(ern)?/ , v:'E' ], [k: ~/(?>(S|s)outh(ern|side)?)(?! Carolina| Dakota)/ , v:'S' ], [k: ~/(?!(?<=George ))(?>(W|w)est(ern| of the)?)(?! Virginia| Palm Beach)/ , v:'W' ], [k: ~/(?>(C|c)entral|Center|Middle|the middle section of the)(?!town| Peninsula| Tennessee|ia)/ , v:'C' ]] points.each {p -> def matcher = (text =~ p.k) text = matcher.replaceAll(p.v) println "p.v: ${p.v} text: $text" } } churnText('Northwest Virginia') println '='*40 churnText('NorthWestern Territories') println '='*40 churnText('East George West') return
Thursday, February 23, 2012
Swing Notification Popup
//see: http://groovy.codehaus.org/GUI+Programming+with+Groovy import groovy.swing.* import java.awt.* import javax.swing.* import javax.swing.border.* import groovy.util.slurpersupport.NodeChild as Node public class Notify { def sb = new SwingBuilder() public static void main(String[] args) { // creates and displays itself new Notify(args) } public Notify(String[] args){ // arg is path to xml message file, // will be deleted after popup displayed if (args.size() != 1) return String appTitle = ".:. Notification .:." String filePath = args[0] Color backgroundColor = Color.yellow Border emptyBorder = BorderFactory.createMatteBorder(5, 5, 5, 5, backgroundColor) Toolkit tk = Toolkit.getDefaultToolkit() Dimension screenSize = tk.getScreenSize() final int WIDTH = screenSize.width final int HEIGHT = screenSize.height int w = WIDTH / 2 int h = HEIGHT / 2 int x = (WIDTH / 2) - (w / 2) int y = (HEIGHT / 2) - (h / 2) - 50 Font fontSubject = new Font("Serif", Font.PLAIN, 24) Font fontMessage = new Font("Serif", Font.PLAIN, 16) //generate frame// sb.dialog(id:"popupBox", title:appTitle, visible:true, alwaysOnTop:true, defaultCloseOperation:JFrame.DISPOSE_ON_CLOSE, resizable:false, location:[x, y], size:[w, h]) { borderLayout() label(id:"subject", constraints:BorderLayout.NORTH, horizontalAlignment:JTextField.CENTER, font:fontSubject, "SUBJ") panel(constraints:BorderLayout.CENTER){ gridLayout(cols:1, rows:1, hgap:1, vgap:1) scrollPane(border:emptyBorder) { textArea(id:"message", editable:false, lineWrap:true, wrapStyleWord:true, font:fontMessage, "MESG") } } } def frame = sb.popupBox //decorate frame color// def cp = frame.contentPane cp.background = backgroundColor sb.message.background = cp.background //populate frame data// File xmlFile Node root try { xmlFile = new File(filePath) root = new XmlSlurper().parse(xmlFile) //println root.getClass().name } catch (Exception) { xmlFile = new File("") root = new XmlSlurper().parseText('''''') } sb.subject.text = root.subject.text() // if not found, subject UI label is hidden sb.message.text = root.message.text() ? root.message.text().replaceAll('\\\\n', System.getProperty( "line.separator" )) : 'Sorry, empty notification.' //display form// frame.show() try { xmlFile.delete() } catch (Exception ignore) {} } } Error Sorry, file path or XML syntax error.
Thursday, February 16, 2012
Shell/Command line execution
//def cmd = "cmd /C dir" def cmd = ["cmd","/C","dir g*.bat"] // more flexible format //Groovyish Java// Runtime r = Runtime.runtime Process p = r.exec(cmd.toArray(new String())) BufferedReader inp = new BufferedReader(new InputStreamReader(p.getInputStream())) while (line = inp.readLine()) { println line } //Groovy!// println cmd.execute().text
Friday, February 10, 2012
Colt - Random Number Generators
/* * see: http://acs.lbl.gov/software/colt/ */ @Grapes( @Grab(group='colt', module='colt', version='1.2.0') ) import cern.jet.random.* println Binomial.staticNextInt(500,0.5d) println ChiSquare.staticNextDouble(10.0d) println Exponential.staticNextDouble(1.0d) println ExponentialPower.staticNextDouble(1.0d) println Normal.staticNextDouble(10.0d,1.0d) println Poisson.staticNextInt(100.0d) println Uniform.staticNextDoubleFromTo(1.0d,100.0d) println VonMises.staticNextDouble(10.0d)
Apache Commons Collections
@Grapes( @Grab(group='commons-collections', module='commons-collections', version='3.2.1') ) import org.apache.commons.collections.* import org.apache.commons.collections.map.* import org.apache.commons.collections.bidimap.* IterableMap map1 = [a:1, b:2] as HashedMap map1.each { print it.key println it.value } OrderedMap map = new LinkedMap() map.with { put("FIVE", "5") put("SIX", "6") put("SEVEN", "7") assert firstKey() == "FIVE" assert nextKey("FIVE") == "SIX" assert nextKey("SIX") == "SEVEN" } BidiMap bidi = new TreeBidiMap() bidi.with { put("SIX", "6") assert get("SIX") == "6" assert get("SIX") == "6" assert getKey("6") == "SIX" removeValue("6") assert getKey("SIX") == null put("ONE", "1") } BidiMap inverse = bidi.inverseBidiMap() // returns a map with keys and values swapped assert inverse.getKey("ONE") == "1" Buffer buffer = new UnboundedFifoBuffer() buffer.with { add("ONE") add("TWO") add("THREE") assert remove() == "ONE" assert remove() == "TWO" } Bag bag = new HashBag() bag.with { add("ONE", 6) // add 6 copies of "ONE" remove("ONE", 2) // removes 2 copies of "ONE" assert getCount("ONE") == 4 }
Trove - high speed regular and primitive collections
/* * see: http://trove.starlight-systems.com/ */ @Grapes( @Grab(group='net.sf.trove4j', module='trove4j', version='3.0.2') ) import gnu.trove.set.* import gnu.trove.set.hash.* import gnu.trove.list.* import gnu.trove.list.array.* import gnu.trove.list.linked.* import gnu.trove.map.* import gnu.trove.map.hash.* //Most Trove classes start with the letter "T" to indicate that they're part of the Trove library. THashSet s = new THashSet() 100.times { i -> s.add ((i / 2).toInteger()) } assert s.size() == 50 assert s.contains(0) TIntArrayList a = new TIntArrayList() 100.times { i -> a.add ((i / 3).toInteger()) } assert a.size() == 100 assert a.get(0) == 0 TIntLinkedList l = new TLinkedList() 100.times { i -> l.add ((i / 4).toInteger()) } assert l.size() == 100 assert l.get(0) == 0 THashMap m = new THashMap() m['a'] = 1 m.b = 2 assert m.a == 1
Thursday, February 9, 2012
Google Guava
/* * see: http://code.google.com/p/guava-libraries/ * grails caching idea: http://refactr.com/blog/2012/05/grails-in-memory-cache-using-googles-guava-library/ */ @Grapes([ @Grab("com.google.guava:guava:14.0.1") ]) import java.util.concurrent.TimeUnit import com.google.common.primitives.Ints import com.google.common.collect.Iterables import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableMap import com.google.common.hash.Hashing import com.google.common.cache.Cache import com.google.common.cache.CacheBuilder import com.google.common.cache.CacheLoader List list = [1,2,3,3] assert Iterables.frequency(list, 2) == 1 assert Iterables.frequency(list, 3) == 2 String temp = "test" md5 = Hashing.md5() String hash = md5.newHasher().putBytes(temp as byte[]).hash() assert hash != temp assert hash == "098f6bcd4621d373cade4e832627b4f6" ImmutableList of = ImmutableList.of("a", "b", "c", "d"); // Same one for map ImmutableMap map = ImmutableMap.of("key1", "value1", "key2", "value2"); //list of ints List theList = Ints.asList(1, 2, 3, 4, 522, 5, 6); //see: https://code.google.com/p/guava-libraries/wiki/CachesExplained Cache cache = CacheBuilder.newBuilder() .weakKeys() .maximumSize(10000) .expireAfterWrite(10, TimeUnit.MINUTES) .build( new CacheLoader() { @Override public String load(Integer key) throws Exception { return retreveStringForKey(key); } @Override public Object load(Object o) { return o; } //??? }); cache.metaClass.propertyMissing { k -> delegate.get(k) } cache.metaClass.propertyMissing { k, v -> delegate.put(k, v) } cache["a"] = 9 assert cache.size() == 1 assert cache["a"] == 9
Wednesday, February 8, 2012
Java2Html
@Grapes(
@Grab(group='de.java2html', module='java2html', version='5.0')
)
import de.java2html.*;
import de.java2html.options.*;
String javaText = '''
/**
* This is about ClassName
.
* {@link com.yourCompany.aPackage.SuperClass}
* @author author
*/
public class ClassName extends SuperClass {
/* This comment may span multiple lines. */
private int integer = 0;
public final static char character = 'A';
// This comment may span only this line
private String string = "zero";
}
'''
JavaSourceConversionSettings conversionOptions = new JavaSourceConversionSettings(new JavaSourceConversionOptions());
String htmlText = Java2Html.convertToHtmlPage(javaText, conversionOptions);
println (htmlText)
Tuesday, February 7, 2012
Geb Web Test
//updated Jan 12 2013 //check out Geb/Phantomjs integration via RemoteWebDriver support! @Grapes([ @Grab("junit:junit-dep:4.8.2"), @Grab("org.codehaus.geb:geb-junit4:0.7.2"), //soon to go 0.9.0 @Grab("org.seleniumhq.selenium:selenium-firefox-driver:2.28.0"), @Grab("org.seleniumhq.selenium:selenium-remote-driver:2.28.0"), @Grab("org.seleniumhq.selenium:selenium-support:2.28.0") ]) import geb.* import geb.driver.CachingDriverFactory import org.openqa.selenium.* import org.openqa.selenium.remote.* //import org.openqa.selenium.firefox.FirefoxProfile //import org.openqa.selenium.firefox.FirefoxDriver //import java.awt.Robot // see http://docs.oracle.com/javase/7/docs/api/java/awt/Robot.html#createScreenCapture(java.awt.Rectangle) def cachedDriver = CachingDriverFactory.clearCacheAndQuitDriver() // clean-up old window & driver if any :) File path = new File("C:\\geb-test\\") path.mkdirs() String searchFor = "dogs" // or null = off String downloadImgURL = 'http://freemailtemplates.com/wp-content/themes/psdfiles-freemailtemplates/images/download-button.png' // or null = off String downloadImgPathFile = path.absolutePath+'\\pic.png' String screenshotURL = 'http://www.yahoo.com' // or null = off String screenshotPathFile = path.absolutePath+'\\screenshot.png' // NOTE: these two webdrivers ONLY init'ed for the URL page screenshots (which need a headless/remote browser like phantomjs) // // you could probably just go to the URL and generate a report, too...? // final RemoteWebDriver rdriver final WebDriver augmentedDriver if (screenshotURL) { try { rdriver = new RemoteWebDriver( "http://localhost:9134".toURL(), DesiredCapabilities.firefox() ) augmentedDriver = new Augmenter().augment(rdriver) } catch (Exception e) { screenshotURL = null } } // NOTE: config ONLY init'ed for reporting purposes // def config = new Browser().getConfig() // steal a default config(??) config.reportsDir = path try{ Browser.drive(config) { if (searchFor) { go "http://www.google.ca/" assert title.contains("Google") // basic searching/reading/etc //////////////////////////////////////////// def inputs = $("input, button") assert inputs.size() > 2 inputs.each { println ":"+it.value() } // try a real Google search! //////////////////////////////////////////// def textSearch = $("form[action='/search'] input[type='text']") assert textSearch.size() == 1 textSearch.value( searchFor ) def buttonSearch = waitFor { $("input[type='button'], button") }.findAll{ it.text().toLowerCase().contains("search") } if (buttonSearch.size() == 0) // try another DOM node search // buttonSearch = waitFor { $("input[type='button']#gbqfb, button#gbqfb", 0) } assert buttonSearch.size() == 1 buttonSearch.click() def items = waitFor { $("li.g") } // show the first item's text println items[0].text() def imgs = $("img") def srcs = imgs*.@src srcs.each { src -> // show the img sources println "img: " + (src ?: 'n/a') } } // try another page! //////////////////////////////////////////// go "http://cnn.com" assert title.contains("CNN.com") println ">>>" + title // try to dump the page's HTML and screenshot! //////////////////////////////////////////// reportGroup "cnn" report "homepage" // try to inject jQuery into the page! //////////////////////////////////////////// injectLibrary(js, 'http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js') //////////////////////////////////////////// js."jQuery.noConflict"() // try to grab the body's raw HTML! //////////////////////////////////////////// String body = ''+js."document.body.innerHTML"+'' // try a URL file download! //////////////////////////////////////////// if (downloadImgURL) { try { downloadFile(browser, downloadImgURL, downloadImgPathFile) } catch (Exception e) { println "[ERROR] downloading: ${e.message}\n${e.printStackTrace()}" } } // try a URL page screenshot! //////////////////////////////////////////// if (screenshotURL) { try { screenshot(augmentedDriver, screenshotURL, screenshotPathFile) } catch(Exception e) { println "[ERROR] screenshot: ${e.message}\n${e.printStackTrace()}" } } println '==Done==' //close() // close window, not neccesary with CachingDriverFactory.clearCacheAndQuitDriver() //quit() // quit window, not neccesary with CachingDriverFactory.clearCacheAndQuitDriver() } cachedDriver = CachingDriverFactory.clearCacheAndQuitDriver() // clean-up window & driver if successful :) } catch(Exception e) { println "[ERROR] Please try again: ${e.message}" } //==END MAIN==// //these util methods all get their context object passed in as a final// def downloadFile(final Browser browser, String downloadImgURL, String downloadImgPathFile) { input = browser.downloadStream(downloadImgURL) // geb function output = new BufferedOutputStream(new FileOutputStream(downloadImgPathFile)) output << input } def screenshot(final WebDriver driver, String url, String filename) { /********************************************************* * Note: you need a headless/remote web server running (like phantomjs) * - beware, this doesn't seem to like HTTP redirects *********************************************************/ driver.get(url) final File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE) scrFile.renameTo(filename ?: 'screenshot.png') } def injectLibrary(final js, String library){ if (!js."document.body.innerHTML".contains(library)) js.exec("document.body.appendChild(document.createElement('script')).src='$library'"); //assert js."document.body.innerHTML".contains(library) }
Thursday, January 26, 2012
Simple SHA Digest/Hash
import java.security.* makeDigest = {String msg, int loops = 1, long t1 = (new Date()).getTime(), double q1 = Math.random() -> MessageDigest md = MessageDigest.getInstance("SHA") (Math.abs(loops) ?: 1).times { byte[] randm = { ByteArrayOutputStream byteOut = new ByteArrayOutputStream() DataOutputStream dataOut = new DataOutputStream(byteOut) dataOut.writeLong(t1) dataOut.writeDouble(q1) return byteOut.toByteArray() }() md.update(randm) md.update(msg.getBytes()) } return md.digest() } String user = "admin" String password = "s3cr3t" int loops = 1 byte[] hash1 = makeDigest(user+password, loops, 0, 0) // not randomized byte[] hash2 = makeDigest(user+password) // randomized assert hash1 != hash2 println "$hash1\n$hash2"
Wednesday, January 25, 2012
File/Directory Traverse
//helpful file properties: http://groovy.codehaus.org/JN2015-Files
import groovy.io.FileType def walkFiles = {filepath, filterOnly, onFind, onEnd = {} -> try { File f = new File(filepath) f.traverse([type:FileType.FILES, nameFilter:filterOnly], onFind) onEnd() } catch (FileNotFoundException e) { println "ERROR: invalid file/directory"} } def pf = { file -> if (file.name.contains("a")) println file.name } walkFiles("C:\\123", ~/.*\.ico/, pf)
Tuesday, January 24, 2012
FastMap and IdentityHashMap
@Grapes( @Grab(group='javolution', module='javolution', version='5.5.1') ) import javolution.util.FastMap // also FastSet, FastList Map labels1 = new FastMap().shared() Map labels2 = [:] as IdentityHashMap // unsorted 100.times { i -> labels1[String.valueOf(i)] = i*i labels2[String.valueOf(i)] = i*i } assert labels1 == labels2.sort()
see http://javolution.org/target/site/apidocs/javolution/util/FastMap.html
Fibonacci
/** * Fibonacci series: * the sum of two elements defines the next */ int LIMIT = 1000 (a,b) = [0,1] while (b < LIMIT) { print "$b " (a,b) = [b, a+b] }
(source)
Subscribe to:
Posts (Atom)