Quantcast

Calling Dynamic Finders on Domain Class via the MetaClass

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Calling Dynamic Finders on Domain Class via the MetaClass

mpwoodward
I'm working on a CFML plugin for Grails that allows CFML and Grails code to run in the same context. I'm about 90% of the way done but I was hoping to be able to call the domain class dynamic finders from CFML code.

Since the CFML code runs via a servlet in the same context, I can access the Grails application context from CFML, so I can call getBean() on the application context.

Using PersonDomainClass as an example, I can call getBean('PersonDomainClass'), and from what I've experimented with, it looks like the dynamic finders exist in that class's metaclass.

So my question is, should I be able to call something like getBean('PersonDomainClass').getMetaClass().invokeMissingMethod() to call the dynamic finders? I've been trying various incarnations of that without success, so this may just be a syntax or datatype issue, but before tearing more hair out I thought I'd ask if I should even expect this to work.

Just so the CFML part isn't a hangup, say I wanted to do this same thing from a JSP page. Is this possible or do other things happen behind the scenes in Grails that make this impossible when you don't go through the normal Grails request cycle?

Thanks for any tips anyone might have on this.

--
Matthew Woodward
[hidden email]
http://blog.mattwoodward.com
identi.ca/Twitter: @mpwoodward

Please do not send me proprietary file formats such as Word, PowerPoint, etc. as attachments.
http://www.gnu.org/philosophy/no-word-attachments.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Calling Dynamic Finders on Domain Class via the MetaClass

burtbeckwith
You can use org.codehaus.groovy.runtime.InvokerHelper from Java:

   List allInstances = (List)InvokerHelper.invokeMethod(SomeDomainClass.class, "list", null));
   Long id = 123;
   SomeDomainClass instance = (SomeDomainClass)InvokerHelper.invokeMethod(SomeDomainClass.class, "get", id);
   InvokerHelper.invokeMethod(instance, "delete", null)

Note that if you pass a Class as the first argument it'll call the corresponding static method. You could also call InvokerHelper.invokeStaticMethod() directly.

Burt

> I'm working on a CFML plugin for Grails that allows CFML and Grails code to
> run in the same context. I'm about 90% of the way done but I was hoping to
> be able to call the domain class dynamic finders from CFML code.
>
> Since the CFML code runs via a servlet in the same context, I can access the
> Grails application context from CFML, so I can call getBean() on the
> application context.
>
> Using PersonDomainClass as an example, I can call
> getBean('PersonDomainClass'), and from what I've experimented with, it looks
> like the dynamic finders exist in that class's metaclass.
>
> So my question is, should I be able to call something like
> getBean('PersonDomainClass').getMetaClass().invokeMissingMethod() to call
> the dynamic finders? I've been trying various incarnations of that without
> success, so this may just be a syntax or datatype issue, but before tearing
> more hair out I thought I'd ask if I should even expect this to work.
>
> Just so the CFML part isn't a hangup, say I wanted to do this same thing
> from a JSP page. Is this possible or do other things happen behind the
> scenes in Grails that make this impossible when you don't go through the
> normal Grails request cycle?
>
> Thanks for any tips anyone might have on this.
>

signature.asc (204 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Calling Dynamic Finders on Domain Class via the MetaClass

mpwoodward
On Wed, Mar 17, 2010 at 8:43 AM, Burt Beckwith <[hidden email]> wrote:
You can use org.codehaus.groovy.runtime.InvokerHelper from Java:


Thanks Burt--getting "no method with that signature" type errors when trying from CFML, but I suspect that may be an issue with passing certain datatypes from CFML to Java. I'll give this a shot in a plain old Java class and if that works I'll just use it as a wrapper that's more friendly to CFML.

Thanks much for the info.

--
Matthew Woodward
[hidden email]
http://blog.mattwoodward.com
identi.ca/Twitter: @mpwoodward

Please do not send me proprietary file formats such as Word, PowerPoint, etc. as attachments.
http://www.gnu.org/philosophy/no-word-attachments.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Calling Dynamic Finders on Domain Class via the MetaClass

mpwoodward
In reply to this post by burtbeckwith
On Wed, Mar 17, 2010 at 8:43 AM, Burt Beckwith <[hidden email]> wrote:
You can use org.codehaus.groovy.runtime.InvokerHelper from Java:

  List allInstances = (List)InvokerHelper.invokeMethod(SomeDomainClass.class, "list", null));

Finally getting a chance to dig into this deeper and had a question regarding the mention of "SomeDomainClass" above. Using Person as a concrete example of a Grails domain class, in the code above would SomeDomainClass be replaced with PersonDomainClass, or just Person?

If it's PersonDomainClass, is this actually the PersonDomainClass object I would get from calling getBean('PersonDomainClass') on org.codehaus.groovy.grails.APPLICATION_CONTEXT or am I misunderstanding how this would be created/retrieved?

I created a Java class to handle some of this but I'm still getting errors, specifically when I use PersonDomainClass that I got via getBean("PersonDomainClass") and have a method in my Java class like this:
public List listTest(DefaultGrailsDomainClass gdc) {
  return (List)InvokerHelper.invokeMethod(gdc, "list", null);
}

When I call that method and pass in the what I get from getBean("PersonDomainClass") I get this error:
No signature of method: org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass.list() is applicable for argument types:() values: []

I also experimented with PersonDomainClass.class in various ways, invokeStaticMethod(), and invokeStaticNoArgumentsMethod() but couldn't get any of this working.

I still have a few combinations of things to try but I suspect I'm missing something fundamental from the examples you provided, so if you can steer me in the right direction I'd greatly appreciate it.

Thanks.

--
Matthew Woodward
[hidden email]
http://blog.mattwoodward.com
identi.ca/Twitter: @mpwoodward

Please do not send me proprietary file formats such as Word, PowerPoint, etc. as attachments.
http://www.gnu.org/philosophy/no-word-attachments.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Calling Dynamic Finders on Domain Class via the MetaClass

burtbeckwith
That should be just Person. This Java

   List allInstances = (List)InvokerHelper.invokeMethod(SomeDomainClass.class, "list", null));

is equivalent to this Groovy:

   List allInstances = Person.list()

Burt

> On Wed, Mar 17, 2010 at 8:43 AM, Burt Beckwith <[hidden email]>wrote:
>
> > You can use org.codehaus.groovy.runtime.InvokerHelper from Java:
> >
> >   List allInstances =
> > (List)InvokerHelper.invokeMethod(SomeDomainClass.class, "list", null));
> >
>
> Finally getting a chance to dig into this deeper and had a question
> regarding the mention of "SomeDomainClass" above. Using Person as a concrete
> example of a Grails domain class, in the code above would SomeDomainClass be
> replaced with PersonDomainClass, or just Person?
>
> If it's PersonDomainClass, is this actually the PersonDomainClass object I
> would get from calling getBean('PersonDomainClass') on
> org.codehaus.groovy.grails.APPLICATION_CONTEXT or am I misunderstanding how
> this would be created/retrieved?
>
> I created a Java class to handle some of this but I'm still getting errors,
> specifically when I use PersonDomainClass that I got via
> getBean("PersonDomainClass") and have a method in my Java class like this:
> public List listTest(DefaultGrailsDomainClass gdc) {
>   return (List)InvokerHelper.invokeMethod(gdc, "list", null);
> }
>
> When I call that method and pass in the what I get from
> getBean("PersonDomainClass") I get this error:
> No signature of method:
> org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass.list() is
> applicable for argument types:() values: []
>
> I also experimented with PersonDomainClass.class in various ways,
> invokeStaticMethod(), and invokeStaticNoArgumentsMethod() but couldn't get
> any of this working.
>
> I still have a few combinations of things to try but I suspect I'm missing
> something fundamental from the examples you provided, so if you can steer me
> in the right direction I'd greatly appreciate it.
>
> Thanks.
>
>

signature.asc (204 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Calling Dynamic Finders on Domain Class via the MetaClass

mpwoodward
On Tue, Mar 23, 2010 at 5:17 PM, Burt Beckwith <[hidden email]> wrote:
That should be just Person. This Java

  List allInstances = (List)InvokerHelper.invokeMethod(SomeDomainClass.class, "list", null));

is equivalent to this Groovy:

  List allInstances = Person.list()



Perfect--working like a champ now. Thanks for all the help.

--
Matthew Woodward
[hidden email]
http://blog.mattwoodward.com
identi.ca/Twitter: @mpwoodward

Please do not send me proprietary file formats such as Word, PowerPoint, etc. as attachments.
http://www.gnu.org/philosophy/no-word-attachments.html
Loading...