/* * Copyright (c) 2013 Simon Templer * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Simon Templer - initial version */ package groovy.runtime.metaclass; import java.lang.reflect.Constructor; import eu.esdihumboldt.util.groovy.meta.extension.MetaClassDescriptor; import eu.esdihumboldt.util.groovy.meta.extension.MetaClassExtension; import groovy.lang.MetaClass; import groovy.lang.MetaClassRegistry; import groovy.lang.MetaClassRegistry.MetaClassCreationHandle; /** * Adapts created meta classes with delegating meta classes registered in the * {@link MetaClassExtension}. * * @author Simon Templer */ public class CustomMetaClassCreationHandle extends MetaClassCreationHandle { private final MetaClassExtension ext = new MetaClassExtension(); @Override protected MetaClass createNormalMetaClass(@SuppressWarnings("rawtypes") Class theClass, MetaClassRegistry registry) { MetaClass metaClass = super.createNormalMetaClass(theClass, registry); for (MetaClassDescriptor descriptor : ext.getElements()) { if (descriptorApplies(descriptor, theClass)) { // create meta class Class<?> delegatingMetaClass = descriptor.getMetaClass(); try { Constructor<?> constructor = delegatingMetaClass .getConstructor(MetaClass.class); metaClass = (MetaClass) constructor.newInstance(metaClass); } catch (Exception e) { e.printStackTrace(); } } } return metaClass; } /** * Check if a meta class descriptor applies to a given class. * * @param descriptor the meta class descriptor * @param theClass the class for which should be determined if the * descriptor applies * @return <code>true</code> if the descriptor applies to the class, * <code>false</code> otherwise */ private boolean descriptorApplies(MetaClassDescriptor descriptor, @SuppressWarnings("rawtypes") Class theClass) { Class<?> forClass = descriptor.getForClass(); if (descriptor.isForArray()) { if (theClass.isArray()) { Class<?> componentClass = theClass.getComponentType(); if (componentClass != null) { return forClass.equals(componentClass) || forClass.isAssignableFrom(componentClass); } else { // should actually not happen return false; } } else { // no array return false; } } else { return forClass.equals(theClass) || forClass.isAssignableFrom(theClass); } } }