I was wondering if anyone had an idea for the best way to provide the
functionality of bindData() outside of my grails controllers. In my current
project I have created several groovy classes to model objects returned by
an api. In these classes I have a static method that parses xml and returns
a List of objects of the class. I would like to skip all the type casting
nonsense by using the bindData method in these classes. Any suggestions on
how to do this would be appreciated.
I was looking for a similar solution, to use bindData in a service class. I found a solution in JT's blog. The solution is basically to import:
import org.codehaus.groovy.grails.web.metaclass.BindDynamicMethod
then add this to your code:
def foo = new Foo()
BindDynamicMethod bind = new BindDynamicMethod()
def args = [ foo, params, [exclude:['name', 'mail']] ] // for example
bind.invoke( foo, 'bind', (Object[])args)
The (Object[]) cast is necessary du to Groovy/Java compatability. (Groovy is treating the ‘args’ object as an ArrayList, not an array of Objects.)
Related
I'm trying understand what's the mean of this two final lines of code, on colons... It's a syntax question.
I'm following this github example and I have this doubt on my head.
Can someone help me with this?.
class DietPlan extends ParseObject implements ParseCloneable {
DietPlan() : super(keyDietPlan);
DietPlan.clone() : this();
The part after : is called "initializer list.
It is a list of expressions that can access constructor parameters and can assign to instance fields, even final instance fields.
The first colon, i.e. DietPlan() : super(keyDietPlan); means that you are calling the super constructor, constructor of ParseCloneable in this case.
This is a core OOP concept, you can extend or implement one class to another and you must call the superclass constructor if you do so. This is just a style of doing the same in Dart.
The second colon works in similar way, to understand that you need to understand what is cloning of objects,
Object cloning refers to creation of exact copy of an object. It creates a new instance of the class of current object and initializes all its fields with exactly the contents of the corresponding fields of this object.
This is whats happening on the second line.
I am using Grails 2.4.4. In a controller I have used a command object for handling input from a view. That works fine. But now I want to use subclasses for command objects. Depending on some id in the params I want create a specific subclass for the command object. Next I want to fill this command object using this syntax:
def finish() {
final commandObject = createSubclassInstance(params.task.id)
commandObject.properties = params
...
}
The latter assignment fails with the error message "Cannot set readonly property: properties for class: ".
I read in the documentation that the properties field works for domain classes. Does it not work for subclasses of command objects?
If you want to bind properties from the request to a command or any other object, you can use:
org.codehaus.groovy.grails.web.binding.DataBindingUtils.bindObjectToInstance(command, params)
This and the other static methods of the DataBindingUtils class are the real underlying methods that Grails uses to bind commands/domains with all the Grails binding features (listeners, binding annotations like #BindUsing, ...) and validate it, returning a BindingResult object. If you handle the properties property, you are loosing a lot of great binding features from Grails.
PS: Pay attention with these methods you can bind from params, a Map, the request (if the request hava a POST with a JSON).
I've been working with Dart for a few weeks now, and so far so good. I've run into a problem, however, when trying to access variables from a class that's a few levels higher. I'm not sure how best to explain this without an actual sample, so here's a quick example:
http://pastebin.com/r2ru6G2w
To put this as simply as possible:
AClass has a variable named "parameter."
BClass inherits from AClass, also has a constructor parameter (incomingParameter) that is assigned to the "parameter" variable from AClass.
CClass inherits from BClass, also has a constructor parameter (incomingParameter) that is simply passed on to BClass via the super initializer.
DClass inherits from CClass, but does not have any constructor parameter. Instead, I'm trying to pass the "parameter" variables all the way from AClass into the super initializer.
This results in an error, that says "Only static members can be accessed in initializers." Fair enough. Any idea how to get around this?
Thanks for all the help,
MR
I have a loop in my controller that does something like this:
for(d in grailsApplication.domainClasses) {
def c = d.getClazz().count()
// construct table containing object instance counts
}
My intent is to use this loop to count the instances of non-leaf domain classes in my database. Is there a way to query the domain class itself to find out if it is abstract or not? I wasn't sure if there were some member functions automatically added by the framework since I am still new to Groovy/Grails. I couldn't find anything that addressed it in the Grails documentation.
Figured it out after a few minutes of poking around the Groovy documentation. The function isAbstract() can be invoked on the domain class to determine whether or not the domain class is a leaf node in the class hierarchy
I'm trying to use jason-io to serialize/deserialize MyClass instances. The jason-io library has two classes, JsonWriter and JsonReader which respectively perform serialization and deserialization. Both operations are invoked from a Grails controller.
During serialization a JSON object containing, among other things, class names is created. Deserialization fails at Class.forName("...MyClass"). The class name is correct.
I've traced the problem and found that the class loader of MyClass is a (java.net) URLClassLoader, but the JsonReader class loader is a (org.codehaus.groovy.grails.cli.support) GrailsRootLoader. I don't know how to fix this, though.
Thanks
This may be linked to a known issue in groovy. The solution in that bug report is to specify the class loader:
def file = new File('thingy.txt')
file.withObjectInputStream(getClass().classLoader){ ois ->
def yourObject = ois.readObject ( )
}
The withObjectInputStream method is available in groovy on other classes too, for example I used this successfully with an instance of GZIPInputStream.