Populate List<Callable<String>> in Groovy with Groovy objects - groovy

In What JVM-based scripting language support #WebService to create services at runtime? I was suggested to use Groovy to provide web services configured in a script read in at runtime.
To make this work with our existing infrastructure I need essentially to be able to add new entries to a List<Callable<String>> which I then can ask an executor to invokeAny upon.
The basic structure will be something like:
Groovy is embedded using GroovyScriptEngine
Initial list passed in from Java as "l" in the Binding passed in.
Groovy script defines and instantiates N objects, all implementing Callable<String> and add them to the list.
Back in Java the list is then further processed and then passed to the executor.
My initial feeble steps show that I will most likely need to use def c = { ... } as Callable<String> but then I get a ClassCastException. Reading up I see that it appears that this is a bit hard and involves closures.
What is the correct way to define and instantiate an object in Groovy which implements Callable<String>?

In Groovy 1.8 and later, groovy.lang.Closure implements Callable by default so you don't need any "as" magic., simply:
l << { "hello" }
l << { "world" }
For earlier versions of Groovy (1.6 and 1.7 certainly, not sure about "ancient" versions) you need to use as:
import java.util.concurrent.Callable
l << ({ "hello" } as Callable)

Related

SOAPUI context variables - How does Groovy make this possible?

Sorry to all you Groovy dudes if this is a bit of a noob question.
In SOAPUI, i can create a Groovy script where i can define an arbitrary variable to the run context to retrieve at a later time.
context.previouslyUndefinedVariable = 3
def num = context.previouslyUndefinedVariable
What feature of Groovy allows previously undefined variables to be added to an object like this? I would like to learn more about it.
Many thanks in advance!
Groovy has the ability to dynamically add methods to a class through metaprogramming.
To learn more, see:
What is Groovy's MetaClass used for?
Groovy Goodness: Add Methods Dynamically to Classes with ExpandoMetaClass
Runtime and compile-time metaprogramming
The accepted answer is a bit of a poor explanation for how SoapUI is doing it.
In this case, context is always an instance of some SoapUI library java class (such as WsdlTestRunContext), and these are all implementations of Map. You can check context.getClass() and assert context in Map.
When you look up a property on a Map, Groovy uses the getAt and putAt methods. There are various syntaxes you can use. All of these are equivalent:
context.someUndef
context.'someUndef'
context[someUndef]
context['someUndef']
context.getAt('someUndef')
And
context.someUndef = 3
context.'someUndef' = 3
context[someUndef] = 3
context['someUndef'] = 3
context.putAt('someUndef', 3)
I like to use any of the above that include quote marks, so that Groovy-Eclipse doesn't flag it as a missing property.
It's also interesting that Groovy looks for a getAt() method before it checks for a get method being referred to as a property.
For example, consider evaluating "foo".class. The String instance doesn't have a property called class and it also doesn't have a method getAt(String), so the next thing it tries is to look for a "get" method with that name, i.e. getClass(), which it finds, and we get our result: String.
But with a map, ['class':'bar'].class refers to the method call getAt('class') first, which will be 'bar'. If we want to know what type of Map it is, we have to be more specific and write in full: ['class':'bar'].getClass() which will be LinkedHashMap.
We still have to specify getClass() even if that Map doesn't have a matching key, because ['foo':'bar'].class will still mean ['foo':'bar'].getAt('class'), which will be null.

How do I compile a groovy user entered script at runtime

I want to compile and execute a piece of Groovy that the user types in (in a DSL) at runtime. Is this possible in Groovy? And if so what's the best way to do it?
You can use the GroovyClassLoader:
def userScript = '''
(1..5).each {
println 'X' * it
}
'''
Class c = new GroovyClassLoader().parseClass( userScript )
c.newInstance().run()
Or you can use any of the other methods in the documentation for integrating Groovy.
you might want to use the concept of binding in groovy which helps you to inject variables from outside and process them.
http://mrhaki.blogspot.in/2010/08/groovy-goodness-store-closures-in.html

groovy singleton pattern

Q1. What is the best way to implement the singleton pattern using groovy? What are the other options available in groovy to support the singleton mechanism?
Any example that would be useful.
Q2. Does groovy support something like File changed listener?
Q1
You can make any class a singleton simply by adding a #Singleton annotation (since groovy v1.7.0 at least):
#Singleton
class MyClass {
}
You can then access the singleton instance with
MyClass singleton = MyClass.instance
Q2
I think you're asking if Groovy provides a listener which is called every time a file is changed? I am not aware of any such facility in Groovy. If such a class exists you're more likely to find a Java implementation (which you could use in your Groovy program).
Regarding Q2: while groovy itself doesn't provide any way to be notified on file changes, Java 7, which can be used with groovy, does.
In particular, if you want to watch for file changes on a file foo in the current directory, you can do something like this:
import java.nio.file.*
FileSystems.default.getPath(".") // dot for current directory
def watchKey = p.register(FileSystems.default.newWatchService(),
StandardWatchEventKinds.ENTRY_MODIFY)
def events = watchKey.pollEvents()
events.findAll{it.context().fileName == 'foo'}.each { event ->
println "foo was changed"
}

How Does "Use" work in groovy?

Hi I have the following Code Snippet;
class StringCalci
{
static def plus(Integer self, Integer Operand)
{
return self.toInteger() * Operand.toInteger()
}
}
use (StringCalci)
{
println("inside the Use method!")
println( 12 + 3 )
}
println(12+3)
I was been shocked to see the use of Use in groovy. The thing is this I can add methods to the Class at run-time(my own methods).when I was looking at the above code, I was Thinking how does Groovy make things possible like this! The use of println inside the Use is multiplying the two given numbers(because I have Override the plus method) , where as the outside println adds it! My question is how does Groovy recognise the println executes in Use and println outside the Use. Is Use is a keyword/method? I need to understand behind the scenes of this process.. Please let me know :)
Thanks in Advance :)
Welcome to the wonderful world of dynamic languages where everything is possible and nothing is certain!
This feature is called Categories. As for the implementation:
use is in fact not a keyword but a method which the Groovy runtime adds to the Object class, which makes it available everywhere.
I think the functionality is implemented mainly in the class GroovyCategorySupport
Judging from the Javadoc, it's based on keeping a map of overriden methods in a ThreadLocal which is then consulted for every method call.
yeah, that's not so great for performance, but so are pretty much all the dynamic "magic" features that Groovy and similar languages offer (and there's lots of them).

Is it possible to automatically preload user classes into the groovy interpreter?

Is there any way to automatically load user classes in the groovy interpreter, the way System.out is automatically loaded (so you don't have to import System.out to use println)? I want to be able to write scripts that employ custom classes and run the scripts in the groovy interpreter without having to import all the classes all the time.
Yep, you just need to create a profile/rc file. Just create a file at ~/.groovy/groovysh.profile and put your imports in there. You'll also want to make sure that any additional classes you want to include are part of your CLASSPATH.
ex: ~/.groovy/groovysh.profile:
import org.apache.commons.lang.StringUtils
println "in groovysh.profile"
Then run groovysh and use a method from StringUtils:
% groovysh
in groovysh.profile
Groovy Shell (1.7.3, JVM: 1.6.0_20)
Type 'help' or '\h' for help.
---------------------------------------------------------------------------------------------------------------------------------
groovy:000> StringUtils.isWhitespace(" ")
===> true
groovy:000>
You can see that the import is in place (and that it also printed out the println I had in the profile. This example will only work if you've got the commons-lang jar file is in your classpath.
See the Groovy Shell page for more details.
Groovy adds some methods to Object, including methods like println and printf that you'd expect on printWriters. They implicitly use System.out. This is actually how groovy makes if feel like System.out is globally available.
If you want to import a set of classes by default, so they can be used without specifying the full package name, Ted's comment about groovysh.profile applies.
However, if you want a specific object, like System.out, global available so its methods can be called without referencing the object, then you can add some dynamic methods to Object. For example, to make the logging methods of the default global JDK logger globally available:
Object.metaClass.info = { String message ->
java.util.logging.Logger.global.info(message)
}
Object.metaClass.warning = { String message ->
java.util.logging.Logger.global.warning(message)
}
Object.metaClass.severe = { String message ->
java.util.logging.Logger.global.severe(message)
}
etc...
Once those methods are applied to the base Object metaClass, any object can call info("message") and have it logged, effectively making Logger.global available in the same way System.out is.

Resources