I would like to externalize all my string constants in my groovy classes to a properies file, and then have them called from there. I have seen the example with the configslurper, want to know how can I make the design such that I just include/import/load the resource/property file in my class and call the property I want to on it..
something like this in my controller
include/load propertyfilename
if (propertyfilename.propertyname == mygroovyVar) {
....some code
}
i.e if possible I want to avoid using "(quotes) when retrieving properties anywhere
like the resource bundle setup for properties in spring mvc
Regards
Priyank
You can do something like this:
something.groovy:
def loadConfig(environment,settingFileName) {
levelConfig = new ConfigSlurper().parse(new File(settingFileName).toURI().toURL())."$environment"
}
To access it :
def configFile = loadConfig("alpha","c:\somewhere\something.properties"
assert configFile.currlevel = "alpha"
something.properties:
alpha {
currlevel = "alpha"
}
beta {
currlevel = "beta"
}
prod {
currlevel = "prod"
}
If you dont want the environment tweak it a bit. Hope this can help.
Related
I'm new to Gradle and Groovy.
I have something like this in my build.gradle file:
jacocoTestReport {
afterEvaluate {
classDirectories.setFrom(files(classDirectories.files.collect {
fileTree(dir: it, exclude: ['aaa/bbb.*', 'ccc/ddd/*',])
}))
}
}
Now, I need this in my custom plugin. But I'm not sure how to set these excludes to it.
I have something like this:
project.afterEvaluate { p ->
def reportTask = project.tasks.findByName('jacocoTestReport') as JacocoReport
reportTask.classDirectories.setFrom(reportTask.classDirectories.files.) // Now what?
}
And I'm stuck here. Can you help me sort this out, please?
EDIT1:
I tried to solve it using patternSet.
println '----------------BEFORE REPORT----------------------'
def patternSet = new PatternSet()
def filesAsString = reportTask.classDirectories.files.collect { file ->
file.path
}
patternSet.setIncludes(filesAsString)
patternSet.setExcludes(['aaa/bbb.*', 'ccc/ddd/*'])
def excludeFiles = reportTask.classDirectories.asFileTree.matching(patternSet).files
println filesAsString
println excludeFiles
def files = reportTask.classDirectories.asFileTree.minus(excludeFiles)
reportTask.classDirectories.setFrom(files)
println '----------------AFTER REPORT----------------------'
println reportTask.classDirectories.files
Result is not what I expected:
----------------BEFORE REPORT----------------------
[aaa\bbb\build\classes\java\main, aaa\bbb\build\classes\groovy\main, aaa\bbb\build\resources\main]
[]
----------------AFTER REPORT----------------------
[]
No exclude directories at all.
So, I somehow solved it.
def ex = ['aaa/bbb/*','ccc/ddd.*','eee/fff/*']
def ft = reportTask.classDirectories.asFileTree.matching {
ex.each {
exclude it
}
}
Don't ask me how Gradle wraps this since it's not a Groovy syntax, but it works.
My opinion is that Gradle somehow implements AntlrTask as a pattern matcher since it implements interface 'PatternFilterable' and documentation mentions Ant. I tried to solve it in pure Groovy using PatternSet which is another class implementing PatternFilterable but I haven't succeded.
But the simple exclude 'aaa/bbb/*' works OK. It doesn't take list so I had to do it using forEach cycle. Maybe there is more simple and elegant way and I'll try to play with it but this solution is good enough.
Is there any way to define an index template with the API of elasticsearch-groovy or elasticsearch-java? I want to apply "settings" (custom analyzers) and "mappings" (apply analyzer on fields) on it. The documentation only refers to index templatex but does not show a vaild example, how to apply them in a groovy closure. The example shown in the docs, adds the "settings" in the data (source) field.
edit: #Val Thank you for your reply, but if I use the source field as follows:
def templateR = client.admin.indices.putTemplate {
name "template_name"
source {
template "template_*"
}
}.actionGet()
... this results in a compiler-error: MissingMethodException No signature of method: ...source(). The following code:
def templateR = client.admin.indices.putTemplate {
name "lemato_template"
template "lemato_*"
settings {
number_of_shards= 1
}
}.actionGet()
gives me the compiler error No such property: number_of_shards. I'm not sure if I use the closure delegation correctly. Is something like .asMap() missing?
elasticsearch-groovy definitely provides support for creating/deleting index templates. The source closure may contain anything you can define for index templates. Something like this should work.
PutIndexTemplateResponse response = client.admin.indices.putTemplate {
name "my_template"
source {
template "index_*"
settings {
index {
number_of_shards = 5
number_of_replicas = 1
}
}
mappings {
// your mapping definitions
}
aliases {
// your aliases
}
}
}.actionGet()
I have an application which can run scripts to automate certain tasks. I'd like to use meta programming in these scripts to optimize code size and readability. So instead of:
try {
def res = factory.allocate();
... do something with res ...
} finally {
res.close()
}
I'd like to
Factory.metaClass.withResource = { c ->
try {
def res = factory.allocate();
c(res)
} finally {
res.close()
}
}
so the script writers can write:
factory.withResource { res ->
... do something with res ...
}
(and I could do proper error handling, etc).
Now I wonder when and how I can/should implement this. I could attach the manipulation of the meta class in a header which I prepend to every script but I'm worried what would happen if two users ran the script at the same time (concurrent access to the meta class).
What is the scope of the meta class? The compiler? The script environment? The Java VM? The classloader which loaded Groovy?
My reasoning is that if Groovy meta classes have VM scope, then I could run a setup script once during startup.
Metaclasses exist per classloader [citation needed]:
File /tmp/Qwop.groovy:
class Qwop { }
File /tmp/Loader.groovy:
Qwop.metaClass.bar = { }
qwop1 = new Qwop()
assert qwop1.respondsTo('bar')
loader = new GroovyClassLoader()
clazz = loader.parseClass new File("/tmp/Qwop.groovy")
clazz.metaClass.brap = { 'oh my' }
qwop = clazz.newInstance()
assert !qwop.respondsTo('bar')
assert qwop1.respondsTo('bar')
assert qwop.brap() == "oh my"
assert !qwop1.respondsTo('brap')
// here be custom classloaders
new GroovyShell(loader).evaluate new File('/tmp/QwopTest.groovy')
And a script to test the scoped metaclass (/tmp/QwopTest.groovy):
assert !new Qwop().respondsTo('bar')
assert new Qwop().respondsTo('brap')
Execution:
$ groovy Loaders.groovy
$
If you have a set of well defined classes you could apply metaprogramming on top of the classes loaded by your classloader, as per the brap method added.
Another option for this sort of thing which is better for a lot of scenarios is to use an extension module.
package demo
class FactoryExtension {
static withResource(Factory instance, Closure c) {
def res
try {
res = instance.allocate()
c(res)
} finally {
res?.close()
}
}
}
Compile that and put it in a jar file which contains a file at META-INF/services/org.codehaus.groovy.runtime.ExtensionModule that contains something like this...
moduleName=factory-extension-module
moduleVersion=1.0
extensionClasses=demo.FactoryExtension
Then in order for someone to use your extension they just need to put that jar file on their CLASSPATH. With all of that in place, a user could do something like this...
factoryInstance.withResource { res ->
... do something with res ...
}
More information on extension modules is available at http://docs.groovy-lang.org/docs/groovy-2.3.6/html/documentation/#_extension_modules.
I'm using Gradle as a build system for my project.
What I want is to make task A depend on task B if a given property is set to "true". Is this doable, and if the answer is yes, how can I do that?
Currently, I'm using conventionMapping but this doesn't seem to work. My code looks like this:
MyTask.conventionMapping.propertyName = { MyPluginConvention.propertyName }
if (MyTask.propertyName.equals("true")) {
MyTask.dependsOn ...
}
Thanks in advance,
Marin
Instead of working with task/convention classes, you'll have to work with their instances. Also, you'll have to defer the decision whether to add a task dependency. For example:
def myTask = project.tasks.create("myTask", MyTask)
def otherTask = ...
def myConvention = new MyConvention()
...
myTask.conventionMapping.propertyName = { myConvention.propertyName }
// defer decision whether to depend on 'otherTask'
myTask.dependsOn { myTask.propertyName == "true" ? otherTask : [] }
If there's no task variable in scope, you can also reference existing tasks via project.myTask or project.tasks["myTask"].
PS: Convention objects have been largely replaced by extension objects.
a little question about erazor https://github.com/ciscoheat/erazor
i know this framwork is based on Razor template engine. http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx
i noticed the api doesn't fit exactly with Razor (ex: #for(a in p) differs from RAZOR)
this template system for haxe is very handy...
i just don't know how to setup a variable like we do in templo ( :: set mock="tada!":: )
//#scope is mycontroller;
#{var mock = scope.getMock()}
#if(mock!=null){
//display some html
}
any tips ?
thx
The following snippet works:
import erazor.Template;
import neko.Lib;
class Main {
static function main() {
var template = new Template("#{var mock = scope.getMock();} #if (mock != null) { #mock }");
Lib.print(template.execute( { scope : { getMock : function() return "hi" } } ));
}
}
What you missed is that inside a code block all the statements must be correctly closed (missing ;). Also erazor is loosely based on Razor and uses the Haxe syntax for expressions.