Shinta Smith
Shinta Smith

Reputation: 500

groovy read a file, resolve variables in file content

I am new to Groovy and I could not get around this issue. I appreciate any help.

I want to read a file from Groovy. While I am reading the content, for each line I want to substitute the string '${random_id}' and '${entryAuthor}' with different string values.

protected def doPost(String url, URL bodyFile, Map headers = new HashMap() ) {
    StringBuffer sb = new StringBuffer()
    def randomId = getRandomId()
    bodyFile.eachLine { line ->
        sb.append( line.replace("\u0024\u007Brandom_id\u007D", randomId)
                     .replace("\u0024\u007BentryAuthor\u007D", entryAuthor) )
        sb.append("\n")
    }
    return doPost(url, sb.toString())
}

But I got the following error:

groovy.lang.MissingPropertyException: 
No such property: random_id for class: tests.SimplePostTest
Possible solutions: randomId
    at foo.test.framework.FooTest.doPost_closure1(FooTest.groovy:85)
    at groovy.lang.Closure.call(Closure.java:411)
    at groovy.lang.Closure.call(Closure.java:427)
    at foo.test.framework.FooTest.doPost(FooTest.groovy:83)
    at foo.test.framework.FooTest.doPost(FooTest.groovy:80)
    at tests.SimplePostTest.Post & check Entry ID(SimplePostTest.groovy:42)

Why would it complain about a property, when I am not doing anything? I also tried "\$\{random_id\}", which works in Java String.replace(), but not in Groovy.

Upvotes: 4

Views: 5182

Answers (3)

Matthew Payne
Matthew Payne

Reputation: 3056

You are doing it the hard way. Just evaluate your file's contents with Groovy's SimpleTemplateEngine.

import groovy.text.SimpleTemplateEngine

def text = 'Dear "$firstname $lastname",\nSo nice to meet you in <% print city %>.\nSee you in ${month},\n${signed}'

def binding = ["firstname":"Sam", "lastname":"Pullara", "city":"San Francisco", "month":"December", "signed":"Groovy-Dev"]

def engine = new SimpleTemplateEngine()
template = engine.createTemplate(text).make(binding)

def result = 'Dear "Sam Pullara",\nSo nice to meet you in San Francisco.\nSee you in December,\nGroovy-Dev'

assert result == template.toString()

Upvotes: 4

Michael Easter
Michael Easter

Reputation: 24468

The issue here is that Groovy Strings will evaluate "${x}" by substituting the value of 'x', and we don't want that behaviour in this case. The trick is to use single-quotes which denote plain old Java Strings.

Using a data file like this:

${random_id} 1 ${entryAuthor}
${random_id} 2 ${entryAuthor}
${random_id} 3 ${entryAuthor}

Consider this code, which is analogous to the original:

// spoof HTTP POST body
def bodyFile = new File("body.txt").getText()

StringBuffer sb = new StringBuffer()
def randomId = "257" // TODO: use getRandomId()
def entryAuthor = "Bruce Eckel"

// use ' here because we don't want Groovy Strings, which would try to
// evaluate e.g. ${random_id}
String randomIdToken = '${random_id}'
String entryAuthorToken = '${entryAuthor}'

bodyFile.eachLine { def line ->
    sb.append( line.replace(randomIdToken, randomId)
                   .replace(entryAuthorToken, entryAuthor) )
    sb.append("\n")
}

println sb.toString()

The output is:

257 1 Bruce Eckel
257 2 Bruce Eckel
257 3 Bruce Eckel

Upvotes: 0

Lucas Oliveira
Lucas Oliveira

Reputation: 883

you better use groovy.text.SimpleTemplateEngine class; check this for more details http://groovy.codehaus.org/Groovy+Templates

Upvotes: 3

Related Questions