1
votes

It has been a couple of days since I started with Groovy. But with all the reading and surfing, I haven't quite been able to figure out how to accomplish what I have in mind. So, please excuse me as a beginner. Would be much grateful for your help, as always.

What I want to achieve is this: I have a Java class, say ServiceClass that has some methods (getMethod(), postMethod() etc) to make some REST GET/POST requests (on its own, it works fine). Now, I want to expose a DSL so that the end-user may just say something like: callService ServiceClass method getMethod and I have the execution of ServiceClass.getMethod()

What I have been trying so far is this: I got a userCommand file placed somewhere, that for now just reads: callService ServiceClass

I have a sample.groovy that just does this now:

class Sample {
    def srvc
    def callService(srvc) {
        this.srvc = srvc
        "Calling $srvc"
    }
}

I got an integrator.groovy file that has:

//necessary imports
class Integrator{
    def sample = new Sample()
    def binding = new Binding([
        sample:sample, 
        ServiceClass: new ServiceClass(), 
        callService:sample.&callService ])
    def shell = new GroovyShell(binding)

    def runIt() {
        shell.evaluate("userCommand")
    }
}

And then to run it from my Java application, I am doing:

public static void main(String[] args) {
    Integator i = new Integrator()
    i.runIt();
}

But this is just not working. With the above syntax it says:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke method setVariable() on null object....

Could anyone please tell me how do I pass around parameters and create object instances?

1
What happens when you try? "not working" does not tell us what your problem is. - bmargulies
@bmargulies: have added the error message seen. Actually, am not even sure if the adopted approach is correct. So would like someone to guide me in how to have the whole thing working. - 5122014009

1 Answers

1
votes

Update: Consider the following userCommand file:

File userCommand:

callService ServiceClass getMethod

Which will be parsed by groovy as callService(ServiceClass).getGetMethod(). So you need a getProperty method which reroute the call to the correct method:

File Dsl.groovy:

class Dsl {
  static void main(args) {
      new Integrator().runIt()
  }
}

class DslDelegate {
    def service
    def callService(service) {
        this.service = service
        this
    }

    def getProperty(String prop) {
      if (prop == "getMethod") { service.getMethod() }
      else { throw new RuntimeException("Unrecognized property '$prop'") }
    }
}

class ServiceClass {
  def getMethod() { "serviceClass getMethod" }
}

class Integrator{
    def dslDelegate = new DslDelegate()
    def binding = new Binding([
        ServiceClass: new ServiceClass(), 
        callService:dslDelegate.&callService ])
    def shell = new GroovyShell(binding)

    def runIt() {
        assert shell.evaluate(new File("userCommand")) == 
            "serviceClass getMethod"
    }
}

Note I renamed the Sample class, so it becomes a delegator to ServiceClass. Now it separates DSL/Service responsibilities.

You can do callService ServiceClass method getMethod too, but it requires more code.