« Return to Thread: a standard way to enhance the GDK using Java code using META-INF/services/groovy/groovyMethods files...

Re: a standard way to enhance the GDK using Java code using META-INF/services/groovy/groovyMethods files...

by Joachim Baumann :: Rate this Message:

Reply to Author | View in Thread

Hi James,

first of all, never having met you, let me say: A big thanks for
inventing Groovy, even if you went on to greener (or at least other)
pastures. :-)

You can add your own metaclasses by simply placing them in the right
spot. Here is an example:

---------------------------------------------------------------------
package groovy.runtime.metaclass.de.groovybuch.kap7

import java.lang.reflect.Modifier

class ExtendMeMetaClass extends MetaClassImpl {
    ExtendMeMetaClass(MetaClassRegistry registry,
                      Class objClass) {
        super(registry, objClass)
        getClass().declaredMethods.each { method ->
            if(Modifier.isStatic(method.modifiers)
                    && !method.name.contains('$')) {
                addNewInstanceMethod(method)
            }
        }
        super.initialize()
    }
    static addedMethod(obj, name){
        return "Hallo, $name"
    }
}
---------------------------------------------------------------------
This metaclass is used for the class de.groovybuch.kap7.ExtendMe. The
metaclass is named after the class for which it is used
(<classname>MetaClass) and placed in the package
groovy.runtime.metclass.<package of class>.

Now this metaclass simply adds all static methods it contains to the
methods of the class. In the simple case above this is only the method
addedMethod, that when called like this

extendMe.addedMethod("James)

returns "Hallo, James".

Since this class is packed into your jar, it can never be lost.

This an existing mechanism you could use. The one remaining problem: You
have to create a metaclass like the above one for every class you
modify. But in my opinion this is not really a disadvantage, because the
association is quite clear.

Cheers, Joachim

James Strachan schrieb:

> I've just got an excuse to play with Groovy again after a rather long
> quiet time; I'm busy hacking a little Groovy DSL for Apache Camel...
> http://activemq.apache.org/camel/
> (I can imagine the logo already BTW; a camel with shades and flared
> disco trousers... ;-)
>
> Firstly - great work everyone! Groovy's really come on in leaps and
> bounds since I last used it. Also the IDEA plugin is amazing! (I found
> I had to use the latest EAP; I struggled with 7.0 M2 to no avail).
>
> So I found the easiest way to implement my little DSL was to add some
> extra groovy methods to various types. (These methods needed to be
> added to some base classes too, so the GDK type additions being a
> really nice way to solve this issue).
>
> I know I can do this with categories; but I really wanted to hard-bake
> in these extra methods with the actual library so its not really
> possible to not have these methods around. i.e. I'd like
> camel-groovy.jar being on the classpath to auto-register some groovy
> methods for working with Camel in a groovy way.
>
> I took a quick peek at the grails stuff for adding extensions and
> didn't quite grok it but it looked like it was doing clever stuff
> doing pattern matching and whatnot - I guess for the find by methods
> for ORM etc. The methods I need to add are pretty simple and need to
> be typed (need multiple methods with same name but different
> parameters). I wondered what the current approach was in Groovy?
>
> I kinda liked the idea of a way to expose new groovy methods in other
> libraries that just kinda gets wired up by default if the library is
> on the classpath; particular for library developers to be able to ship
> a separate groovy jar with their library for folks wishing to work
> with groovy and their library.
>
> I couldn't see any other option (forgive me if I missed something) so
> took a little stab at a simple implementation. Namely, if a file
> called
>
>   META-INF/services/groovy/groovyMethods
>
> is found on the classpath then its parsed (lines starting with #
> ignored) then any non-whitespace lines are tokenized on ",", removing
> all whitespace and then assumed to be a Class which defines instance
> groovy methods. Then for static methods we look for...
>
>   META-INF/services/groovy/groovyStaticMethods
>
> So in Camel's case, we write a file called
> META-INF/services/groovy/groovyMethods that contains
> "org.apache.camel.groovy.CamelGroovyMethods" and then hey presto;
> anyone with the camel-groovy jar on their classpath gets nice DSL
> magic.
>
>
> Its a pretty trivial patch - and is really easy to back-out if there's
> a better way of doing this. I don't seem to have commit karma any
> more, so I've raised a JIRA and attached the patch for review...
> http://jira.codehaus.org/browse/GROOVY-2116
>
> I'm sure there's another way tinkering with the
> MetaClassRegister/MetaClass stuff; I just liked this simple approach
> as its nice and simple & hard to break & is barely any code etc.
>
> Thoughts?
>  

--
Xinaris GmbH
Flüsselweg 10, 76646 Bruchsal
Tel.: +(49)7251/39264-21    | Sitz der Gesellschaft: Bruchsal
Fax:  +(49)7251/39264-29    | Registergericht: AG Mannheim HRB 232791
WWW:  http://www.xinaris.de | Geschäftsführer: Dr. Joachim Baumann
Mail: info@...       | USt-ID DE 242 975 278


---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email

 « Return to Thread: a standard way to enhance the GDK using Java code using META-INF/services/groovy/groovyMethods files...