}
public <T> T build(Object source, String propertyName, Class<T> propertyType)
{
Class sourceClass = source.getClass();
PropertyAdapter adapter = _propertyAccess.getAdapter(sourceClass).getPropertyAdapter(
propertyName);
// TODO: Perhaps extend ClassPropertyAdapter to do these checks?
if (adapter == null)
throw new RuntimeException(ServiceMessages.noSuchProperty(sourceClass, propertyName));
if (!adapter.isRead())
throw new RuntimeException(ServiceMessages.readNotSupported(source, propertyName));
if (!propertyType.isAssignableFrom(adapter.getType()))
throw new RuntimeException(ServiceMessages.propertyTypeMismatch(
propertyName,
sourceClass,
adapter.getType(),
propertyType));
ClassFab cf = _classFactory.newClass(propertyType);
cf.addField("_source", sourceClass);
cf.addConstructor(new Class[]
{ sourceClass }, null, "_source = $1;");
String body = format("return _source.%s();", adapter.getReadMethod().getName());
MethodSignature sig = new MethodSignature(propertyType, "_delegate", null, null);
cf.addMethod(Modifier.PRIVATE, sig, body);
String toString = format("<Shadow: property %s of %s>", propertyName, source);