if (generatedClass != null) {
return generatedClass;
}
if (Modifier.isPrivate(type.getModifiers())) {
throw new GradleException(String.format("Cannot create a proxy class for private class '%s'.",
type.getSimpleName()));
}
if (Modifier.isAbstract(type.getModifiers())) {
throw new GradleException(String.format("Cannot create a proxy class for abstract class '%s'.",
type.getSimpleName()));
}
Class<? extends T> subclass;
try {
ClassBuilder<T> builder = start(type);
boolean isConventionAware = type.getAnnotation(NoConventionMapping.class) == null;
boolean isDynamicAware = type.getAnnotation(NoDynamicObject.class) == null;
builder.startClass(isConventionAware, isDynamicAware);
if (isDynamicAware && !DynamicObjectAware.class.isAssignableFrom(type)) {
builder.mixInDynamicAware();
}
if (isDynamicAware && !GroovyObject.class.isAssignableFrom(type)) {
builder.mixInGroovyObject();
}
if (isDynamicAware) {
builder.addDynamicMethods();
}
if (isConventionAware && !IConventionAware.class.isAssignableFrom(type)) {
builder.mixInConventionAware();
}
Class noMappingClass = Object.class;
for (Class<?> c = type; c != null && noMappingClass == Object.class; c = c.getSuperclass()) {
if (c.getAnnotation(NoConventionMapping.class) != null) {
noMappingClass = c;
}
}
Collection<String> skipProperties = Arrays.asList("metaClass", "conventionMapping", "convention", "asDynamicObject");
MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(type);
for (MetaProperty property : metaClass.getProperties()) {
if (skipProperties.contains(property.getName())) {
continue;
}
if (property instanceof MetaBeanProperty) {
MetaBeanProperty metaBeanProperty = (MetaBeanProperty) property;
MetaMethod getter = metaBeanProperty.getGetter();
if (getter == null) {
continue;
}
if (Modifier.isFinal(getter.getModifiers()) || Modifier.isPrivate(getter.getModifiers())) {
continue;
}
if (getter.getReturnType().isPrimitive()) {
continue;
}
Class declaringClass = getter.getDeclaringClass().getTheClass();
if (declaringClass.isAssignableFrom(noMappingClass)) {
continue;
}
builder.addGetter(metaBeanProperty);
MetaMethod setter = metaBeanProperty.getSetter();
if (setter == null) {
continue;
}
if (Modifier.isFinal(setter.getModifiers()) || Modifier.isPrivate(setter.getModifiers())) {
continue;
}
builder.addSetter(metaBeanProperty);
}
}
for (Constructor<?> constructor : type.getConstructors()) {
if (Modifier.isPublic(constructor.getModifiers())) {
builder.addConstructor(constructor);
}
}
subclass = builder.generate();
} catch (Throwable e) {
throw new GradleException(String.format("Could not generate a proxy class for class %s.", type.getName()), e);
}
cache.put(type, subclass);
return subclass;
}