tag:blogger.com,1999:blog-10821711318523131162023-08-15T02:25:00.222-07:00Crazy4GroovyStevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.comBlogger96125tag:blogger.com,1999:blog-1082171131852313116.post-41769176135265077602016-01-29T17:59:00.000-08:002016-01-29T17:59:30.449-08:00HEAD HTTP Request<pre>boolean isValidUrl(String url) {
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection()
connection.setRequestMethod('HEAD')
if (connection.getResponseCode() == 200) {
return true
}
}
catch(final MalformedURLException e) { }
catch(final IOException e) { }
return false
}
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-10639409838384184562016-01-05T06:33:00.004-08:002016-01-05T06:33:48.634-08:00GZip HTTP Request/Response<pre>import java.util.zip.GZIPInputStream
String pageUrl = "http://www.google.com"
BufferedInputStream buff = pageUrl.toURL().newInputStream(requestProperties: ['Accept-Encoding': 'gzip,deflate'])
BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(buff)))
String resp = ""; reader.eachLine{ line -> resp += line }
</pre>
Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-68986432786650990042014-10-24T08:33:00.000-07:002016-04-12T11:24:23.961-07:00Easy peasy file/URL binary downloading with Ant get<pre>
def ant = new AntBuilder()
ant.get(src: 'http://groovy.codehaus.org/a.jpg', dest: /C:\scrap\a.jpg/, skipexisting: 'true')
//or
File destFile = new File(dest)
if (destFile.exists()) return
destFile.withOutputStream { it << src.toURL().openStream() }
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-18586309833797497732014-05-29T08:50:00.002-07:002014-05-29T08:50:38.401-07:00Simple Linked List<pre>class Node implements Cloneable {
private int val
private int i
private Node prev
private Node next
private static Node head
private static Node last
Node(int val, int i = 0) {
if (!head) head = this
if (!last) last = this
this.i = i
this.val = val
}
Integer at(int x, Node node = this) {
//println "" + x + node.i + node.next
if (x > node.i) {
if (node.next != null)
return this.at(x, node.next)
else
return null
}
return node.val
}
Node add(int val) {
Node newNode = new Node(val, last.i + 1)
newNode.prev = last
last.next = newNode
last = newNode
//println "---\nadd done\n---"
return head
}
Node reverse() {
Node r = last.clone()
Node prev = last.prev
while (prev != null) {
r.add(prev.val)
prev = prev.prev
}
return r
}
}
Node list = new Node(1)
assert list.at(0) == 1
list.add(4).add(6) // chained adding
assert list.at(0) == 1
assert list.at(1) == 4
assert list.at(2) == 6
assert list.at(3) == null
assert list.reverse().at(0) == list.at(2)
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-83085816849532740272014-05-29T07:41:00.000-07:002014-05-29T07:42:48.173-07:00Persistent (Immutable) Collections<pre>
@Grapes(
@Grab(group='org.pcollections', module='pcollections', version='2.1.2')
)
import org.pcollections.*
PSet<String> set = HashTreePSet.empty()
set = set + "something"
println set
println(set + "something else")
println set // immutable
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-78774990974626531412014-05-28T13:08:00.002-07:002014-05-28T13:10:53.570-07:00GPars Actors<pre>
import static groovyx.gpars.actor.Actors.actor
/**
* A demo showing two cooperating actors. The decryptor decrypts received messages and replies them back.
* The console actor sends a message to decrypt, prints out the reply and terminates both actors.
* The main thread waits on both actors to finish using the join() method to prevent premature exit,
* since both actors use the default actor group, which uses a daemon thread pool.
*
* code derrived from: http://gpars.codehaus.org/Actor
*/
def decryptor = actor {
loop {
react {message ->
Thread.sleep(1000);
if (!(message instanceof String)) {
stop()
return
}
reply message.reverse()
}
}
}
def console = actor {
List strs = ['abc','zyx','Vvv',false];
int i = -1
loop {
if (!strs[++i]) stop()
decryptor << strs[i]
println "Sent: ${strs[i]}"
react {msg ->
println "Decrypted msg: $msg"
}
}
}
[decryptor, console]*.join()
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-68876698493607115762014-04-16T13:44:00.001-07:002014-04-16T13:44:34.357-07:00Spock - BDD<pre>@Grapes([
@Grab(group='org.spockframework', module='spock-core', version='0.7-groovy-2.0')
])
import spock.lang.*
// see: http://meetspock.appspot.com/
// https://github.com/spockframework/spock
class MyFirstSpec extends Specification {
def "test min"() {
given: "min of a&b"
expect:
Math.min(a, b) == c
where:
a << [1,2]
b << [4,3]
c << [1,2]
}
def "test string length"() {
given: "length of name"
expect:
name.size() == length
where:
name << ["Sally","Bill"]
length << [5,4]
}
}
</pre>
Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-26926770151259361842014-01-16T11:08:00.001-08:002014-01-23T10:00:10.539-08:00dotPath<pre>
int item = Math.random() * 100000
def doCode = { return 'hi' }
Map $_ = [a: 1, b: ['c d': [z: item, doit: doCode]]]
use (UtilCategory) {
assert $_.dotPath() == [a: 1, b: ['c d': [z: item, doit: doCode]]]
assert $_.dotPath('') == [a: 1, b: ['c d': [z: item, doit: doCode]]]
assert $_.dotPath(null) == [a: 1, b: ['c d': [z: item, doit: doCode]]]
assert $_.dotPath('a') == 1
assert $_.dotPath('b.c d.z') == item
assert $_.dotPath('b/c d/z', '/') == item
assert $_.dotPath('b.c d.doit')() == 'hi'
assert $_.dotPath('b.c d.y') == null
assert $_.dotPath('b.c d.z.z') == null
assert $_.dotPath('b.c d.z.z.') == null
assert 1.dotPath('toString') == null
}
//========================================
@Category(Object)
class UtilCategory {
def dotPath(String path = '', String delimiter = /\./) {
Object self = this
if (!path) return self
try {
return path.split(/$delimiter/).inject(self) { x, i->
x = x[i]
}
}
catch (Exception ex) { return null }
}
}
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-1796299763011123552014-01-15T13:13:00.002-08:002014-01-15T13:14:24.454-08:00collectEntries - List to Map<pre>
List a = (1..50).toList()
Closure remainder = { return (it % 8) }
Map b = a.collectEntries{ i-> [(i.toString()) : remainder(i)]}
assert b['5'] == 5
assert b['7'] == 7
assert b['8'] == 0
assert b['17'] == 1
String last = b.keySet()[-1]
assert b[last] == 2 // [50:2]
a = ('a'..'z').toList()
Closure mult = { return (it * 8) }
b = a.collectEntries{ i-> [(i.toString()) : mult(i)]}
assert b['a'] == 'a'*8
last = b.keySet()[-1]
assert b[last] == 'z'*8 // [z:zzzzzzzz]
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-67144803553936871282014-01-15T10:18:00.002-08:002014-01-15T10:56:11.767-08:00csv-2-List for groovycsv
<pre>
@Grab('com.xlson.groovycsv:groovycsv:1.0')
import com.xlson.groovycsv.CsvParser
// a normally parsed csv can only be searched through ONCE
// this is used to create a "re-searchable" object (List of Maps)
List csv2List( String filePath, boolean shouldTrim = true ) {
new File( filePath ).withReader { r ->
new CsvParser().parse( r ).with { csv ->
return csv.collect { line ->
line.columns.collectEntries { c, v ->
[ c, (shouldTrim ? line[ c ].trim() : line[ c ]) ]
}
}
}
}
}
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-14362069211096784892013-09-17T11:05:00.000-07:002013-09-17T11:05:40.339-07:00Embedding groovy with groovyShell<pre>
//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);
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-15225732405175192512013-09-16T14:02:00.000-07:002013-09-17T06:46:52.422-07:00SwingX with MiGLayout - sample<pre>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)
}
}
</pre>
Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-79319514239302218702013-08-23T12:39:00.001-07:002013-08-23T12:39:28.066-07:00MySQL Connect and Query bootstrap<pre>
//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
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-16752600938561930592013-07-29T07:39:00.002-07:002013-08-23T12:46:38.459-07:00GroupBy and SubMap<pre>
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]]
</pre>
Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-14238124963154941472013-07-29T06:53:00.001-07:002014-01-23T10:00:46.673-08:00Intersect Lists and Maps<pre>
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
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-78553695871005759582013-07-24T08:48:00.000-07:002013-08-23T12:49:46.295-07:00Random String generator<pre>
//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)
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-36597069152374680992013-07-04T08:17:00.000-07:002013-07-04T08:17:52.435-07:00printf with Strings<pre>
//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)
}
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-42989020668582586792013-06-17T13:30:00.001-07:002013-06-17T19:16:03.769-07:00Gradle templates<pre>
// 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
}
}
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-2635505308487219972013-06-17T08:04:00.002-07:002013-09-17T06:40:52.649-07:00Script template<pre>// 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'
</pre>
Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-27157209893819912892013-06-14T09:31:00.002-07:002013-06-17T19:18:33.687-07:00Simple Performance Benchmarking<pre>
int delayMillis = 100
Long startMillis = Calendar.instance.time.time
Thread.sleep(delayMillis)
Long passedMillis = Calendar.instance.time.time - startMillis
println passedMillis
assert passedMillis >= delayMillis
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-20818001821984188532013-06-12T12:25:00.001-07:002013-06-12T12:26:25.680-07:00XML StreamingMarkupBuilder<pre>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>
</pre>
Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-42369276931676565082013-06-06T08:11:00.000-07:002013-06-06T08:11:11.625-07:00Scrape image src's from a web page<pre>
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')
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-64070885394939418522013-06-05T18:46:00.001-07:002013-06-05T18:46:04.405-07:00Immutable Maps (and Lists)<pre>
//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
}
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-50703848273347617162013-05-29T07:02:00.001-07:002013-05-29T07:02:42.567-07:00Immutable (Annotation)<pre>
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
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0tag:blogger.com,1999:blog-1082171131852313116.post-32964245941112024302013-05-16T18:01:00.001-07:002013-05-16T20:00:36.374-07:00POJO to JSON : binding and serializing<pre>
//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)
*/
</pre>Stevehttp://www.blogger.com/profile/11165277170755988215noreply@blogger.com0