groovy.lang
Class ExpandoMetaClass

java.lang.Object
  extended by groovy.lang.MetaClassImpl
      extended by groovy.lang.ExpandoMetaClass
All Implemented Interfaces:
GroovyObject, MetaClass, MetaObjectProtocol, MutableMetaClass

public class ExpandoMetaClass
extends MetaClassImpl
implements GroovyObject

A MetaClass that implements GroovyObject and behaves like an Expando, allowing the addition of new methods on the fly. Some examples of usage:

 // defines or replaces instance method:
 metaClass.myMethod = { args -> }

 // defines a new instance method
 metaClass.myMethod << { args -> }

 // creates multiple overloaded methods of the same name
 metaClass.myMethod << { String s -> } << { Integer i -> }

 // defines or replaces a static method with the 'static' qualifier
 metaClass.'static'.myMethod = { args ->  }

 // defines a new static method with the 'static' qualifier
 metaClass.'static'.myMethod << { args ->  }

 // defines a new constructor
 metaClass.constructor << { String arg -> }

 // defines or replaces a constructor
 metaClass.constructor = { String arg -> }

 // defines a new property with an initial value of "blah"
 metaClass.myProperty = "blah"
 
By default methods are only allowed to be added before initialize() is called. In other words you create a new ExpandoMetaClass, add some methods and then call initialize(). If you attempt to add new methods after initialize() has been called an error will be thrown. This is to ensure that the MetaClass can operate appropriately in multi threaded environments as it forces you to do all method additions at the beginning, before using the MetaClass. If you need more fine grained control of how a method is matched you can use DynamicMethodsMetaClass WARNING: This MetaClass uses a thread-bound ThreadLocal instance to store and retrieve properties. In addition properties stored use soft references so they are both bound by the life of the Thread and by the soft references. The implication here is you should NEVER use dynamic properties if you want their values to stick around for long periods because as soon as the JVM is running low on memory or the thread dies they will be garbage collected.

Since:
1.5
Author:
Graeme Rocher

Nested Class Summary
protected  class ExpandoMetaClass.ExpandoMetaConstructor
          Handles the ability to use the left shift operator to append new constructors
protected  class ExpandoMetaClass.ExpandoMetaProperty
          Instances of this class are returned when using the << left shift operator.
 
Nested classes/interfaces inherited from class groovy.lang.MetaClassImpl
MetaClassImpl.Index
 
Field Summary
static String CONSTRUCTOR
           
 boolean inRegistry
           
static String STATIC_QUALIFIER
           
 
Fields inherited from class groovy.lang.MetaClassImpl
getPropertyMethod, INVOKE_METHOD_METHOD, invokeMethodMethod, isGroovyObject, isMap, metaMethodIndex, METHOD_MISSING, PROPERTY_MISSING, registry, setPropertyMethod, STATIC_METHOD_MISSING, STATIC_PROPERTY_MISSING, theCachedClass, theClass
 
Constructor Summary
ExpandoMetaClass(Class theClass)
          Constructs a new ExpandoMetaClass instance for the given class
ExpandoMetaClass(Class theClass, boolean register)
          Constructs a new ExpandoMetaClass instance for the given class optionally placing the MetaClass in the MetaClassRegistry automatically
ExpandoMetaClass(Class theClass, boolean register, boolean allowChangesAfterInit)
          Constructs a new ExpandoMetaClass instance for the given class optionally placing the MetaClass in the MetaClassRegistry automatically
ExpandoMetaClass(Class theClass, boolean register, MetaMethod[] add)
           
ExpandoMetaClass(Class theClass, MetaMethod[] add)
           
 
Method Summary
 void addMixinClass(MixinInMetaClass mixin)
           
 Object castToMixedType(Object obj, Class type)
           
 CallSite createConstructorSite(CallSite site, Object[] args)
           
 CallSite createPogoCallCurrentSite(CallSite site, Class sender, String name, Object[] args)
           
 CallSite createPogoCallSite(CallSite site, Object[] args)
           
 CallSite createPojoCallSite(CallSite site, Object receiver, Object[] args)
           
 CallSite createStaticSite(CallSite site, Object[] args)
           
 ExpandoMetaClass define(Closure closure)
           
static void disableGlobally()
          Call to disable the global use of ExpandoMetaClass
static void enableGlobally()
          Call to enable global use of global use of ExpandoMetaClass within the registry.
 MetaMethod findMixinMethod(String methodName, Class[] arguments)
           
 List<MetaMethod> getExpandoMethods()
          Returns a list of expando MetaMethod instances added to this ExpandoMetaClass
 Collection<MetaProperty> getExpandoProperties()
          Returns a list of MetaBeanProperty instances added to this ExpandoMetaClass
 Collection getExpandoSubclassMethods()
           
 Class getJavaClass()
           
 MetaClass getMetaClass()
          Returns the metaclass for a given class.
 MetaProperty getMetaProperty(String name)
          Looks up an existing MetaProperty by name
 List<MetaMethod> getMethods()
          Overrides the behaviour of parent getMethods() method to make MetaClass aware of added Expando methods
 List<MetaProperty> getProperties()
          Get all the properties defined for this type
 Object getProperty(Class sender, Object object, String name, boolean useSuper, boolean fromInsideClass)
          Overrides default implementation just in case getProperty method has been overriden by ExpandoMetaClass
 Object getProperty(Object object, String name)
          Overrides default implementation just in case getProperty method has been overriden by ExpandoMetaClass
 Object getProperty(String property)
          Retrieves a property value.
 String getPropertyForSetter(String setterName)
          Returns a property name equivalent for the given setter name or null if it is not a getter
protected  Object getSubclassMetaMethods(String methodName)
           
 boolean hasMetaMethod(String name, Class[] args)
          Checks whether a MetaMethod for the given name and arguments exists
 boolean hasMetaProperty(String name)
          Returns true if the MetaClass has the given property
 void initialize()
          complete the initlialisation process.
 Object invokeConstructor(Object[] arguments)
          Invokes a constructor for the given arguments.
 Object invokeMethod(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, boolean fromInsideClass)
          Overrides default implementation just in case invokeMethod has been overridden by ExpandoMetaClass
 Object invokeMethod(String name, Object args)
          Invokes the given method.
 Object invokeStaticMethod(Object object, String methodName, Object[] arguments)
          Overrides default implementation just in case a static invoke method has been set on ExpandoMetaClass
protected  boolean isInitialized()
           
 boolean isModified()
          Return whether the MetaClass has been modified or not
 boolean isSetter(String name, CachedClass[] args)
           
static boolean isValidExpandoProperty(String property)
           
protected  void onGetPropertyFoundInHierarchy(MetaMethod method)
           
protected  void onInvokeMethodFoundInHierarchy(MetaMethod method)
           
protected  void onSetPropertyFoundInHierarchy(MetaMethod method)
           
protected  void onSuperMethodFoundInHierarchy(MetaMethod method)
           
protected  void onSuperPropertyFoundInHierarchy(MetaBeanProperty property)
           
protected  void performOperationOnMetaClass(groovy.lang.ExpandoMetaClass.Callable c)
           
 void refreshInheritedMethods(Set modifiedSuperExpandos)
          Called from ExpandoMetaClassCreationHandle in the registry if it exists to set up inheritance handling
 void registerBeanProperty(String property, Object newValue)
          Registers a new bean property
 void registerInstanceMethod(MetaMethod metaMethod)
          Registers a new instance method for the given method name and closure on this MetaClass
 void registerInstanceMethod(String name, Closure closure)
           
protected  void registerStaticMethod(String name, Closure callable)
           
protected  void registerStaticMethod(String name, Closure callable, Class[] paramTypes)
          Registers a new static method for the given method name and closure on this MetaClass
 void registerSubclassInstanceMethod(MetaMethod metaMethod)
           
 void registerSubclassInstanceMethod(String name, Class klazz, Closure closure)
           
protected  void setInitialized(boolean b)
           
 void setMetaClass(MetaClass metaClass)
          Allows the MetaClass to be replaced with a derived implementation.
 void setProperty(Class sender, Object object, String name, Object newValue, boolean useSuper, boolean fromInsideClass)
          Overrides default implementation just in case setProperty method has been overriden by ExpandoMetaClass
 void setProperty(String property, Object newValue)
          Sets the given property to the new value.
 
Methods inherited from class groovy.lang.MetaClassImpl
addMetaBeanProperty, addMetaMethod, addMetaMethodToIndex, addNewInstanceMethod, addNewStaticMethod, checkIfGroovyObjectMethod, checkInitalised, chooseMethod, clearInvocationCaches, createPogoCallCurrentSite, dropMethodCache, dropStaticMethodCache, findMethodInClassHierarchy, findOwnMethod, findPropertyInClassHierarchy, getAdditionalMetaMethods, getAttribute, getAttribute, getAttribute, getClassInfo, getClassNode, getEffectiveGetMetaProperty, getMetaMethod, getMetaMethods, getMethodWithCaching, getMethodWithoutCaching, getStaticMetaMethod, getSuperClasses, getTheCachedClass, getTheClass, getVersion, hasProperty, incVersion, invokeConstructorAt, invokeMethod, invokeMethod, invokeMissingMethod, invokeMissingProperty, invokeStaticMissingProperty, isGroovyObject, onMixinMethodFound, pickMethod, respondsTo, respondsTo, retrieveConstructor, retrieveMethod, retrieveStaticMethod, selectConstructorAndTransformArguments, setAttribute, setAttribute, setProperties, setProperty, toString
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

STATIC_QUALIFIER

public static final String STATIC_QUALIFIER
See Also:
Constant Field Values

CONSTRUCTOR

public static final String CONSTRUCTOR
See Also:
Constant Field Values

inRegistry

public boolean inRegistry
Constructor Detail

ExpandoMetaClass

public ExpandoMetaClass(Class theClass)
Constructs a new ExpandoMetaClass instance for the given class

Parameters:
theClass - The class that the MetaClass applies to

ExpandoMetaClass

public ExpandoMetaClass(Class theClass,
                        MetaMethod[] add)

ExpandoMetaClass

public ExpandoMetaClass(Class theClass,
                        boolean register)
Constructs a new ExpandoMetaClass instance for the given class optionally placing the MetaClass in the MetaClassRegistry automatically

Parameters:
theClass - The class that the MetaClass applies to
register - True if the MetaClass should be registered inside the MetaClassRegistry. This defaults to true and ExpandoMetaClass will effect all instances if changed

ExpandoMetaClass

public ExpandoMetaClass(Class theClass,
                        boolean register,
                        MetaMethod[] add)

ExpandoMetaClass

public ExpandoMetaClass(Class theClass,
                        boolean register,
                        boolean allowChangesAfterInit)
Constructs a new ExpandoMetaClass instance for the given class optionally placing the MetaClass in the MetaClassRegistry automatically

Parameters:
theClass - The class that the MetaClass applies to
register - True if the MetaClass should be registered inside the MetaClassRegistry. This defaults to true and ExpandoMetaClass will effect all instances if changed
allowChangesAfterInit - Should the meta class be modifiable after initialization. Default is false.
Method Detail

getExpandoSubclassMethods

public Collection getExpandoSubclassMethods()

findMixinMethod

public MetaMethod findMixinMethod(String methodName,
                                  Class[] arguments)
Overrides:
findMixinMethod in class MetaClassImpl

onInvokeMethodFoundInHierarchy

protected void onInvokeMethodFoundInHierarchy(MetaMethod method)
Overrides:
onInvokeMethodFoundInHierarchy in class MetaClassImpl

onSuperMethodFoundInHierarchy

protected void onSuperMethodFoundInHierarchy(MetaMethod method)
Overrides:
onSuperMethodFoundInHierarchy in class MetaClassImpl

onSuperPropertyFoundInHierarchy

protected void onSuperPropertyFoundInHierarchy(MetaBeanProperty property)
Overrides:
onSuperPropertyFoundInHierarchy in class MetaClassImpl

onSetPropertyFoundInHierarchy

protected void onSetPropertyFoundInHierarchy(MetaMethod method)
Overrides:
onSetPropertyFoundInHierarchy in class MetaClassImpl

onGetPropertyFoundInHierarchy

protected void onGetPropertyFoundInHierarchy(MetaMethod method)
Overrides:
onGetPropertyFoundInHierarchy in class MetaClassImpl

isModified

public boolean isModified()
Description copied from interface: MutableMetaClass
Return whether the MetaClass has been modified or not

Specified by:
isModified in interface MutableMetaClass
Overrides:
isModified in class MetaClassImpl
Returns:
True if it has

registerSubclassInstanceMethod

public void registerSubclassInstanceMethod(String name,
                                           Class klazz,
                                           Closure closure)

registerSubclassInstanceMethod

public void registerSubclassInstanceMethod(MetaMethod metaMethod)

addMixinClass

public void addMixinClass(MixinInMetaClass mixin)

castToMixedType

public Object castToMixedType(Object obj,
                              Class type)

enableGlobally

public static void enableGlobally()
Call to enable global use of global use of ExpandoMetaClass within the registry. This has the advantage that inheritance will function correctly, but has a higher memory usage on the JVM than normal Groovy


disableGlobally

public static void disableGlobally()
Call to disable the global use of ExpandoMetaClass


initialize

public void initialize()
Description copied from interface: MetaClass
complete the initlialisation process. After this method is called no methods should be added to the meta class. Invocation of methods or access to fields/proeprties is forbidden unless this method is called. This method should contain any initialisation code, taking a longer time to complete. An example is the creation of the Reflector. It is suggested to synchronize this method.

Specified by:
initialize in interface MetaClass
Overrides:
initialize in class MetaClassImpl

isInitialized

protected boolean isInitialized()
Overrides:
isInitialized in class MetaClassImpl

setInitialized

protected void setInitialized(boolean b)

invokeConstructor

public Object invokeConstructor(Object[] arguments)
Description copied from interface: MetaObjectProtocol
Invokes a constructor for the given arguments. The MetaClass will attempt to pick the best argument which matches the types of the objects passed within the arguments array

Specified by:
invokeConstructor in interface MetaObjectProtocol
Overrides:
invokeConstructor in class MetaClassImpl
Parameters:
arguments - The arguments to the constructor
Returns:
An instance of the java.lang.Class that this MetaObjectProtocol object applies to

getMetaClass

public MetaClass getMetaClass()
Description copied from interface: GroovyObject
Returns the metaclass for a given class.

Specified by:
getMetaClass in interface GroovyObject
Returns:
the metaClass of this instance

getProperty

public Object getProperty(String property)
Description copied from interface: GroovyObject
Retrieves a property value.

Specified by:
getProperty in interface GroovyObject
Parameters:
property - the name of the property of interest
Returns:
the given property

isValidExpandoProperty

public static boolean isValidExpandoProperty(String property)

invokeMethod

public Object invokeMethod(String name,
                           Object args)
Description copied from interface: GroovyObject
Invokes the given method.

Specified by:
invokeMethod in interface GroovyObject
Parameters:
name - the name of the method to call
args - the arguments to use for the method call
Returns:
the result of invoking the method

setMetaClass

public void setMetaClass(MetaClass metaClass)
Description copied from interface: GroovyObject
Allows the MetaClass to be replaced with a derived implementation.

Specified by:
setMetaClass in interface GroovyObject
Parameters:
metaClass - the new metaclass

setProperty

public void setProperty(String property,
                        Object newValue)
Description copied from interface: GroovyObject
Sets the given property to the new value.

Specified by:
setProperty in interface GroovyObject
Parameters:
property - the name of the property of interest
newValue - the new value for the property

define

public ExpandoMetaClass define(Closure closure)

performOperationOnMetaClass

protected void performOperationOnMetaClass(groovy.lang.ExpandoMetaClass.Callable c)

registerBeanProperty

public void registerBeanProperty(String property,
                                 Object newValue)
Registers a new bean property

Parameters:
property - The property name
newValue - The properties initial value

registerInstanceMethod

public void registerInstanceMethod(MetaMethod metaMethod)
Registers a new instance method for the given method name and closure on this MetaClass

Parameters:
metaMethod -

registerInstanceMethod

public void registerInstanceMethod(String name,
                                   Closure closure)

getMethods

public List<MetaMethod> getMethods()
Overrides the behaviour of parent getMethods() method to make MetaClass aware of added Expando methods

Specified by:
getMethods in interface MetaClass
Specified by:
getMethods in interface MetaObjectProtocol
Overrides:
getMethods in class MetaClassImpl
Returns:
A list of MetaMethods
See Also:
MetaObjectProtocol.getMethods()

getProperties

public List<MetaProperty> getProperties()
Description copied from class: MetaClassImpl
Get all the properties defined for this type

Specified by:
getProperties in interface MetaClass
Specified by:
getProperties in interface MetaObjectProtocol
Overrides:
getProperties in class MetaClassImpl
Returns:
a list of MetaProperty objects
See Also:
MetaProperty

registerStaticMethod

protected void registerStaticMethod(String name,
                                    Closure callable)

registerStaticMethod

protected void registerStaticMethod(String name,
                                    Closure callable,
                                    Class[] paramTypes)
Registers a new static method for the given method name and closure on this MetaClass

Parameters:
name - The method name
callable - The callable Closure

getSubclassMetaMethods

protected Object getSubclassMetaMethods(String methodName)
Overrides:
getSubclassMetaMethods in class MetaClassImpl

getJavaClass

public Class getJavaClass()
Returns:
The Java class enhanced by this MetaClass

refreshInheritedMethods

public void refreshInheritedMethods(Set modifiedSuperExpandos)
Called from ExpandoMetaClassCreationHandle in the registry if it exists to set up inheritance handling

Parameters:
modifiedSuperExpandos - A list of modified super ExpandoMetaClass

getExpandoMethods

public List<MetaMethod> getExpandoMethods()
Returns a list of expando MetaMethod instances added to this ExpandoMetaClass

Returns:
the expandoMethods

getExpandoProperties

public Collection<MetaProperty> getExpandoProperties()
Returns a list of MetaBeanProperty instances added to this ExpandoMetaClass

Returns:
the expandoProperties

invokeMethod

public Object invokeMethod(Class sender,
                           Object object,
                           String methodName,
                           Object[] originalArguments,
                           boolean isCallToSuper,
                           boolean fromInsideClass)
Overrides default implementation just in case invokeMethod has been overridden by ExpandoMetaClass

Specified by:
invokeMethod in interface MetaClass
Overrides:
invokeMethod in class MetaClassImpl
Parameters:
sender - The java.lang.Class instance that invoked the method
object - The object which the method was invoked on
methodName - The name of the method
originalArguments - The arguments to the method
isCallToSuper - Whether the method is a call to a super class method
fromInsideClass - Whether the call was invoked from the inside or the outside of the class
Returns:
The return value of the method
See Also:
MetaClassImpl.invokeMethod(Class, Object, String, Object[], boolean, boolean)

invokeStaticMethod

public Object invokeStaticMethod(Object object,
                                 String methodName,
                                 Object[] arguments)
Overrides default implementation just in case a static invoke method has been set on ExpandoMetaClass

Specified by:
invokeStaticMethod in interface MetaObjectProtocol
Overrides:
invokeStaticMethod in class MetaClassImpl
Parameters:
object - An instance of the class returned by the getTheClass() method or the class itself
methodName - The name of the method
arguments - The arguments to the method
Returns:
The return value of the method which is null if the return type is void
See Also:
MetaClassImpl.invokeStaticMethod(Object, String, Object[])

getProperty

public Object getProperty(Class sender,
                          Object object,
                          String name,
                          boolean useSuper,
                          boolean fromInsideClass)
Overrides default implementation just in case getProperty method has been overriden by ExpandoMetaClass

Specified by:
getProperty in interface MetaClass
Overrides:
getProperty in class MetaClassImpl
Parameters:
sender - The java.lang.Class instance that requested the property
object - The Object which the property is being retrieved from
name - The name of the property
useSuper - Whether the call is to a super class property
fromInsideClass - ??
Returns:
the given property's value on the object
See Also:
MetaClassImpl.getProperty(Class, Object, String, boolean, boolean)

getProperty

public Object getProperty(Object object,
                          String name)
Overrides default implementation just in case getProperty method has been overriden by ExpandoMetaClass

Specified by:
getProperty in interface MetaObjectProtocol
Overrides:
getProperty in class MetaClassImpl
Parameters:
object - An instance of the class returned by the getTheClass() method
name - The name of the property to retrieve the value for
Returns:
The properties value
See Also:
MetaClassImpl.getProperty(Object, String)

setProperty

public void setProperty(Class sender,
                        Object object,
                        String name,
                        Object newValue,
                        boolean useSuper,
                        boolean fromInsideClass)
Overrides default implementation just in case setProperty method has been overriden by ExpandoMetaClass

Specified by:
setProperty in interface MetaClass
Overrides:
setProperty in class MetaClassImpl
Parameters:
sender - The java.lang.Class instance that is mutating the property
object - The Object which the property is being set on
name - The name of the property
newValue - The new value of the property to set
useSuper - Whether the call is to a super class property
fromInsideClass - ??
See Also:
MetaClassImpl.setProperty(Class, Object, String, Object, boolean, boolean)

getMetaProperty

public MetaProperty getMetaProperty(String name)
Looks up an existing MetaProperty by name

Specified by:
getMetaProperty in interface MetaObjectProtocol
Overrides:
getMetaProperty in class MetaClassImpl
Parameters:
name - The name of the MetaProperty
Returns:
The MetaProperty or null if it doesn't exist
See Also:
MetaObjectProtocol.getMetaProperty(String)

hasMetaProperty

public boolean hasMetaProperty(String name)
Returns true if the MetaClass has the given property

Parameters:
name - The name of the MetaProperty
Returns:
True it exists as a MetaProperty

hasMetaMethod

public boolean hasMetaMethod(String name,
                             Class[] args)
Checks whether a MetaMethod for the given name and arguments exists

Parameters:
name - The name of the MetaMethod
args - The arguments to the meta method
Returns:
True if the method exists otherwise null

getPropertyForSetter

public String getPropertyForSetter(String setterName)
Returns a property name equivalent for the given setter name or null if it is not a getter

Parameters:
setterName - The setter name
Returns:
The property name equivalent

isSetter

public boolean isSetter(String name,
                        CachedClass[] args)

createPojoCallSite

public CallSite createPojoCallSite(CallSite site,
                                   Object receiver,
                                   Object[] args)
Overrides:
createPojoCallSite in class MetaClassImpl

createStaticSite

public CallSite createStaticSite(CallSite site,
                                 Object[] args)
Overrides:
createStaticSite in class MetaClassImpl

createPogoCallSite

public CallSite createPogoCallSite(CallSite site,
                                   Object[] args)
Overrides:
createPogoCallSite in class MetaClassImpl

createPogoCallCurrentSite

public CallSite createPogoCallCurrentSite(CallSite site,
                                          Class sender,
                                          String name,
                                          Object[] args)

createConstructorSite

public CallSite createConstructorSite(CallSite site,
                                      Object[] args)
Overrides:
createConstructorSite in class MetaClassImpl

Copyright © 2003-2010 The Codehaus. All rights reserved.