Search

Dark theme | Light theme
Showing posts with label GroovyGoodness:IO. Show all posts
Showing posts with label GroovyGoodness:IO. Show all posts

October 17, 2017

Groovy Goodness: Make Sure Closeable Objects Are Closed Using withCloseable Method

If a class implements the Closeable interface Groovy adds the withCloseable method to the class. The withCloseable method has a closure as argument. The code in the closure is executed and then the implementation of the close method of the Closeable interface is invoked. The Closeable object is passed as argument to the closure, so we can refer to it inside the closure.

In the following example we have two objects that implement the Closeable interface. By using withCloseable we know for sure the close method is invoked after all the code in the closure is executed:

@Grab(group='org.apache.httpcomponents', module='httpclient', version='4.5.3')
import org.apache.http.impl.client.HttpClientBuilder
import org.apache.http.client.methods.HttpGet

// HttpClientBuilder.create().build() returns a CloseableHttpClient
// that implements the Closeable interface. Therefore we can use
// the withCloseable method to make sure the client is closed
// after the closure code is executed. 
HttpClientBuilder.create().build().withCloseable { client ->
    final request = new HttpGet('http://www.mrhaki.com')

    // The execute method returns a CloseableHttpResponse object
    // that implements the Closeable interface. We can use
    // withCloseable method to make sure the response is closed
    // after the closure code is executed.
    client.execute(request).withCloseable { response ->
        assert response.statusLine.statusCode == 200
    }
}

Written with Groovy 2.4.12.

February 19, 2015

Groovy Goodness: Access XML-RPC API

Recently I had to access the XML-RPC WordPress API for a small project. Luckily with Groovy we can access a XML-RPC server in a Groovy way. We need to use the Groovy XML-RPC module, which is a separate dependency. The module provides code to write a XML-RPC server, but also code to access a XML-RPC server as client. We use the class XMLRPCServerProxy in the package groovy.net.xmlrpc to act as a client to a XML-RPC API. The XMLRPCServerProxy class only needs to know the URL to access the API. All API methods are dynamically dispatched to the server, so it is very flexible.

In the following Groovy script we use the WordPress XML-RPC API to access posts:

@Grab('org.codehaus.groovy:groovy-xmlrpc:0.8')
import groovy.net.xmlrpc.*

// Use correct blog identifier.
def blogId = 0 

// Use correct URL for XML-RPC API.
def blogUrl = 'http://blog/xmlrpc' 

def blogUsername = 'mrhaki'
def blogPassword = 'secret'

// Create client access for XML-RPC API.
// The second parameter is set to true
// to autodetect encoding. Default encoding
// is ISO-8859-1.
def wordPress = new XMLRPCServerProxy(blogUrl, true)

// Now we can access the API methods from WordPress.
// Notice the API method wp.getPosts is dynamically
// available from the XMLRPCServerProxy instance.
def latestFivePost = 
    wordPress
        ."wp.getPosts"(
             blogId,
             blogUsername,
             blogPassword,       
             [number: 5, post_type: 'post'],
             ['post_id', 'post_title'])

latestFivePosts.each { post ->
    println "Blog post (#${post.post_id}): ${post.post_title}"
}

Written with Groovy 2.4.

January 28, 2013

Groovy Goodness: Append Values to Appendable Objects

Since Groovy 2.1 we have a couple of extra methods available for objects that implement the java.lang.Appendable interface. A lot of Writer objects implement this interface. The documentation of the Appendable interface mentions: An object to which char sequences and values can be appended.

First the leftShift() method is added. This means we can use the leftShift operator (<<) to append a value. Then we also can use the withFormatter() method. We can pass a closure to this method or a java.util.Locale object and a closure. The closure has a single parameter which is a java.util.Formatter instance. We can use this method to add printf-style formatted strings to an Appendable object. If we pass a Locale object to the method the Formatter is created with the specified Locale to created localized printf-sytle formatted strings.

// Create object that implements the Appendable interface.
final Appendable appendable = new StringWriter()

assert appendable in Appendable


// Use leftShift operator to add to Appendable implementation.
appendable << 'Groovy is Gr8!' << newLine


// Use withFormatter() method.
// Formatter object 
// is passed to closure as parameter.
appendable.withFormatter { formatter ->
    // Simple formatter pattern to reorder the arguments.
    formatter.format(/m r %3$1s %2$1s %1$1s %4$1s%n/, 'k', 'a', 'h', 'i')
}


// Use withFormatter() method and use Locale object
// as extra argument. The Locale is passed on
// to create the Formatter object.
appendable.withFormatter(Locale.US) { formatter ->
    formatter.format("US: " + datePattern, date)
}
// Use different Locale.
appendable.withFormatter(new Locale('nl')) { formatter ->
    formatter.format("Dutch: $datePattern", date)
}


// Check result is as expected:
assert appendable.toString() == '''Groovy is Gr8!
m r h a k i
US: January 27, 2013
Dutch: januari 27, 2013
'''


// Helper getters:

String getNewLine() {
    System.getProperty('line.separator')
}

Date getDate() {
    // Simple date to use in withFormatter() methods.
    Date.parse('yyyy-MM-dd', '2013-01-27')
}

String getDatePattern() {
    // Date pattern for Formatter.
    '%1$tB %1$te, %1$tY%n'
}

Code written with Groovy 2.1

May 31, 2011

Groovy Goodness: Transforming Reader Input to Writer Output

With Groovy we can immediately transform the input from a Reader object(like a file, URL or other input type) to a Writer object (like a file, URL or other output type). Groovy adds the transformLine(Writer, Closure) and transformChar(Writer, Closure) methods to the Reader class. We need to pass the Writer object that will contain the transformed output as the first argument. The second argument is a closure with the rules for the transformation that needs to be applied.

def reader = new StringReader('''\
Groovy's support
for transforming reader input to writer output.
''')

def writer = new StringWriter()

reader.transformLine(writer) { line ->  
    if (line.matches(~/^Groovy.*/)) {
        line = '>>' + line.replaceAll('Groovy', 'GROOVY') + '<< '
    }
    line
}

def resultTransformLine = writer.toString()

reader = new StringReader(resultTransformLine)
writer = new StringWriter()
reader.transformChar(writer) { ch ->
    ch in ['\n', '\r'] ? '' : ch
}

assert writer.toString() == ">>GROOVY's support<< for transforming reader input to writer output."

November 9, 2009

Groovy Goodness: withReader and withWriter

Normally when we are working with readers and writers in Java we must make sure we close the appropriate reader and writer. Groovy has several with...() methods for File, URL or streams and writers, where ... is the name of the reader or writer. We pass a closure to these methods and Groovy makes sure all readers and writers are closed correctly, even if exceptions are thrown in the closure.

def file = new File('sample.txt')

file.withWriter('UTF-8') {
    it.writeLine 'Adding this text to the file.'
}

def s 
file.withReader('UTF-8') {
    s = it.readLine()
}

assert 'Adding this text to the file.' == s