Difference between two action signatures in grails - grails

In grails we can define an action using 2 ways:-
def actionname()
{
}
and
def actionname = {
}
What is the difference between the two styles? When I tried to insert a spring security annotation above the action (second style) it said "#Secured" not applicable to field.
What does this mean? Is it because of closure?

The Grails reference docs 7.The Web Layer mentions the use of closures for controller actions in earlier versions of Grails, the preference is now to use methods. However, both are supported. It goes on to list some benefits of using methods instead.
Personally, I use methods in all my controllers and have also come across the issue with annotations such as #Secured that only work on methods and not the closures.

In earlier versions of Grails option 2 (actions as closures) was the only supported style. Grails 2.x introduced the actions-as-methods style and this is now the recommended approach, but the closure style is still supported for backwards compatibility and you'll see it if you are working on an app (or plugin) that was originally written on Grails 1.x.

The first is normal method definition with undefined return type.
The second is an assigment of a closure to a property 'actionname'.
That is why you get "#Secured" not applicable to field message, because this annotation is for methods only.
Shuttsy is correct that that the first way is now a preffered way to define actions in Grails.

This is an agreeable way of defining methods in Groovy at minimal level having the structure above.
The second way of defining is not refering to a method definition rather it's somehow a rule like closure constraints that governs a given class or method. Like when it is used in domain class .
Example
class Person {
String name
Person parent
static belongsTo = [ supervisor: Person ]
static mappedBy = [ supervisor: "none", parent: "none" ]
static constraints = { supervisor nullable: true }
//this allowed for methods only and why you got an error in above cases
#override
def toString(){
return name.toString()
}
}
#Secured annotation accept list of roles (String[])
it is used only for a method definition based on
toString() method inside the class ...i just give u a scenario of the two ..

#Secured annotation since spring security 2.0 supports method only. As a result, you have to convert closures to real methods if you want to apply the security annotation for it. Read more #Secured Annotation.

Related

Why is #override annotation optional?

I understand definition of an #override annotation.
But, why is the usage of the annotation optional?
From the documentation:
The intent of the #override notation is to catch situations where a superclass renames a member, and an independent subclass which used to override the member, could silently continue working using the superclass implementation.
You might want to name your method equal to the super class without explicitely overriding it. This is allowed as it does not break any constraints.
Basically you can name your methods whatever you want.
#Override only enforces, that one of your parents has to have a method with the same signature.
The annotation wasn't made part of the language because the language designers didn't want to enforce its use.
It has been added as an optional annotation for people who want the feature, but it's only recognized by the analyzer tool, it's not actually part of the language.
You can enable a linter rule to enforce it
http://dart-lang.github.io/linter/lints/annotate_overrides.html
by adding an .analysis_options file to your project besides the pubspec.yaml file with this content
linter:
rules:
- annotate_overrides
Because the name of the method is looked up in the inheritance chain: for example, let's look at this inheritance chain:
A
|
B
|
C
if we create an instance using class C and invoke a method test(), then the definition of test is first looked in the body of class C, then class B, then class A. Thus, the overriding effect is automatically implied.
The effect is similar to what observed in C++, and for a detailed read please check out this link:
https://isocpp.org/wiki/faq/strange-inheritance#hiding-rule
The reason of the existence of the annotation is clearly stated above by Abaddon666.

What is a good way to provide common methods to all of my services in Grails?

Do you suggest that I use Inheritance, Mixins, ExpandoMetaClass or something else?
If your common methods are largely related to one another, use inheritance from a common class containing them.
If however you have separate concerns and would benefit from grouping them into more than one file, I suggest traits - they have deprecated Groovy's #Mixin annotation.
I'm using them to decorate my controllers and they have worked out very nicely. I have read somewhere that the Grails team is also going to use them to replace the 'magic' metaclass decoration of artefacts like controllers (which is how methods like render are currently provided).. can't find the link, though :(
If you want to add this behavior to services in your application and also those from plugins, use the getServiceClasses() dynamic method in GrailsApplication and add to their metaclasses, e.g.
def grailsApplication
....
grailsApplication.serviceClasses.each { sc ->
sc.clazz.metaClass.foo = { bar -> ... }
}

Generic method interception in grails (specifically Controllers)

I'm trying to create a generic function in grails that will allow me to specify a class and function name, and intercept any function calls based on that criteria:
getSomeClass().metaClass.invokeMethod = { String methodName, args ->
MetaMethod someAction = getSomeClass().metaClass.getMetaMethod(methodName, args)
def result = someAction.invoke(delegate, args)
if (methodName==getSomeMethodName())
intercept(args, result)
return result
}
This works for POGO, and domain classes, but does not seem to work for controller classes. While I'm fully aware there are Controller interceptors and filters available in Grails, these don't really centralise what I'm trying to achieve, and was trying to create a simple generic function for some centralised behaviour
Any guidance on why this doesn't work on Controllers would be appreciated, thanks
Your approach will work for method calls that are made through the Groovy metaclass mechanism, but in Grails 2 this doesn't apply to controller actions - they're called using normal Java reflection (java.lang.reflect.Method.invoke), and therefore your custom invokeMethod is bypassed.
If you want an AOP mechanism that'll work for calls from Java as well as from Groovy you'll probably have to use something like AspectJ load-time weaving. Spring's proxy-based AOP may work but the Grails 2 controller system relies on the action methods having a particular #Action annotation (which is added at compile time by an AST transformation) and I don't know whether Spring AOP proxies preserve method annotations from the target class on the generated proxy methods.
Could it be that MyController.metaClass.invokeMethod is overwritten by the grails framework after your definition?
Have you tried to check the content of MyController.metaClass.invokeMethod through reflection?

How to declare and define methods and closures in groovy

How to declare a method inside a closure.Or which is better to use method or closure.
I have a closure and in that closure i have a method to call and i defined method as
def getBindedGenes(Long colId) {
........
}
But when i used codenarc plugin for code review it is showing the rule as GrailsPublicControllerMethod and the message as The Grails controller has a public method getBindedGenes. This should be a closure property or moved
What is the cause and what is happening exactly.
Thanks in advance
I think CodeNarc is warning you that your controller actions must be public closures, not public methods. Given that you can't use a public controller method as an action, there's probably no good reason to have one.
Grails 2.0 Update
Since Grails 2.0, public methods of controllers can be used as actions, and if fact, it is now recommended to use methods instead of closures.

Distinguishing between Grails domain-class fields and getBlah() methods via GrailsDomainClassProperty

I'm writing a Groovy script (as part of a Grails plugin) and I want to get a list of properties for a GrailsDomainClass that a user of my plugin might define. I can do this using domainClass.properties (where domainClass is a GrailsDomainClass).
However, suppose a user has the grails domain class:
class Example {
String name
static constraints = {
}
def getSomeNonExistingProperty(){
return "Not-a-real-property"
}
}
In this case, domainClass.properties returns a list with both name and someNoneExistingProperty
I understand that this is because of Grails is generating a read-only property on-the-fly for use where someone has a getBlah() method. That's great, but in my script I want to perform some actions with the "real" properties only (or at least non read-only properties).
That is, I would like some way of distinguishing or identifying someNonExistingProperty as a read-only property, or, alternatively, as a property generated by Grails and not entered explicitly as a field in the domainClass by the user of my plugin.
I've looked at the GrailsDomainClassProperty Class and it has a range of methods providing information about the property. However, none of them appear to tell me whether a property is read-only or not, or to allow me to distinguish between a field defined in the domainClass and a field created on-the-fly by Grails as a result of a "getSomeNonExistingProperty()" method.
Am I missing something obvious here? Is there a way of getting a list of just the explicitly user-defined fields (eg name, in the above example)?
I believe transient properties are what you are trying to exclude
I've run into this problem a few times, and instead of trying to work around it I typically just end up renaming my getX() method. It's probably the easiest option.
Edit:
Alternatively, I wonder if you could use reflection to see which methods are defined on the class, and while iterating over your properties see if the property has an explicit getter defined, and omit it. I'm not very familiar with reflection when it comes to Groovy and Grails, especially with the dynamic methods, but it's a possible route of investigation.

Resources