use of groovy.lang.ClosureInvokingMethod in project grails-core by grails.
the class GrailsMetaClassUtils method copyExpandoMetaClass.
/**
* Copies the ExpandoMetaClass dynamic methods and properties from one Class to another.
*
* @param fromClass The source class
* @param toClass The destination class
* @param removeSource Whether to remove the source class after completion. True if yes
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void copyExpandoMetaClass(Class<?> fromClass, Class<?> toClass, boolean removeSource) {
MetaClassRegistry registry = getRegistry();
MetaClass oldMetaClass = registry.getMetaClass(fromClass);
AdaptingMetaClass adapter = null;
ExpandoMetaClass emc;
if (oldMetaClass instanceof AdaptingMetaClass) {
adapter = ((AdaptingMetaClass) oldMetaClass);
emc = (ExpandoMetaClass) adapter.getAdaptee();
if (LOG.isDebugEnabled()) {
LOG.debug("Obtained adapted MetaClass [" + emc + "] from AdapterMetaClass instance [" + adapter + "]");
}
if (removeSource) {
registry.removeMetaClass(fromClass);
}
} else {
emc = (ExpandoMetaClass) oldMetaClass;
if (LOG.isDebugEnabled()) {
LOG.debug("No adapter MetaClass found, using original [" + emc + "]");
}
}
ExpandoMetaClass replacement = new ExpandoMetaClass(toClass, true, true);
for (Object obj : emc.getExpandoMethods()) {
if (obj instanceof ClosureInvokingMethod) {
ClosureInvokingMethod cim = (ClosureInvokingMethod) obj;
Closure callable = cim.getClosure();
if (!cim.isStatic()) {
replacement.setProperty(cim.getName(), callable);
} else {
((GroovyObject) replacement.getProperty(ExpandoMetaClass.STATIC_QUALIFIER)).setProperty(cim.getName(), callable);
}
}
}
for (Object o : emc.getExpandoProperties()) {
if (o instanceof ThreadManagedMetaBeanProperty) {
ThreadManagedMetaBeanProperty mbp = (ThreadManagedMetaBeanProperty) o;
replacement.setProperty(mbp.getName(), mbp.getInitialValue());
}
}
replacement.initialize();
if (adapter == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Adding MetaClass for class [" + toClass + "] MetaClass [" + replacement + "]");
}
registry.setMetaClass(toClass, replacement);
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Adding MetaClass for class [" + toClass + "] MetaClass [" + replacement + "] with adapter [" + adapter + "]");
}
try {
Constructor c = adapter.getClass().getConstructor(new Class[] { MetaClass.class });
MetaClass newAdapter = (MetaClass) BeanUtils.instantiateClass(c, new Object[] { replacement });
registry.setMetaClass(toClass, newAdapter);
} catch (NoSuchMethodException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Exception thrown constructing new MetaClass adapter when reloading: " + e.getMessage(), e);
}
}
}
}
Aggregations