* @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);
}