Using 'eachWithindex' groovy instead of For loops to read in json data - groovy

I'm having trouble with converting an existing FOR loop to use the 'eachWithIndex' groovy function.
I'm not sure how to go about doing this successfully, examples I've seen are quite straightforward on tutorials but I'm not sure how to make them work with groovy json files.
The current solution uses a For loop which reads in data from 3 different groovy files
Add_Page1_data = data.get("json_Page1")
Add_Page2_data = data.get("json_Page2")
Add_Page3_data = data.get("json_Page3")
for (int i=0; i< Add_Page1_data.size(); i++) {
execute(w, Add_Page1_data[i],
Add_Page2_data[i],
Add_Page3_data[i])
}
I then use the following code to populate data inside windows by accessing the page objects of the file before :
def execute(w, data1) {
def page1 = new PO_Add_Page1(wrapper: w)
page1.typeInSomeText(data1.sometext)
}
PageObject file looks like this:
class PO_Add_Page1 {
def typeInSomeText(val) {
wrapper.findWithLabel("Some Text . .").rightEditable().type(val)
}
Json file used contains multiple records like this:
{
"json_Page1": [
{
"sometext": "text1"
},
{
"sometext": "text2"
},
The json is fed in as the "data" which maps to elements on the page using the page object groovy file.
I wanted to be able to repeat the same functionality in a more groovy idiomatic way.
Any help would be much appreciated.

Related

Create dynamic xml parametrized block with groovy

I have a comma-separated list/array as input to the groovy script. based on the number of elements in the array, I need to create parameterized XML block like below.
eg if the input is CAT,DOG
I need to create an XML block like below
<v2:values>
<v2:item>CAT</v2:item>
<v2:item>DOG</v2:item>
</v2:values>
if the input is CAT,DOG,ROSE
I need output as
<v2:values>
<v2:item>CAT</v2:item>
<v2:item>DOG</v2:item>
<v2:item>ROSE</v2:item>
</v2:values>
if Input is empty I need output block as empty
I wrote a groovy script like this
if(input.contains(","))
{
String[] param_array = input1[0].split(',')
res="<v2:values>"
for (parameter in param_array)
{
after that, I am not sure how do I iterate over the array and put values for other XML tags. Is there any way to do that?
You can use StreamingMarkupBuilder to generate the XML into a String
It won't be pretty-printed, but it will be valid XML as requested:
import groovy.xml.*
def input = 'cat,mouse,dog'
String xml = new StreamingMarkupBuilder().bind {
'v2:values' {
input.split(',').collect { item ->
'v2:item'(item)
}
}
}
println xml
If you need it pretty printed, you will need to know where the schema for v2 is, as XmlUtil.serialize needs the xml to validate
Edit
If you need it pretty printed, you can switch to MarkupBuilder
import groovy.xml.*
def input = 'cat,mouse,dog'
def writer = new StringWriter()
new MarkupBuilder(writer).'v2:values' {
input.split(',').collect { item ->
'v2:item'(item)
}
}
println writer.toString()

How to add custom import statements in the generated java file in xtext using jvmmodelInferrer?

I have written a grammar for my domain specific language in xtext and I am using jvmmodelInferrer to generate java code. I can generate fields and custom methods but how can I add custom import statements like 'import java.util.*' in the generated java file without the user having to explicitly write the import statement?
you dont generate import strings. you just use rich strings in a proper way and everything happens automatically
def dispatch void infer(Model element, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
for (greeting : element.greetings) {
acceptor.accept(greeting.toClass("demo." + greeting.name)) [
members += greeting.toMethod("demo", Void.TYPE.typeRef) [
body = '''
«JFrame» f = null;
«"java.util.List".typeRef("java.lang.String".typeRef)» l = null;
return;
'''
]
]
}
}

Can groovy heredocs be internationalized?

Have some multiline strings that are presented to the user and stored as Heredocs. So rather than a 'normal' (Java) property file, a groovy-based one (see here) to be consumed by ConfigSlurper was used and works great. Sorry if this is a dumb question, but can that be easily internationalized? If so, can you outline how that is accomplished?
My solution: In your ConfigSlurper you should store keys to the internalized strings. Inject messageSourceand localResolver in your controller/service, get key from your ConfigSlurper and find localized string in your i18n messages.property file. Example (not sure that code is correct, but it's the main idea):
def config = new ConfigSlurper().parse(new File('src/Config.groovy').toURL())
//localized string1 value
def msg = messageSource.getMessage(config.data1.string1, null, localeResolver.defaultLocale)
As far as I know the ConfigSlurper does not have special support for i18n.
You may achieve it by using the leveraging its support for environments by creating an environment closure per locale. For example:
environments {
english {
sample {
hello = "hello"
}
}
spanish {
sample {
hello = "hola"
}
}
}
When creating the ConfigSlurper you will need to pass the desired language:
def config = new ConfigSlurper("spanish")

groovy parse local html file

I am working on a groovy script that will get all the local html files and parse certain tags in them. I tried using something like html clean and it just is not working. I tried to read each line but that only works when the stuff I need is on 1 line. I have this script up on github, https://github.com/jrock2004/johns-octopress-scripts/blob/master/convertCompiledPosts/convertPosts.groovy. Thanks for any input
Edit: So I am getting closer. I have this code now
def parser = new org.cyberneko.html.parsers.SAXParser()
new XmlParser( parser ).parse( curFile+ "/index.html" ).with { page ->
page.'**'.DIV.grep { it.'#class'?.contains 'entry-content' }.each {
println it
println "--------------------------------"
}
}
And what it prints is
DIV[attributes={class=entry-content}; value=[P[attributes={}; value=[As an automation developer, I have learned how to write code in Java. When I am having an issue, one of the nice things that you can do is debug your code, line by line. For the longest I had wished that something like this existed in PHP. I have come to find out that you can actually debug code, like I do in Java. This is such a helpful task because I do not have to waste time using var_dump and such on variables or results. In your apache/php server you need to install and or enable something called, A[attributes={href=http://xdebug.org/}; value=[Xdebug]], . I will work on a tutorial on how to use xdebug while writing code in Sublime Text 2. So keep an eye out on my blog and or, A[attributes={href=http://www.youtube.com/jrock20041}; value=[YouTube]], channel for this tutorial.]]]]
So basically what I want is I wall the text including the html elements in the div with the class entry-content. If you want to see the page it can be found here -- http://jcwebconcepts.net/blog/2013/02/02/xdebug/
Thanks for your help
It does work... Save the HTML for this page to a file, then you can parse it.
The following code prints the name of the author of every comment on the page:
#Grab('net.sourceforge.nekohtml:nekohtml:1.9.16')
def parser = new org.cyberneko.html.parsers.SAXParser()
new XmlParser( parser ).parse( file ).with { page ->
page.'**'.A.grep { it.'#class'?.contains 'comment-user' }.each {
println it.text()
}
}
When file is set to be a File pointing to the saved HTML (or a String containing the URL of this question), it prints:
tim_yates
jrock2004
tim_yates
Edit:
To print the contents of a given node, you could do (using the example from your edited question):
#Grab('net.sourceforge.nekohtml:nekohtml:1.9.16')
import groovy.xml.*
def parser = new org.cyberneko.html.parsers.SAXParser()
new XmlParser( parser ).parse( 'http://jcwebconcepts.net/blog/2013/02/02/xdebug/' ).with { page ->
page.'**'.DIV.grep { it.'#class'?.contains 'entry-content' }.each { it ->
println XmlUtil.serialize( it )
}
}

External Content with Groovy BuilderSupport

I've built a custom builder in Groovy by extending BuilderSupport. It works well when configured like nearly every builder code sample out there:
def builder = new MyBuilder()
builder.foo {
"Some Entry" (property1:value1, property2: value2)
}
This, of course, works perfectly. The problem is that I don't want the information I'm building to be in the code. I want to have this information in a file somewhere that is read in and built into objects by the builder. I cannot figure out how to do this.
I can't even make this work by moving the simple entry around in the code.
This works:
def textClosure = { "Some Entry" (property1:value1, property2: value2) }
builder.foo(textClosure)
because textClosure is a closure.
If I do this:
def text = '"Some Entry" (property1:value1, property2: value2)'
def textClosure = { text }
builder.foo(textClosure)
the builder only gets called for the "foo" node. I've tried many variants of this, including passing the text block directly into the builder without wrapping it in a closure. They all yield the same result.
Is there some way I take a piece of arbitrary text and pass it into my builder so that it will be able to correctly parse and build it?
Your problem is that a String is not Groovy code. The way ConfigSlurper handles this is to compile the text into an instance of Script using GroovyClassLoader#parseClass. e.g.,
// create a Binding subclass that delegates to the builder
class MyBinding extends Binding {
def builder
Object getVariable(String name) {
return { Object... args -> builder.invokeMethod(name,args) }
}
}
// parse the script and run it against the builder
new File("foo.groovy").withInputStream { input ->
Script s = new GroovyClassLoader().parseClass(input).newInstance()
s.binding = new MyBinding(builder:builder)
s.run()
}
The subclass of Binding simply returns a closure for all variables that delegates the call to the builder. So assuming foo.groovy contains:
foo {
"Some Entry" (property1:value1, property2: value2)
}
It would be equivalent to your code above.
I think the problem you described is better solved with a slurper or parser.
See:
http://groovy.codehaus.org/Reading+XML+using+Groovy%27s+XmlSlurper
http://groovy.codehaus.org/Reading+XML+using+Groovy%27s+XmlParser
for XML based examples.
In your case. Given the XML file:
<foo>
<entry name='Some Entry' property1="value1" property2="value2"/>
</foo>
You could slurp it with:
def text = new File("test.xml").text
def foo = new XmlSlurper().parseText(text)
def allEntries = foo.entry
allEntries.each {
println it.#name
println it.#property1
println it.#property2
}
Originally, I wanted to be able to specify
"Some Entry" (property1:value1, property2: value2)
in an external file. I'm specifically trying to avoid XML and XML-like syntax to make these files easier for regular users to create and modify. My current solution uses ConfigSlurper and the file now looks like:
"Some Entry"
{
property1 = value1
property2 = value2
}
ConfigSlurper gives me a map like this:
["Some Entry":[property1:value1,property2:value2]]
It's pretty simple to use these values to create my objects, especially since I can just pass the property/value map into the constructor.

Resources