use of groovy.lang.ExpandoMetaClass in project grails-core by grails.
the class GrailsMetaClassUtils method getMetaClass.
public static MetaClass getMetaClass(Object instance) {
if (instance instanceof GroovyObject) {
GroovyObject groovyObject = (GroovyObject) instance;
MetaClass metaClass = groovyObject.getMetaClass();
metaClass = unwrapDelegatingMetaClass(metaClass);
if (!(metaClass instanceof ExpandoMetaClass)) {
metaClass = getExpandoMetaClass(instance.getClass());
groovyObject.setMetaClass(metaClass);
}
return metaClass;
}
return getExpandoMetaClass(instance.getClass());
}
use of groovy.lang.ExpandoMetaClass in project grails-core by grails.
the class GrailsClassUtils method getExpandoMetaClass.
@SuppressWarnings("rawtypes")
public static MetaClass getExpandoMetaClass(Class clazz) {
MetaClassRegistry registry = GroovySystem.getMetaClassRegistry();
Assert.isTrue(registry.getMetaClassCreationHandler() instanceof ExpandoMetaClassCreationHandle, "Grails requires an instance of [ExpandoMetaClassCreationHandle] to be set in Groovy's MetaClassRegistry! (current is : " + registry.getMetaClassCreationHandler() + ")");
MetaClass mc = registry.getMetaClass(clazz);
AdaptingMetaClass adapter = null;
if (mc instanceof AdaptingMetaClass) {
adapter = (AdaptingMetaClass) mc;
mc = ((AdaptingMetaClass) mc).getAdaptee();
}
if (!(mc instanceof ExpandoMetaClass)) {
// removes cached version
registry.removeMetaClass(clazz);
mc = registry.getMetaClass(clazz);
if (adapter != null) {
adapter.setAdaptee(mc);
}
}
Assert.isTrue(mc instanceof ExpandoMetaClass, "BUG! Method must return an instance of [ExpandoMetaClass]!");
return mc;
}
use of groovy.lang.ExpandoMetaClass in project grails-core by grails.
the class MetaClassRegistryCleaner method updateConstantMetaClass.
public void updateConstantMetaClass(MetaClassRegistryChangeEvent cmcu) {
if (!cleaning) {
MetaClass oldMetaClass = cmcu.getOldMetaClass();
Class classToUpdate = cmcu.getClassToUpdate();
Object instanceToUpdate = cmcu.getInstance();
if (instanceToUpdate == null && (cmcu.getNewMetaClass() instanceof ExpandoMetaClass)) {
updateMetaClassOfClass(oldMetaClass, classToUpdate);
} else if (instanceToUpdate != null) {
updateMetaClassOfInstance(oldMetaClass, instanceToUpdate);
}
}
}
use of groovy.lang.ExpandoMetaClass in project groovy-core by groovy.
the class MixinInMetaClass method mixinClassesToMetaClass.
public static void mixinClassesToMetaClass(MetaClass self, List<Class> categoryClasses) {
final Class selfClass = self.getTheClass();
if (self instanceof HandleMetaClass) {
self = (MetaClass) ((HandleMetaClass) self).replaceDelegate();
}
if (!(self instanceof ExpandoMetaClass)) {
if (self instanceof DelegatingMetaClass && ((DelegatingMetaClass) self).getAdaptee() instanceof ExpandoMetaClass) {
self = ((DelegatingMetaClass) self).getAdaptee();
} else {
throw new GroovyRuntimeException("Can't mixin methods to meta class: " + self);
}
}
ExpandoMetaClass mc = (ExpandoMetaClass) self;
List<MetaMethod> arr = new ArrayList<MetaMethod>();
for (Class categoryClass : categoryClasses) {
final CachedClass cachedCategoryClass = ReflectionCache.getCachedClass(categoryClass);
final MixinInMetaClass mixin = new MixinInMetaClass(mc, cachedCategoryClass);
final MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(categoryClass);
final List<MetaProperty> propList = metaClass.getProperties();
for (MetaProperty prop : propList) if (self.getMetaProperty(prop.getName()) == null) {
mc.registerBeanProperty(prop.getName(), new MixinInstanceMetaProperty(prop, mixin));
}
for (MetaProperty prop : cachedCategoryClass.getFields()) if (self.getMetaProperty(prop.getName()) == null) {
mc.registerBeanProperty(prop.getName(), new MixinInstanceMetaProperty(prop, mixin));
}
for (MetaMethod method : metaClass.getMethods()) {
final int mod = method.getModifiers();
if (!Modifier.isPublic(mod))
continue;
if (method instanceof CachedMethod && ((CachedMethod) method).getCachedMethod().isSynthetic())
continue;
if (Modifier.isStatic(mod)) {
if (method instanceof CachedMethod)
staticMethod(self, arr, (CachedMethod) method);
} else if (method.getDeclaringClass().getTheClass() != Object.class || method.getName().equals("toString")) {
// if (self.pickMethod(method.getName(), method.getNativeParameterTypes()) == null) {
final MixinInstanceMetaMethod metaMethod = new MixinInstanceMetaMethod(method, mixin);
arr.add(metaMethod);
// }
}
}
}
for (Object res : arr) {
final MetaMethod metaMethod = (MetaMethod) res;
if (metaMethod.getDeclaringClass().isAssignableFrom(selfClass))
mc.registerInstanceMethod(metaMethod);
else {
mc.registerSubclassInstanceMethod(metaMethod);
}
}
}
use of groovy.lang.ExpandoMetaClass in project groovy by apache.
the class MixinInMetaClass method mixinClassesToMetaClass.
public static void mixinClassesToMetaClass(MetaClass self, List<Class> categoryClasses) {
final Class selfClass = self.getTheClass();
if (self instanceof HandleMetaClass) {
self = (MetaClass) ((HandleMetaClass) self).replaceDelegate();
}
if (!(self instanceof ExpandoMetaClass)) {
if (self instanceof DelegatingMetaClass && ((DelegatingMetaClass) self).getAdaptee() instanceof ExpandoMetaClass) {
self = ((DelegatingMetaClass) self).getAdaptee();
} else {
throw new GroovyRuntimeException("Can't mixin methods to meta class: " + self);
}
}
ExpandoMetaClass mc = (ExpandoMetaClass) self;
List<MetaMethod> arr = new ArrayList<MetaMethod>();
for (Class categoryClass : categoryClasses) {
final CachedClass cachedCategoryClass = ReflectionCache.getCachedClass(categoryClass);
final MixinInMetaClass mixin = new MixinInMetaClass(mc, cachedCategoryClass);
final MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(categoryClass);
final List<MetaProperty> propList = metaClass.getProperties();
for (MetaProperty prop : propList) if (self.getMetaProperty(prop.getName()) == null) {
mc.registerBeanProperty(prop.getName(), new MixinInstanceMetaProperty(prop, mixin));
}
for (MetaProperty prop : cachedCategoryClass.getFields()) if (self.getMetaProperty(prop.getName()) == null) {
mc.registerBeanProperty(prop.getName(), new MixinInstanceMetaProperty(prop, mixin));
}
for (MetaMethod method : metaClass.getMethods()) {
final int mod = method.getModifiers();
if (!Modifier.isPublic(mod))
continue;
if (method instanceof CachedMethod && ((CachedMethod) method).getCachedMethod().isSynthetic())
continue;
if (Modifier.isStatic(mod)) {
if (method instanceof CachedMethod)
staticMethod(self, arr, (CachedMethod) method);
} else if (method.getDeclaringClass().getTheClass() != Object.class || method.getName().equals("toString")) {
// if (self.pickMethod(method.getName(), method.getNativeParameterTypes()) == null) {
final MixinInstanceMetaMethod metaMethod = new MixinInstanceMetaMethod(method, mixin);
arr.add(metaMethod);
// }
}
}
}
for (Object res : arr) {
final MetaMethod metaMethod = (MetaMethod) res;
if (metaMethod.getDeclaringClass().isAssignableFrom(selfClass))
mc.registerInstanceMethod(metaMethod);
else {
mc.registerSubclassInstanceMethod(metaMethod);
}
}
}
Aggregations