public void builtinConverters() { // tag::bultincnv[] PropertyValueConverter.numericBoolean(Integer.class); // <1> PropertyValueConverter.localDate(); // <2> PropertyValueConverter.localDateTime(); // <3> PropertyValueConverter.enumByOrdinal(); // <4> PropertyValueConverter.enumByName(); // <5> Property.Builder<Boolean, Property<Boolean>, ?> builder = getPropertyBuilder(); builder.converter(PropertyValueConverter.numericBoolean(Integer.class)); // <6> // end::bultincnv[] }
@Override public TYPE fromModel(MODEL value) { return converter.fromModel(value, property); }
@Override public MODEL toModel(TYPE value) { return converter.toModel(value, property); }
@SuppressWarnings("unchecked") @Override public <MODEL> B elementConverter(PropertyValueConverter<E, MODEL> elementConverter) { ObjectUtils.argumentNotNull(elementConverter, "Element value converter must be not null"); return converter(new CollectionCallbackPropertyValueConverter<>(getType(), elementConverter.getModelType(), v -> elementConverter.fromModel(v, (Property<E>) this), v -> elementConverter.toModel(v, (Property<E>) this), getDefaultInstanceProvider())); }
/** * Create a new {@link Input} from another {@link Input} with a different value type, using given * {@link PropertyValueConverter} to perform value conversions. * @param <T> New value type * @param <V> Original value type * @param input Actual input (not null) * @param property Property to provide to the converter * @param converter Value converter (not null) * @return A new {@link Input} of the converted value type */ static <T, V> Input<T> from(Input<V> input, Property<T> property, PropertyValueConverter<T, V> converter) { ObjectUtils.argumentNotNull(converter, "PropertyValueConverter must be not null"); return new InputConverterAdapter<>(input, Converter.from(value -> converter.fromModel(value, property), value -> converter.toModel(value, property), e -> e.getMessage())); }
/** * Create a new {@link BooleanProperty} with given <code>name</code>, using a default {@link PropertyValueConverter} * to convert a numeric model data type into the boolean type. * @param <N> Numeric model data type * @param name Property name (not null) * @param modelType Numeric model data type (not null) * @return {@link BooleanProperty} builder * @see PropertyValueConverter#numericBoolean(Class) */ static <N extends Number> BooleanPropertyBuilder create(String name, Class<N> modelType) { ObjectUtils.argumentNotNull(modelType, "Model type must be not null"); return create(name).converter(PropertyValueConverter.numericBoolean(modelType)); }
@SuppressWarnings({ "rawtypes", "unchecked" }) @Override public T write(PropertyBox propertyBox, T instance, boolean ignoreMissing) { ObjectUtils.argumentNotNull(propertyBox, "PropertyBox must be not null"); ObjectUtils.argumentNotNull(instance, "Bean instance must be not null"); propertyBox.stream().filter(p -> !p.isReadOnly()).filter(p -> Path.class.isAssignableFrom(p.getClass())) .map(p -> (Path<?>) p).forEach(p -> { getProperty(p, ignoreMissing).ifPresent(bp -> { final Property<Object> property = ((Property) p); final Object boxValue = propertyBox.getValue(property); Object value = boxValue; // check conversion if (!TypeUtils.isAssignable(bp.getType(), property.getType())) { value = property.getConverter() .filter(c -> TypeUtils.isAssignable(bp.getType(), c.getModelType())) .map(c -> ((PropertyValueConverter) c).toModel(boxValue, property)) .orElse(boxValue); } write(bp, p.getType(), value, instance); }); }); return instance; }
property.getConverter().filter(c -> (type != null && TypeUtils.isAssignable(type, c.getModelType()))) .map(cv -> ((PropertyValueConverter) cv).fromModel(value, property)).orElse(value), instanceToWrite);
@SuppressWarnings({ "unchecked", "rawtypes" }) private <V> V read(BeanProperty<?> property, T instance, Class<V> expectedType) { ObjectUtils.argumentNotNull(property, "Property must be not null"); ObjectUtils.argumentNotNull(instance, "Bean instance must be not null"); Object value = null; Object currentInstance = instance; for (BeanProperty<?> p : getPropertyHierarchy(property)) { currentInstance = value = readValue(p, currentInstance); } final Object readValue = value; final V propertyValue = (expectedType == null) ? (V) readValue : (V) property.getConverter() .filter(c -> (readValue == null || (!TypeUtils.isAssignable(readValue.getClass(), expectedType) && TypeUtils.isAssignable(readValue.getClass(), c.getPropertyType())))) .map(cv -> ((PropertyValueConverter) cv).toModel(readValue, property)).orElse(readValue); LOGGER.debug(() -> "BeanPropertySet: read property [" + property + "] value [" + propertyValue + "] from instance [" + instance + "]"); return propertyValue; }
@SuppressWarnings({ "unchecked", "rawtypes" }) @Override protected Builder<?> processJpaBeanProperty(Builder<?> property, Class<?> beanOrNestedClass) { if (!property.getConverter().isPresent()) { property.getAnnotation(Enumerated.class).ifPresent(a -> { final EnumType enumType = a.value(); if (enumType == EnumType.STRING) { ((Builder) property).converter(PropertyValueConverter.enumByName()); } else { ((Builder) property).converter(PropertyValueConverter.enumByOrdinal()); } LOGGER.debug(() -> "JpaEnumeratedBeanPropertyPostProcessor: setted property [" + property + "] value converter to default enumeration converter using [" + enumType.name() + "] mode"); }); } else { LOGGER.debug(() -> "JpaEnumeratedBeanPropertyPostProcessor: property [" + property + "] has a PropertyValueConverter [" + property.getConverter().get() + "]: skip JPA Enumerated annotation processing"); } return property; }
@Override public Class<MODEL> getModelType() { return converter.getModelType(); }
@SuppressWarnings("unchecked") @Override public <MODEL> B elementConverter(PropertyValueConverter<E, MODEL> elementConverter) { ObjectUtils.argumentNotNull(elementConverter, "Element value converter must be not null"); return converter(new CollectionCallbackPropertyValueConverter<>(getType(), elementConverter.getModelType(), v -> elementConverter.fromModel(v, (Property<E>) this), v -> elementConverter.toModel(v, (Property<E>) this), getDefaultInstanceProvider())); }
/** * Create a new {@link Input} from another {@link Input} with a different value type, using given * {@link PropertyValueConverter} to perform value conversions. * @param <T> New value type * @param <V> Original value type * @param input Actual input (not null) * @param property Property to provide to the converter * @param converter Value converter (not null) * @return A new {@link Input} of the converted value type */ static <T, V> Input<T> from(Input<V> input, Property<T> property, PropertyValueConverter<T, V> converter) { ObjectUtils.argumentNotNull(converter, "PropertyValueConverter must be not null"); return new InputConverterAdapter<>(input, Converter.from(value -> converter.fromModel(value, property), value -> converter.toModel(value, property), e -> e.getMessage())); }
public void input7() { // tag::input7[] BooleanProperty PROPERTY = BooleanProperty.create("test"); Input<Integer> integerInput = Input.number(Integer.class).build(); // <1> Input<Boolean> booleanInput = Input.from(integerInput, PROPERTY, PropertyValueConverter.numericBoolean(Integer.class)); // <2> // end::input7[] }
/** * Checks if the type of given {@link Property} is admitted as document identifier value type. Admitted types are: * {@link String}, {@link BigInteger} and {@link ObjectId}. * @param property Property to check * @return <code>true</code> if given type is admitted as document identifier type, <code>false</code> otherwise */ @SuppressWarnings("rawtypes") private static boolean isValidDocumentIdPropertyType(Property<?> property) { final Class<?> type = property.getConverter().map(c -> (Class) c.getModelType()).orElse(property.getType()); return isAdmittedDocumentIdType(type); }
public void input8() { // tag::input8[] Input<Integer> integerInput = Components.input.number(Integer.class).build(); final Property<Boolean> BOOL_PROPERTY = PathProperty.create("bool", Boolean.class); // <1> Input<Boolean> booleanInput = Input.from(integerInput, BOOL_PROPERTY, PropertyValueConverter.numericBoolean(Integer.class)); // <2> // end::input8[] }
/** * Return the given <code>value</code> against this property, converting it to required model data type if a * {@link PropertyValueConverter} is present. * @param value Property value (can be null) * @return Model value, possibly converted using the {@link PropertyValueConverter} */ default Object getConvertedValue(T value) { return getConverter().map((c) -> (Object) c.toModel(value, this)).orElse(value); }
/** * Check property value before putting it in PropertyBox. * @param <T> Property and value type * @param property Property * @param value Property value * @return Checked property value * @throws TypeMismatchException Value is not consistent with property type */ @SuppressWarnings("unchecked") protected <T> T checkupPropertyValue(Property<T> property, T value) throws TypeMismatchException { return validatePropertyValue(property, property.getConverter().filter(c -> isModelTypeConvertible(value, c)) .map(cv -> ((PropertyValueConverter<T, Object>) cv).fromModel(value, property)) .orElseGet(() -> checkValueTypeConsistency(property, value))); }
return TypeUtils.isAssignable(value.getClass(), converter.getModelType());