Tuesday, September 17, 2013

Embedding groovy with groovyShell

//see: http://groovy.codehaus.org/Embedding+Groovy

Binding binding = new Binding();
binding.setVariable("foo", 2);
GroovyShell shell = new GroovyShell(binding);

Object value = shell.evaluate("println 'Hello World!'; x = 123; return foo * 10");
assert value.equals(20);
assert binding.getVariable("x").equals(123);

Monday, September 16, 2013

SwingX with MiGLayout - sample

package groovy.swingx.demo

@Grapes( 
    @Grab(group='com.miglayout', module='miglayout-swing', version='4.2') 
)
import groovy.swing.SwingXBuilder
import java.awt.Color
import java.awt.Font
import javax.imageio.ImageIO
import javax.swing.BorderFactory
import javax.swing.ImageIcon
import javax.swing.SwingConstants
import javax.swing.WindowConstants
import net.miginfocom.swing.MigLayout
import org.jdesktop.swingx.painter.GlossPainter
import org.jdesktop.swingx.painter.MattePainter


def swing = new SwingXBuilder()

// Text strings
def purchaseText = "Tried Catalog? Liked it? Now that you're convinced \
that living without Catalog would be horrible, purchase it for \
yourself and use it forever!"
def downloadText = "If you have Mac OS X 10.3 or later, you can grab a \
copy of Catalog right now and take it for a spin. At 816KB it's not \
only the best way to index your discs, but the most lightweight way."
def screenshotsText = "View a high quality, detailed screenshot of \
Catalog. Once you start drooling, click the button above and download."
def coolProduct  = "Introducing: Our Cool Product"
def coolProduct2 = "Having a bit of trouble shuffling through a ton of \
disks, trying to find the one that had that one document from way \
back when? Catalog allows you to find the file you're looking for \
without wearing out your disc drive (or your arm). Simply pop in a \
disk, drop it onto Catalog, and watch as it is indexed \u2013 \
virtually representing every file and tons of information about it. \
Then, when you want to find the file, search for it in Catalog and \
you find out exactly where it is, even if the disc isn't in your drive."
def dude  = "But Dude! The Disc Isn't In The Drive!"
def dude2 = "Catalog isn't supposed to feel like an extension of your disc \
browsing needs \u2013 rather it seamlessly blends offline disc \
browsing into your work environment. Browsing in Catalog feels just \
like browsing in the Finder \u2013 your files are right there in \
front of you. Once you find the file you want, just look to see where \
it is, pop in that disk, and open it up. Whether you are cataloging \
your backup, your music collection, family recipes, or your super \
secret world domination plans, Catalog will work exactly how it should."

def compoundPaint = swing.compoundPainter() {
        mattePainter(fillPaint:new Color(51,51,51))
        pinstripePainter(paint:new Color(1.0f,1.0f,1.0f,0.17f),
            spacing:5.0f)
        glossPainter(paint:new Color(1.0f,1.0f,1.0f,0.2f),
            position:GlossPainter.GlossPosition.TOP)
    }

swing.frame(title:"Groovy SwingXBuilder Painter Demo",
    background:Color.WHITE, resizable:false,
    layout:new MigLayout("insets 0 0 0 0"),
    defaultCloseOperation:WindowConstants.DISPOSE_ON_CLOSE,
    show:true,
    pack:true,
) {
    panel( backgroundPainter:compoundPaint, background:new Color(51,51,51), layout:new MigLayout(), constraints:"north, w 522") {
        //label(name:'shield',icon:new ImageIcon(ImageIO.read(new File("shield.png"))))
        label()
        label(font:new Font("Tahoma", 1,18), foreground:Color.WHITE, text:"UTAH BOY SOFTWARE", constraints:"x 80, y 20")
        label(font:new Font("Tahoma",0,14), foreground:Color.WHITE, text:"Better tools.", constraints:"x 80, y 50")
    }
    panel(backgroundPainter:new MattePainter(new Color(51,51,51)), layout:new MigLayout(), border:BorderFactory.createLineBorder(new Color(102,102,102)), constraints:"newline, north") {
        label(font:new Font("Lucinda Grande",0,9), text:"PRODUCTS", foreground:Color.WHITE, horizontalAlignment:SwingConstants.CENTER, constraints:"gapleft 9")
        label(font:new Font("Lucinda Grande",0,9), text:"STORE", foreground:Color.WHITE, horizontalAlignment:SwingConstants.CENTER, constraints: "gapleft 23")
        label(font:new Font("Lucinda Grande",0,9), text:"ABOUT", foreground:Color.WHITE, horizontalAlignment:SwingConstants.CENTER ,constraints: "gapleft 29")
        label(font:new Font("Lucinda Grande",0,9), text:"NEWS", foreground:Color.WHITE, horizontalAlignment:SwingConstants.CENTER ,constraints: "gapleft 33")
        label(font:new Font("Lucinda Grande",0,9), text:"SUPPORT", foreground:Color.WHITE, horizontalAlignment:SwingConstants.CENTER, constraints: "gapleft 28")
        label(font:new Font("Lucinda Grande",0,9), text:"GOODIES", foreground:Color.WHITE, horizontalAlignment:SwingConstants.CENTER, constraints: "gapleft 27")
    }
    //label(icon:new ImageIcon(ImageIO.read(new File("title.png"))), constraints:"north")
    label(font:new Font("Lucinda Grande",0,9), text:"TITLE IMAGE", foreground:Color.BLACK, horizontalAlignment:SwingConstants.CENTER, constraints:"north")
    separator(constraints:"w 2, h 500, gap 0", background:new Color(99,130,191), orientation:SwingConstants.VERTICAL)
    panel(layout:new MigLayout("insets 0 0 0 0")) {
        // Purchase Panel
        panel(backgroundPainter:new MattePainter(new Color(240,239,239)), layout:new MigLayout(), constraints:"gap 0, wrap") {
            label(font:new Font("Tahoma",1,11), foreground:new Color(51,102,255), text:"Purchase", constraints:"wrap")
            textArea(columns:20, constraints:"align left", font:new Font("Tahoma",0,11), lineWrap:true, rows:5, text:purchaseText, wrapStyleWord:true, border:null,
                disabledTextColor:new Color(0,0,0), opaque:false, enabled:false, selectedTextColor:Color.WHITE, selectionColor:Color.BLACK)
        }

        // Download panel
        panel(backgroundPainter:new MattePainter(Color.WHITE), layout:new MigLayout(), constraints:"gap 0, wrap") {
            label(font:new Font("Tahoma",1,11), foreground:new Color(51,102,255), text:"Download", constraints:"wrap")
            textArea(columns:20, constraints:"align left", font:new Font("Tahoma",0,11), lineWrap:true, rows:5, text:downloadText, wrapStyleWord:true, border:null,
                disabledTextColor:Color.BLACK, opaque:false, enabled:false, selectedTextColor:Color.WHITE, selectionColor:Color.BLACK)
        }

        // Screenshots panel
        panel(backgroundPainter:new MattePainter(new Color(240,239,239)), layout:new MigLayout(), constraints:"gap 0,wrap") {
            label(font:new Font("Tahoma",1,11), foreground:new Color(51,102,255), text:"Screenshots", constraints:"wrap")
            textArea(columns:20, constraints:"align left", font:new Font("Tahoma",0,11), lineWrap:true, rows:5, text:screenshotsText, wrapStyleWord:true, border:null,
                disabledTextColor:Color.BLACK, opaque:false, enabled:false, selectedTextColor:Color.WHITE, selectionColor:Color.BLACK)
        }
   }

   // western panel - cool product and dude
   panel(backgroundPainter:new MattePainter(Color.WHITE), layout:new MigLayout(), constraints:"west") {
        label(font:new Font("Tahoma",1,11), text:coolProduct)
        textArea(columns:28, constraints:"newline, gaptop 10, gapbottom 10", font:new Font("Tahoma",0,11), lineWrap:true, rows:5, text:coolProduct2, wrapStyleWord:true, disabledTextColor:Color.BLACK,
            enabled:false, selectedTextColor:Color.BLACK, border:null, selectionColor:Color.WHITE)
        label(font:new Font("Tahoma",1,11), text:dude, constraints:"newline")
        textArea(columns:28, constraints:"newline",font:new Font("Tahoma",0,11), lineWrap:true, rows:5, text:dude2, wrapStyleWord:true, disabledTextColor:Color.BLACK,
            enabled:false, selectedTextColor:Color.BLACK, border:null, selectionColor:Color.WHITE)
    }
}

Friday, August 23, 2013

MySQL Connect and Query bootstrap

//see: http://groovy.codehaus.org/Tutorial+6+-+Groovy+SQL
@Grapes(
 @Grab(group='mysql', module='mysql-connector-java', version='5.1.26')
)
@GrabConfig(systemClassLoader=true)
import groovy.sql.Sql
String user = "root"
String pwd = "1234"

String fileTable = "mcScrap";
List fileCols = ['col1','test1col'];

def sql = Sql.newInstance("jdbc:mysql://localhost:3306/onix21", user, pwd, "com.mysql.jdbc.Driver")

println "Connected!\n"

println "Found $fileTable ?: " + !!(sql.rows("SHOW TABLES LIKE ${fileTable}").size())

String command = """
CREATE TABLE IF NOT EXISTS `$fileTable` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`${fileCols[0]}` VARCHAR(45) NULL ,
`${fileCols[1]}` VARCHAR(45) NULL ,
PRIMARY KEY (`id`) ,
UNIQUE INDEX `id_UNIQUE` (`id` ASC) );
"""
println command
println sql.execute(command)

command = "SELECT * FROM `$fileTable`"
println command
sql.eachRow(command) { println "$it.id -- ${it[fileCols[0]]} -- ${it[fileCols[1]]} --" }

println sql.execute("INSERT INTO `$fileTable` (${fileCols.join(',')}) VALUES (?,?);", ['1','1'])

command = "SELECT * FROM `$fileTable`"
println command
sql.eachRow(command) { println "$it.id -- ${it.col1} -- ${it.test1col} --" }

println sql.executeUpdate("UPDATE `$fileTable` SET ${fileCols[0]} = ? WHERE ${fileCols[1]}=1", [Math.random()])

List rows = []
sql.eachRow(command) { rows << (it.toRowResult() as HashMap) }
println "rows: " + rows.size()
println "type: " + rows[0].getClass().name
println "1st: " + rows[0]
println "all: " + rows

Monday, July 29, 2013

GroupBy and SubMap

int groups = 7
//divide list up into groups by % (their remainder)
Map a = (1..50).groupBy({ it % groups }) as TreeMap
assert a.keySet() == (0..<groups) as Set
assert a.keySet() == [0, 1, 2, 3, 4, 5, 6] as Set

//pull out specific keys (plus vals) from a Map
assert a.subMap(1) == [1:[1, 8, 15, 22, 29, 36, 43, 50]]
assert a.subMap([1,2]) == [1:[1, 8, 15, 22, 29, 36, 43, 50], 2:[2, 9, 16, 23, 30, 37, 44]]
assert a.subMap([1,2,99]) == [1:[1, 8, 15, 22, 29, 36, 43, 50], 2:[2, 9, 16, 23, 30, 37, 44], 99:null]
assert a.subMap([1,2,99]).findAll({k,v->!!v}) == [1:[1, 8, 15, 22, 29, 36, 43, 50], 2:[2, 9, 16, 23, 30, 37, 44]]
assert a.subMap((1..3)) == [1:[1, 8, 15, 22, 29, 36, 43, 50], 2:[2, 9, 16, 23, 30, 37, 44], 3:[3, 10, 17, 24, 31, 38, 45]]

Intersect Lists and Maps

List a = [1,2,3]
List b = [2,3,4]
assert [2,3] == a.intersect(b)
assert [1,2,3,4] == (a + b).unique()
assert [1] == a - b
assert [4] == b - a


Map c = [a:1, b:2, c:44]
Map d = [b:2, c:3]
assert [b:2] == c.intersect(d)
assert [a:1, b:2, c:3] == c + d
assert [a:1, b:2, c:44] == d + c
assert [a:1, c:44] == c - d
assert [c:3] == d - c

Wednesday, July 24, 2013

Random String generator

//see: http://groovyconsole.appspot.com/edit/1032002

String generateToken(Integer size = 16){
    String availableChars = 'ABCDEFGHIJLMNOPQRSTUVXZYabcdefghijlmnopqrstuvxzy0123456789!@#$%*_'
    Random generator = new Random()
    String token = ""
    size.times {
        token += availableChars[generator.nextInt(availableChars.length() - 1)]
    }
    return token
}
 
generateToken()
generateToken(8)

Thursday, July 4, 2013

printf with Strings

//all formatting options: http://docs.oracle.com/javase/6/docs/api/java/util/Formatter.html#syntax

//test padding on both sides of "HI"//

(-8..8).each{ i ->
    if (i == 0) i = '' // avoid illegal printf syntax
    
    String f = "**%${i}s**"
    print ((f + ' --> ').padRight(15)) // just for debugging
    printf(f+'\n', "HI")
}


//Tic Tac Toe//

List field = [["","x","o"],["","x",""],["o","",""]]
field.eachWithIndex { line,index ->
    if(index > 0) {
        println "---+" * 2 + "---"
    }
    printf(" %-2s| %-2s| %-2s\n", line)
}

Monday, June 17, 2013

Gradle templates

// Generate a new Groovy Project Qwickly (tm) //
// source: https://github.com/townsfolk/gradle-templates

// in build.gradle file (in the project's root folder):
apply from: 'http://www.tellurianring.com/projects/gradle-plugins/gradle-templates/apply.groovy'

dependencies {
   groovy localGroovy()
}

//then get a list of tasks:
>> gradle tasks

...
Template tasks
--------------
createGroovyClass - Creates a new Groovy class in the current project. **************
createGroovyProject - Creates a new Gradle Groovy project in a new directory named after your project.
createJavaClass - Creates a new Java class in the current project.
createJavaProject - Creates a new Gradle Java project in a new directory named after your project.
exportGroovyTemplates - Exports the default groovy template files into the current directory.
exportJavaTemplates - Exports the default java template files into the current directory.
initGroovyProject - Initializes a new Gradle Groovy project in the current directory. **************
initJavaProject - Initializes a new Gradle Java project in the current directory.
...


>> gradle initGroovyProject
>> gradle createGroovyClass


/**********************************************************/

//Here's a pretty useful project build.gradle:
apply plugin: 'groovy'
apply from: 'http://www.tellurianring.com/projects/gradle-plugins/gradle-templates/apply.groovy'
apply from: 'http://evgenyg.artifactoryonline.com/evgenyg/libs-releases-local/CodeNarc.gradle'

group = 'myapp1'
mainClassName = 'org.MyCompany.Main'

dependencies {
   groovy localGroovy()
}

jar {
    manifest {
        attributes("Main-Class": mainClassName)
    }
}

// uberjar adds in groovy jars to make this easy: "java -jar MyApp.jar"
task uberjar(type: Jar, dependsOn:[':compileJava', ':compileGroovy']) {
    from files(sourceSets.main.output.classesDir)
    from configurations.runtime.asFileTree.files.collect { zipTree(it) }

    manifest {
        attributes 'Main-Class': mainClassName
    }
}

Script template

// this is just intended to give a little more OOP structure to a script.
// put most code inside of run(), plus class variables and methods.

class Script {
    
    private String hello = "Hello"
    
    public Script run(Map options = [:]) {
        println "$hello ${options.name ?: 'World'}${shout(23)}"
        
        
        return this // for method chaining
    }
    
    private String shout(int times = 1) {
        return ('!' * times)
    }
    
}

new Script()
    .run()
    .run([name:'Crazy4Groovy'])

println 'DONE'

Friday, June 14, 2013

Simple Performance Benchmarking

int delayMillis = 100

Long startMillis = Calendar.instance.time.time

Thread.sleep(delayMillis)

Long passedMillis = Calendar.instance.time.time - startMillis

println passedMillis

assert passedMillis >= delayMillis

Wednesday, June 12, 2013

XML StreamingMarkupBuilder

import groovy.xml.StreamingMarkupBuilder

Map props = [addressid:'1', line1:'line-1_VALUE', line2:'line-2_VALUE']

def builder = new StreamingMarkupBuilder()

def address = {
     "address"(id: props.addressid) {
         "line-1"(props.line1)
         "line-2"(props.line2)
         "city"("city_VALUE") // typing wimped out...
         "state"("State_VALUE")
         "postal-code"("postal_VALUE")
     }
}

println builder.bind(address).toString() // something XML-compatible <address id="1">
...</address>

Thursday, June 6, 2013

Scrape image src's from a web page

import java.net.URLEncoder

String url = "http://msnbc.com"

String serviceUrl = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22${URLEncoder.encode(url)}%22%20and%20xpath%3D%22%2F%2Fimg%22"
//println serviceUrl

String resultXML = serviceUrl.toURL().text // YQL will return the HTML page as XML!
//println resultXML

def root = new XmlSlurper().parseText(resultXML)

List imgSrcs = root.results.img.@src as List
imgSrcs = imgSrcs*.toString().unique()
//println imgSrcs.join('\n')

Wednesday, June 5, 2013

Immutable Maps (and Lists)

//source: http://royontechnology.blogspot.co.at/2010/06/creating-collection-with-single-element.html

//note the different constructor args; both return immutables

assert [2] == Collections.singletonMap(1, 1).collect {k,v ->
    return k+v
}

assert [3, 7] == Collections.unmodifiableMap([1:2, 3:4]).collect {k,v ->
    return k+v
}

Wednesday, May 29, 2013

Immutable (Annotation)

import groovy.transform.Immutable

@Immutable
class A {
    Date d // private final
    Date z // private final
    
    /* //no constructor def'n needed with @Immutable
    public A(Date D, Date Z) {
        d = D
        z = Z
    }*/
}

A a = new A(new Date(), new Date())

println a // see provided toString()

Date d1 = a.d // get property
assert (d1 == a.d)
d1.setHours(0) // mutate copy of property
assert (d1 != a.d) // this would not pass if class was mutable

println a.d
a.d.setHours(0) // no consequence/ignored
println a.d

Thursday, May 16, 2013

POJO to JSON : binding and serializing

//see: http://www.cowtowncoder.com/blog/archives/2009/01/entry_137.html
//see: https://github.com/FasterXML/jackson-databind

@Grapes([
/*
  @Grab(
    group='com.fasterxml.jackson.core', module='jackson-core', version='2.2.1'
  ),
  @Grab(
    group='com.fasterxml.jackson.core', module='jackson-annotations', version='2.2.1'
  ),
*/
  @Grab(
    group='com.fasterxml.jackson.core', module='jackson-databind', version='2.2.1'
  )
])
import com.fasterxml.jackson.databind.ObjectMapper

class Abc {
    int id, age
    String person
}

ObjectMapper mapper = new ObjectMapper();
Abc entry = mapper.readValue('{"id": 1, "person": "Steve", "age": "1"}', Abc.class);

assert entry1.id == 1
assert entry1.person == "Steve"
assert entry1.age == 1 //notice the auto type conversion from the JSON!

def entry2 = mapper.readValue('{"id": 1, "person": "Steve", "age": [1, {}, 3]}', LinkedHashMap.class);

assert entry2.id == 1
assert entry2.person == "Steve"
assert entry2.age.size() == 3
assert entry2.age[1].getClass().name == 'java.util.LinkedHashMap'


mapper.writeValue(new File("C:\\result.json"), entry1)  //--> {"id":1,"person":"Steve","age":1}
/*
  public void com.fasterxml.jackson.databind.ObjectMapper#writeValue(java.io.File, java.lang.Object)
  public void com.fasterxml.jackson.databind.ObjectMapper#writeValue(java.io.OutputStream, java.lang.Object)
  public void com.fasterxml.jackson.databind.ObjectMapper#writeValue(java.io.Writer, java.lang.Object)
*/

Monday, January 7, 2013

Simple Timer & TimerTask

public class MyTask extends TimerTask{
    Closure onFinish
    int count, repeat
    
    public MyTask(Closure onFinish = {}, int repeat = 1){
        this.onFinish = onFinish
        this.repeat = repeat
        this.count = 1
    }
    
    private void toDo(){
        println "count-> ${count}"      
    }
    
    private void checkFinished() {
        if (count > repeat) { //this is the condition when you want to stop the task.
            println "DONE-> before ${count}"
            onFinish()
            return
        }
    }
    
    @Override
    public void run() {        
        toDo()
        count++
        checkFinished()
    }
}

public class MyScheduler {
    public static void doIt( Closure then = {} ) {
        Timer timer = new Timer()
        MyTask myTask = new MyTask( repeat:3, 
            onFinish:{ 
                timer.cancel() // stop the timer
                then() // do the callback
            })
        int delayStartMs = 2000
        int intervalMs = 1000
        timer.schedule(myTask, delayStartMs, intervalMs)
    }
}

MyScheduler.doIt( { println "#1 DONE" } )
MyScheduler.doIt( { println "#2 DONE" } )

Run OS command

//windows
String cmd = "ping google.com"

String[] command = ["CMD", "/C", cmd] as String[]
ProcessBuilder builder = new ProcessBuilder(command)
Process process = builder.start()

println process.text

println "*"*5+"DONE"+"*"*5

Sunday, January 6, 2013

String padding with zeros

String.metaClass.zeropad = { Integer padding = 0 ->
    return ("0" * Math.max(0, (padding ?: 0) - delegate.size())) + delegate
}
Integer.metaClass.zeropad = { Integer padding = 0 ->
    return delegate.toString().zeropad(padding)
}

assert "123".zeropad()     == "123"
assert "123".zeropad(null) == "123"
assert "123".zeropad(5)    == "00123"
assert "1234".zeropad(5)   == "01234"
assert "12345".zeropad(5)  == "12345"
assert "123456".zeropad(5) == "123456"

assert 123.zeropad()     == "123"
assert 123.zeropad(null) == "123"
assert 123.zeropad(5)    == "00123"
assert 1234.zeropad(5)   == "01234"
assert 12345.zeropad(5)  == "12345"
assert 123456.zeropad(5) == "123456"