BeanModelType implements ComplexModelType<T> { public void importProperties(ElementPropertyMap model, Object bean, PropertyFilter propertyFilter) { Class<?> beanClass = bean.getClass(); assert isBean(beanClass); Map<String, Object> values = new HashMap<>(); beanPropertyCache.get(beanClass).forEach((propertyName, getter) -> { if (!hasProperty(propertyName) || !propertyFilter.test(propertyName)) { return; } Type getterType = getter.getGenericReturnType(); ModelType propertyType = getPropertyType(propertyName); if (!propertyType.accepts(getterType)) { throw new IllegalArgumentException(String.format( "Expected type '%s' for property '%s' but imported type is '%s'", propertyType.getJavaType().getTypeName(), propertyName, getterType.getTypeName())); } try { Object value = getter.invoke(bean); values.put(propertyName, value); } catch (Exception e) { throw new IllegalArgumentException( "Cannot access bean property " + propertyName, e); } }); values.forEach((name, value) -> { ModelType type = getPropertyType(name); model.setProperty(name, type.applicationToModel(value, new PropertyFilter(propertyFilter, name))); }); } protected  BeanModelType(Class<T> proxyType,
            Map<String, BeanModelTypeProperty> properties,
            boolean allowEmptyProperties); private  BeanModelType(Class<T> javaType, PropertyFilter propertyFilter,
            PathLookup<ModelEncoder<?, ?>> converterLookup,
            PathLookup<ClientUpdateMode> clientUpdateLookup); protected  BeanModelType(Class<T> javaType, PropertyFilter propertyFilter,
            boolean allowEmptyProperties); static boolean isBean(Type type); boolean hasProperty(String propertyName); ModelType getPropertyType(String propertyName); @Override T modelToApplication(Serializable modelValue); Class<T> getProxyType(); @Override StateNode applicationToModel(Object applicationValue,
            PropertyFilter filter); void importProperties(ElementPropertyMap model, Object bean,
            PropertyFilter propertyFilter); ModelType resolveType(String modelPath); @Override @SuppressWarnings("unchecked") BeanModelType<C> cast(Class<C> proxyType); Stream<String> getPropertyNames(); @Override boolean accepts(Type applicationType); @Override Type getJavaType(); @Override JsonValue toJson(); @Override void createInitialValue(StateNode node, String property); void createInitialValues(StateNode node); Map<String, Boolean> getClientUpdateAllowedProperties(
            Set<String> twoWayBindingPaths);  }
@Test public void importBean() { BeanModelType<Bean> beanType = new BeanModelType<>(Bean.class, PropertyFilter.ACCEPT_ALL, false); ElementPropertyMap model = createEmptyModel(); Bean bean = new Bean(3); beanType.importProperties(model, bean, PropertyFilter.ACCEPT_ALL); assertThreeBean(model); }
@Test(expected = IllegalArgumentException.class) public void importBean_incompatibleBean() { BeanModelType<Bean> beanType = new BeanModelType<>(Bean.class, PropertyFilter.ACCEPT_ALL, false); ElementPropertyMap model = createEmptyModel(); DifferentBean bean = new DifferentBean(3); beanType.importProperties(model, bean, PropertyFilter.ACCEPT_ALL); }