Ambuj Jauhari
Ambuj Jauhari

Reputation: 1299

MethodIntercept with groovy

I have written a small piece of code in groovy. I have 2 methods 1) generateAll and other 2) validate. The idea was to intercept the call to generateAll. Validate the input first and then proceed for generateAll. I don't know why but this.metaClass.getMetaMethod(name, args) always gives me null for validate method. However if I don't pass the arguments it finds the method but later breaks because of wrong number of arguments passed.

class CreateAllScripts implements GroovyInterceptable {
   void generateAll(String configName) {
   //DO some stuff
   }

   def invokeMethod(String name, args) {
      if (name == 'generateAll') {
         //First validate the config
         validate(args);
      }
      def method = this.metaClass.getMetaMethod(name, args)
      method.invoke(this, args)
   }

   private void validate(String configName) {
      println("Validating")
      //perform some validation.
   }
}

Upvotes: 0

Views: 59

Answers (1)

Opal
Opal

Reputation: 84844

The problem lies in how you pass arguments to validate. * operator should be used:

class CreateAllScripts implements GroovyInterceptable {
    void generateAll(String configName) {
        System.out.println("generating: $configName")
    }

    def invokeMethod(String name, args) {
        System.out.println("$name $args")
        if (name == 'generateAll') {
            validate(*args)
        }
        def method = this.metaClass.getMetaMethod(name, args)
        method.invoke(this, args)    
    }

    private void validate(String configName) {
        System.out.println("validating: $configName")
    }
}
new CreateAllScripts().generateAll('aaa')

If simply validate(args) is called the output will be:

generateAll [aaa]
validate [[aaa]]
Exception thrown

Do you see that aaa was wrapped into a second list? That causes the problem. There's no method with name validate that accepts a collection.

Now, validate(*args) gives the following output:

generateAll [aaa]
validate [aaa]
validating: aaa
generating: aaa     

Which is correct. On dynamic method invocation args should be generally passed with *.

Upvotes: 1

Related Questions