use of com.vaadin.flow.templatemodel.ModelType in project flow by vaadin.
the class BeanModelType method importProperties.
/**
* Imports properties from a bean into a model map based on the properties
* in this model type.
*
* @param model
* the model map to import values into
* @param bean
* the bean to get values from
* @param propertyFilter
* defines which properties from this model type to import
*/
public void importProperties(ModelMap model, Object bean, PropertyFilter propertyFilter) {
Class<? extends Object> beanClass = bean.getClass();
assert isBean(beanClass);
/*
* Collect all values and let getters throw before starting to populate
* the model.
*
* Can't use Collectors.toMap() since it disallows null values.
*/
Map<String, Object> values = new HashMap<>();
properties.keySet().stream().filter(propertyFilter).map(name -> ReflectTools.getGetter(beanClass, name)).filter(Optional::isPresent).map(Optional::get).forEach(getter -> {
String propertyName = ReflectTools.getPropertyName(getter);
Type beanPropertyType = ReflectTools.getPropertyType(getter);
ModelType modelPropertyType = getPropertyType(propertyName);
if (!modelPropertyType.accepts(beanPropertyType)) {
throw new IllegalArgumentException(propertyName + " is not of the expected type");
}
try {
Object value = getter.invoke(bean);
values.put(propertyName, value);
} catch (Exception e) {
throw new IllegalArgumentException("Cannot access bean property " + propertyName, e);
}
});
// Populate the model with the extracted values
values.forEach((name, value) -> {
ModelType type = getPropertyType(name);
model.setValue(name, type.applicationToModel(value, new PropertyFilter(propertyFilter, name)));
});
}
use of com.vaadin.flow.templatemodel.ModelType in project flow by vaadin.
the class BeanModelType method resolveType.
/**
* Finds the model type denoted by the given model path.
*
* @param modelPath
* the model path to resolve, not <code>null</code>
* @return the model type of the resolved path, not <code>null</code>
*/
public ModelType resolveType(String modelPath) {
assert modelPath != null;
if (modelPath.isEmpty()) {
return this;
}
String[] parts = modelPath.split("\\.", 2);
String propertyName = parts[0];
if (!hasProperty(propertyName)) {
throw new IllegalArgumentException("No such property: " + propertyName);
}
ModelType propertyType = getPropertyType(propertyName);
if (parts.length == 1) {
// Last segment of the path
return propertyType;
} else {
String subPath = parts[1];
if (propertyType instanceof BeanModelType<?>) {
return ((BeanModelType<?>) propertyType).resolveType(subPath);
} else {
throw new IllegalArgumentException(propertyName + " is not a bean");
}
}
}
use of com.vaadin.flow.templatemodel.ModelType in project flow by vaadin.
the class TemplateModelUtil method resolveBeanAndRun.
/**
* Resolves a bean model type and model map based on a model instance and
* passes those values to the provided callback.
*
* @param <R>
* the return value type
* @param model
* the model instance for which to resolve a type and a map, not
* <code>null</code>
* @param modelPath
* the model path to resolve, not <code>null</code>
* @param callback
* the callback to run with the resolved bean type and the model
* map, not <code>null</code>
* @return the value returned by the callback
*/
public static <R> R resolveBeanAndRun(TemplateModel model, String modelPath, BiFunction<BeanModelType<?>, ModelMap, R> callback) {
assert model != null;
assert modelPath != null;
assert callback != null;
BeanModelType<?> modelType = TemplateModelProxyHandler.getModelTypeForProxy(model);
ModelType beanType = modelType.resolveType(modelPath);
if (beanType instanceof BeanModelType<?>) {
StateNode stateNode = TemplateModelProxyHandler.getStateNodeForProxy(model);
ModelMap modelMap = ModelMap.get(stateNode);
ModelMap beanMap = modelMap.resolveModelMap(modelPath);
return callback.apply((BeanModelType<?>) beanType, beanMap);
} else {
throw new IllegalArgumentException(modelPath + " does not resolve to a bean");
}
}
use of com.vaadin.flow.templatemodel.ModelType in project flow by vaadin.
the class PolymerPublishedEventRpcHandlerTest method getTemplateItem.
public static Object getTemplateItem(Component template, JsonObject argValue, Type convertedType) {
final Optional<UI> ui = template.getUI();
if (ui.isPresent()) {
StateNode node = ui.get().getInternals().getStateTree().getNodeById((int) argValue.getNumber("nodeId"));
ModelType propertyType = ((PolymerTemplate<?>) template).getModelType(convertedType);
return propertyType.modelToApplication(node);
}
throw new IllegalStateException("Event sent for a non attached template component");
}
use of com.vaadin.flow.templatemodel.ModelType in project flow by vaadin.
the class AbstractTemplate method getModelType.
/**
* Get the {@code ModelType} for given class.
*
* @param type
* Type to get the ModelType for
* @return ModelType for given Type
*/
public ModelType getModelType(Type type) {
List<ModelType> modelTypes = ModelDescriptor.get(getModelType()).getPropertyNames().map(this::getModelType).collect(Collectors.toList());
for (ModelType mtype : modelTypes) {
if (type.equals(mtype.getJavaType())) {
return mtype;
} else if (mtype instanceof ListModelType) {
ModelType modelType = getModelTypeForListModel(type, mtype);
if (modelType != null) {
return modelType;
}
}
}
String msg = String.format("Couldn't find ModelType for requested class %s", type.getTypeName());
throw new IllegalArgumentException(msg);
}
Aggregations