// check visited
final Binding<IEntity, Model> b = visited.findBindingBySource(source);
if(b != null) return b.tgt;
final Class<? extends IEntity> entityClass = source.entityClass();
final Model model = new Model(etResolver.resolveEntityType(entityClass));
visited.add(new Binding<IEntity, Model>(source, model));
final BeanWrapperImpl bw = new BeanWrapperImpl(source);
for(final PropertyDescriptor pd : bw.getPropertyDescriptors()) {
final String pname = pd.getName();
// skip certain properties...
if(!bw.isWritableProperty(pname) || !isMarshalableProperty(pd)) {
continue;
}
final Class<?> ptype = pd.getPropertyType();
Object obj = null;
try {
obj = bw.getPropertyValue(pname);
}
catch(final RuntimeException re) {
log.debug("Skipping entity prop: " + pname + " due to: " + re.getMessage());
continue;
}
final PropertyMetadata pdata = generatePropertyData(entityClass, pname);
IModelProperty prop = createValueProperty(ptype, pname, obj, pdata);
if(prop == null) {
// related one
if(IEntity.class.isAssignableFrom(ptype)) {
final RelationInfo ri = schemaInfo.getRelationInfo(entityClass, pname);
final boolean reference = ri.isReference();
if(shouldMarshalRelation(reference, depth, options)) {
final IEntity e = (IEntity) obj;
final Model m = e == null ? null : marshalEntity(e, options, visited, depth + 1);
final IEntityType etype =
ri.getRelatedType() == null ? null : etResolver.resolveEntityType(e == null ? ri.getRelatedType() : e
.entityClass());
prop = new RelatedOneProperty(etype, m, pname, reference);
}
}
// related many collection
else if(Collection.class.isAssignableFrom(ptype)) {
final RelationInfo ri = schemaInfo.getRelationInfo(entityClass, pname);
final boolean reference = ri.isReference();
if(shouldMarshalRelation(reference, depth, options)) {
List<Model> list = null;
if(obj != null) {
list = new ArrayList<Model>();
final Collection<IEntity> set = (Collection<IEntity>) obj;
for(final IEntity e : set) {
final Model nested = marshalEntity(e, options, visited, depth + 1);
list.add(nested);
}
}
prop = new RelatedManyProperty(etResolver.resolveEntityType(ri.getRelatedType()), pname, reference, list);
}