Search in sources :

Example 11 with ModelType

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)));
    });
}
Also used : BasicModelType(com.vaadin.flow.templatemodel.BasicModelType) TemplateModelUtil(com.vaadin.flow.templatemodel.TemplateModelUtil) StateNode(com.vaadin.flow.internal.StateNode) Predicate(java.util.function.Predicate) Json(elemental.json.Json) ReflectTools(com.vaadin.flow.internal.ReflectTools) HashMap(java.util.HashMap) Function(java.util.function.Function) ModelMap(com.vaadin.flow.internal.nodefeature.ModelMap) TemplateElementStateProvider(com.vaadin.flow.dom.impl.TemplateElementStateProvider) Serializable(java.io.Serializable) InvalidTemplateModelException(com.vaadin.flow.templatemodel.InvalidTemplateModelException) PropertyFilter(com.vaadin.flow.templatemodel.PropertyFilter) JsonValue(elemental.json.JsonValue) ModelType(com.vaadin.flow.templatemodel.ModelType) Stream(java.util.stream.Stream) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) Map(java.util.Map) Optional(java.util.Optional) JsonObject(elemental.json.JsonObject) Method(java.lang.reflect.Method) ComplexModelType(com.vaadin.flow.templatemodel.ComplexModelType) BasicModelType(com.vaadin.flow.templatemodel.BasicModelType) ModelType(com.vaadin.flow.templatemodel.ModelType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) ComplexModelType(com.vaadin.flow.templatemodel.ComplexModelType) Optional(java.util.Optional) HashMap(java.util.HashMap) BasicModelType(com.vaadin.flow.templatemodel.BasicModelType) ModelType(com.vaadin.flow.templatemodel.ModelType) ComplexModelType(com.vaadin.flow.templatemodel.ComplexModelType) JsonObject(elemental.json.JsonObject) PropertyFilter(com.vaadin.flow.templatemodel.PropertyFilter) InvalidTemplateModelException(com.vaadin.flow.templatemodel.InvalidTemplateModelException)

Example 12 with ModelType

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");
        }
    }
}
Also used : BasicModelType(com.vaadin.flow.templatemodel.BasicModelType) ModelType(com.vaadin.flow.templatemodel.ModelType) ComplexModelType(com.vaadin.flow.templatemodel.ComplexModelType)

Example 13 with ModelType

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");
    }
}
Also used : ModelMap(com.vaadin.flow.internal.nodefeature.ModelMap) StateNode(com.vaadin.flow.internal.StateNode) ModelType(com.vaadin.flow.templatemodel.ModelType)

Example 14 with ModelType

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");
}
Also used : UI(com.vaadin.flow.component.UI) StateNode(com.vaadin.flow.internal.StateNode) ModelType(com.vaadin.flow.templatemodel.ModelType) PolymerTemplate(com.vaadin.flow.component.polymertemplate.PolymerTemplate)

Example 15 with ModelType

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);
}
Also used : ListModelType(com.vaadin.flow.templatemodel.ListModelType) BeanModelType(com.vaadin.flow.templatemodel.BeanModelType) ListModelType(com.vaadin.flow.templatemodel.ListModelType) ModelType(com.vaadin.flow.templatemodel.ModelType)

Aggregations

ModelType (com.vaadin.flow.templatemodel.ModelType)16 StateNode (com.vaadin.flow.internal.StateNode)7 BasicModelType (com.vaadin.flow.templatemodel.BasicModelType)6 ModelMap (com.vaadin.flow.internal.nodefeature.ModelMap)5 BeanModelType (com.vaadin.flow.templatemodel.BeanModelType)4 ListModelType (com.vaadin.flow.templatemodel.ListModelType)4 ParameterizedType (java.lang.reflect.ParameterizedType)4 Type (java.lang.reflect.Type)4 BeanModelType (com.vaadin.flow.template.angular.model.BeanModelType)3 ComplexModelType (com.vaadin.flow.templatemodel.ComplexModelType)3 InvalidTemplateModelException (com.vaadin.flow.templatemodel.InvalidTemplateModelException)3 Test (org.junit.Test)3 UI (com.vaadin.flow.component.UI)2 PolymerTemplate (com.vaadin.flow.component.polymertemplate.PolymerTemplate)2 ListModelType (com.vaadin.flow.template.angular.model.ListModelType)2 TemplateElementStateProvider (com.vaadin.flow.dom.impl.TemplateElementStateProvider)1 ReflectTools (com.vaadin.flow.internal.ReflectTools)1 ModelList (com.vaadin.flow.internal.nodefeature.ModelList)1 TemplateMap (com.vaadin.flow.internal.nodefeature.TemplateMap)1 JsExpressionBindingProvider (com.vaadin.flow.template.angular.JsExpressionBindingProvider)1