CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-apache-groovy--groovy

Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax.

Pending
Overview
Eval results
Files

meta-programming.mddocs/

Meta-Programming

Comprehensive meta-programming capabilities for runtime method and property manipulation, dynamic behavior modification, and advanced meta-object protocol features.

Capabilities

MetaClass System

Core meta-programming interface for runtime method dispatch and property access.

/**
 * Core meta-class interface for runtime method dispatch and property access
 */
interface MetaClass {
    /** Invoke method on object with given arguments */
    Object invokeMethod(Object object, String methodName, Object[] arguments)
    
    /** Invoke method on class (static method) */
    Object invokeStaticMethod(Object object, String methodName, Object[] arguments)
    
    /** Invoke constructor with arguments */
    Object invokeConstructor(Object[] arguments)
    
    /** Get property value from object */
    Object getProperty(Object object, String property)
    
    /** Set property value on object */
    void setProperty(Object object, String property, Object newValue)
    
    /** Get attribute (field) value */
    Object getAttribute(Object object, String attribute)
    
    /** Set attribute (field) value */
    void setAttribute(Object object, String attribute, Object newValue)
    
    /** Get list of all methods */
    List<MetaMethod> getMethods()
    
    /** Get list of methods by name */
    List<MetaMethod> getMethods(String name)
    
    /** Get list of all properties */
    List<MetaProperty> getProperties()
    
    /** Get specific property by name */
    MetaProperty getMetaProperty(String name)
    
    /** Check if method exists */
    boolean hasMethod(String name, Object[] arguments)
    
    /** Check if property exists */
    boolean hasProperty(Object obj, String name)
    
    /** Get the class this MetaClass represents */
    Class getTheClass()
}

MetaClass Implementation

Default implementation providing comprehensive meta-programming features.

/**
 * Default implementation of MetaClass
 */
class MetaClassImpl implements MetaClass, MutableMetaClass {
    /** Create MetaClassImpl for given class */
    MetaClassImpl(Class theClass)
    
    /** Create with custom class registry */
    MetaClassImpl(MetaClassRegistry registry, Class theClass)
    
    /** Add new method to the metaclass */
    void addNewMethod(String name, Closure closure)
    
    /** Add new static method */
    void addNewStaticMethod(String name, Closure closure)
    
    /** Add new constructor */
    void addNewConstructor(Closure closure)
    
    /** Add new property getter */
    void addNewProperty(String name, Closure getter)
    
    /** Add new property with getter and setter */
    void addNewProperty(String name, Closure getter, Closure setter)
    
    /** Initialize the metaclass */
    void initialize()
}

ExpandoMetaClass

Dynamic meta-class that allows runtime addition of methods and properties.

/**
 * MetaClass that allows dynamic addition of methods and properties at runtime
 */
class ExpandoMetaClass extends MetaClassImpl {
    /** Enable globally for all classes */
    static void enableGlobally()
    
    /** Disable globally */
    static void disableGlobally()
    
    /** Create ExpandoMetaClass for class */
    ExpandoMetaClass(Class clazz)
    
    /** Create with inheritance enabled */
    ExpandoMetaClass(Class clazz, boolean register)
    
    /** Define method on metaclass using closure */
    void define(Closure definition)
    
    /** Left shift operator for method addition */
    ExpandoMetaClass leftShift(Closure closure)
    
    /** Add method dynamically */
    void addMethod(String name, Closure closure)
    
    /** Add static method dynamically */
    void addStaticMethod(String name, Closure closure)
    
    /** Add constructor dynamically */
    void addConstructor(Closure closure)
    
    /** Add property dynamically */
    void addProperty(String name, Object value)
}

Usage Examples:

// Enable ExpandoMetaClass globally
ExpandoMetaClass.enableGlobally()

// Add method to existing class
String.metaClass.reverse = {
    return delegate.reverse()
}

println "hello".reverse() // "olleh"

// Add method with parameters
String.metaClass.multiply = { times ->
    return delegate * times
}

println "ha".multiply(3) // "hahaha"

// Add static method
Integer.metaClass.static.random = { max ->
    return new Random().nextInt(max)
}

println Integer.random(100) // random number 0-99

// Add property
String.metaClass.getWordCount = {
    return delegate.split(/\s+/).size()
}

println "hello world test".wordCount // 3

// Define multiple methods at once
String.metaClass.define {
    palindrome = {
        return delegate == delegate.reverse()
    }
    
    capitalize = {
        return delegate.toLowerCase().split(' ').collect { 
            it.capitalize() 
        }.join(' ')
    }
}

println "racecar".palindrome() // true
println "hello world".capitalize() // "Hello World"

// Add methods to specific instances
def person = new Person()
person.metaClass.greet = {
    return "Hello, I'm ${delegate.name}"
}
println person.greet()

// Add constructor
Person.metaClass.constructor = { String name, int age ->
    def instance = new Person()
    instance.name = name
    instance.age = age
    return instance
}

def newPerson = new Person("Alice", 30)

MetaMethod and MetaProperty

Representations of methods and properties in the meta-object system.

/**
 * Base class for meta-methods
 */
abstract class MetaMethod {
    /** Get method name */
    String getName()
    
    /** Get return type */
    Class getReturnType()
    
    /** Get parameter types */
    Class[] getParameterTypes()
    
    /** Check if method is static */
    boolean isStatic()
    
    /** Check if method is public */
    boolean isPublic()
    
    /** Check if method is private */
    boolean isPrivate()
    
    /** Check if method is protected */
    boolean isProtected()
    
    /** Invoke the method */
    Object invoke(Object object, Object[] arguments)
    
    /** Get declaring class */
    Class getDeclaringClass()
}

/**
 * Represents a property in the meta-object system
 */
abstract class MetaProperty {
    /** Get property name */
    String getName()
    
    /** Get property type */
    Class getType()
    
    /** Get property value from object */
    Object getProperty(Object object)
    
    /** Set property value on object */
    void setProperty(Object object, Object newValue)
    
    /** Get declaring class */
    Class getDeclaringClass()
}

MetaClassRegistry

Registry for managing MetaClass instances globally.

/**
 * Registry for MetaClass instances
 */
interface MetaClassRegistry {
    /** Get MetaClass for given class */
    MetaClass getMetaClass(Class theClass)
    
    /** Set MetaClass for given class */
    void setMetaClass(Class theClass, MetaClass theMetaClass)
    
    /** Remove MetaClass for given class */
    void removeMetaClass(Class theClass)
    
    /** Get MetaClass for given object */
    MetaClass getMetaClass(Object obj)
    
    /** Add change event listener */
    void addMetaClassRegistryChangeEventListener(MetaClassRegistryChangeEventListener listener)
    
    /** Remove change event listener */
    void removeMetaClassRegistryChangeEventListener(MetaClassRegistryChangeEventListener listener)
    
    /** Get change listeners */
    MetaClassRegistryChangeEventListener[] getMetaClassRegistryChangeEventListeners()
}

Usage Examples:

// Get global registry
def registry = GroovySystem.metaClassRegistry

// Get metaclass for a class
def stringMetaClass = registry.getMetaClass(String)
println "String has ${stringMetaClass.methods.size()} methods"

// Set custom metaclass
def customMetaClass = new ExpandoMetaClass(String)
customMetaClass.shout = { delegate.toUpperCase() + "!!!" }
customMetaClass.initialize()

registry.setMetaClass(String, customMetaClass)
println "hello".shout() // "HELLO!!!"

// Listen for metaclass changes
registry.addMetaClassRegistryChangeEventListener { event ->
    println "MetaClass changed for ${event.classToUpdate}"
}

Categories

Temporary method additions using the Category pattern.

/**
 * Marks a class as a category for use with `use` blocks
 */
@interface Category {
    Class value() default Object.class
}

/**
 * Support for category-based method enhancement
 */
class GroovyCategorySupport {
    /** Execute closure with category methods available */
    static Object use(Class categoryClass, Closure closure)
    
    /** Execute closure with multiple categories */
    static Object use(List<Class> categoryClasses, Closure closure)
    
    /** Execute closure with category instance */
    static Object use(Object categoryInstance, Closure closure)
}

Usage Examples:

import groovy.lang.Category

// Define a category class
@Category(String)
class StringUtils {
    static String reverse() {
        return this.reverse()
    }
    
    static boolean isPalindrome() {
        def reversed = this.reverse()
        return this.toLowerCase() == reversed.toLowerCase()
    }
    
    static String encrypt(String key) {
        // Simple encryption example
        return this.collect { char ->
            (char as int) + (key as int)
        }.collect { 
            it as char 
        }.join('')
    }
}

// Use category methods temporarily
use(StringUtils) {
    println "hello".reverse()        // "olleh"
    println "racecar".isPalindrome() // true
    println "secret".encrypt("x")    // encrypted string
}

// Outside use block, methods are not available
// "hello".reverse() // Would cause MissingMethodException

// Multiple categories
@Category(Number)
class NumberUtils {
    static boolean isEven() {
        return this % 2 == 0
    }
    
    static boolean isOdd() {
        return this % 2 != 0
    }
}

use([StringUtils, NumberUtils]) {
    println "test".reverse()  // String category method
    println 42.isEven()       // Number category method
}

Method Missing and Property Missing

Handle missing method and property calls dynamically.

/**
 * Handle missing method calls (typically implemented in classes)
 */
Object methodMissing(String name, Object args) {
    // Custom implementation for handling unknown method calls
}

/**
 * Handle missing property access (typically implemented in classes)
 */
Object propertyMissing(String name) {
    // Custom implementation for handling unknown property access
}

/**
 * Handle missing property assignment (typically implemented in classes)
 */
Object propertyMissing(String name, Object value) {
    // Custom implementation for handling unknown property assignment
}

Usage Examples:

class DynamicBean {
    private Map properties = [:]
    
    // Handle missing property gets
    def propertyMissing(String name) {
        return properties[name]
    }
    
    // Handle missing property sets
    def propertyMissing(String name, value) {
        properties[name] = value
    }
    
    // Handle missing method calls
    def methodMissing(String name, args) {
        if (name.startsWith('get')) {
            def propName = name[3..-1].toLowerCase()
            return properties[propName]
        } else if (name.startsWith('set')) {
            def propName = name[3..-1].toLowerCase()
            properties[propName] = args[0]
            return this
        } else {
            throw new MissingMethodException(name, this.class, args)
        }
    }
}

def bean = new DynamicBean()

// Property syntax
bean.name = "Alice"
bean.age = 30
println bean.name  // "Alice"
println bean.age   // 30

// Method syntax
bean.setEmail("alice@example.com")
println bean.getEmail()  // "alice@example.com"

// Method chaining
bean.setName("Bob").setAge(25)
println "${bean.name} is ${bean.age} years old"

Interceptors

Intercept method calls for logging, security, or other cross-cutting concerns.

/**
 * Interface for method call interception
 */
interface Interceptor {
    /** Called before method execution */
    Object beforeInvoke(Object object, String methodName, Object[] arguments)
    
    /** Called after method execution */
    Object afterInvoke(Object object, String methodName, Object[] arguments, Object result)
    
    /** Check if this interceptor applies to the method */
    boolean doInvoke()
}

/**
 * Tracing interceptor for debugging
 */
class TracingInterceptor implements Interceptor {
    TracingInterceptor()
    
    Object beforeInvoke(Object object, String methodName, Object[] arguments)
    Object afterInvoke(Object object, String methodName, Object[] arguments, Object result)
    boolean doInvoke()
}

Usage Examples:

import groovy.lang.TracingInterceptor

// Add tracing to a class
def tracer = new TracingInterceptor()
def proxy = ProxyMetaClass.getInstance(String)
proxy.interceptor = tracer
proxy.use {
    "hello".toUpperCase()
    "world".reverse()
}

// Custom interceptor
class LoggingInterceptor implements Interceptor {
    boolean doInvoke() { return true }
    
    Object beforeInvoke(Object object, String methodName, Object[] arguments) {
        println "Calling ${methodName} on ${object.class.simpleName} with args: ${arguments}"
        return null
    }
    
    Object afterInvoke(Object object, String methodName, Object[] arguments, Object result) {
        println "Method ${methodName} returned: ${result}"
        return result
    }
}

def logger = new LoggingInterceptor()
def proxyMeta = ProxyMetaClass.getInstance(List)
proxyMeta.interceptor = logger
proxyMeta.use {
    def list = [1, 2, 3]
    list.add(4)
    list.size()
}

Install with Tessl CLI

npx tessl i tessl/maven-org-apache-groovy--groovy

docs

cli-interface.md

collections-utilities.md

core-runtime.md

index.md

json-processing.md

meta-programming.md

script-execution.md

sql-database.md

template-processing.md

xml-processing.md

tile.json