Tuesday, April 24, 2012
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.
Subscribe to:
Posts (Atom)