All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
pl.fhframework.binding.CompiledBinding Maven / Gradle / Ivy
package pl.fhframework.binding;
import lombok.Getter;
import org.springframework.util.ClassUtils;
import pl.fhframework.core.FhAuthorizationException;
import pl.fhframework.core.FhBindingException;
import pl.fhframework.BindingResult;
import pl.fhframework.ReflectionUtils;
import pl.fhframework.format.FhConversionService;
import pl.fhframework.model.forms.Component;
import java.text.ParseException;
import java.util.Optional;
import java.util.function.*;
/**
* Created by Piotr on 2017-02-14.
*/
public class CompiledBinding extends ModelBinding {
@FunctionalInterface
public interface BaseObjectGetter extends Supplier {}
@FunctionalInterface
public interface ValueGetterForBaseObject extends Function {}
@FunctionalInterface
public interface ValueSetterForBaseObject extends BiConsumer {}
@FunctionalInterface
public interface ValueGetter extends Supplier {}
@FunctionalInterface
public interface ValueSetter extends Consumer {}
private String attributeName;
@Getter
private Class targetType;
private Supplier conversionServiceSupplier;
// fields for base object usage
private BaseObjectGetter baseObjectGetter;
private ValueGetterForBaseObject valueGetterForBaseObject;
private ValueSetterForBaseObject valueSetterForBaseObject;
// fields without base object usage
private ValueGetter valueGetter;
private ValueSetter valueSetter;
public CompiledBinding(String bindingExpression, String attributeName, Class targetType,
Supplier conversionServiceSupplier,
BaseObjectGetter baseObjectGetter,
ValueGetterForBaseObject valueGetterForBaseObject,
ValueSetterForBaseObject valueSetterForBaseObject) {
super(bindingExpression);
this.attributeName = attributeName;
this.baseObjectGetter = (BaseObjectGetter) baseObjectGetter;
this.valueGetterForBaseObject = (ValueGetterForBaseObject) valueGetterForBaseObject;
this.valueSetterForBaseObject = (ValueSetterForBaseObject) valueSetterForBaseObject;
this.targetType = targetType;
this.conversionServiceSupplier = conversionServiceSupplier;
}
public CompiledBinding(String bindingExpression, String attributeName, Class targetType,
Supplier conversionServiceSupplier,
ValueGetter valueGetter, ValueSetter valueSetter) {
super(bindingExpression);
this.attributeName = attributeName;
this.valueGetter = valueGetter;
this.valueSetter = valueSetter;
this.targetType = targetType;
this.conversionServiceSupplier = conversionServiceSupplier;
}
public CompiledBinding(Class targetType, ValueGetter valueGetter, ValueSetter valueSetter) {
super("__INLINE_BINDING__");
this.valueGetter = valueGetter;
this.valueSetter = valueSetter;
this.targetType = targetType;
}
public CompiledBinding(Class targetType, ValueGetter valueGetter) {
this(targetType, valueGetter, null);
}
@Override
public boolean canChange() {
return valueSetter != null || (baseObjectGetter != null && valueSetterForBaseObject != null);
}
@Override
public void setValue(T value, Optional formatter) {
if (!canChange()) {
throw new RuntimeException(bindingExpression + " is a read-only binding");
}
try {
value = (T) convertValue(value, formatter);
if (baseObjectGetter != null) {
valueSetterForBaseObject.accept(baseObjectGetter.get(), value);
} else {
valueSetter.accept(value);
}
} catch (Exception e) {
throw new FhBindingException("Exception while setting value to compiled binding: " + bindingExpression, e);
}
}
@Override
public BindingResult getBindingResult() {
try {
if (baseObjectGetter != null) {
Object baseObject = baseObjectGetter.get();
return new BindingResult<>(baseObject, attributeName, valueGetterForBaseObject.apply(baseObject));
} else {
return new BindingResult<>(null, attributeName, valueGetter.get());
}
} catch (FhAuthorizationException e) {
throw e;
} catch (Exception e) {
throw new FhBindingException("Exception while getting value to compiled binding: " + bindingExpression, e);
}
}
@Override
public ModelBinding clone(Component newOwner) {
return this; // compiled binding is immutable
}
public Object convertValue(Object newValue, Optional formatterOpt) throws ParseException {
if (newValue == null) {
return null;
}
Class valueType = newValue.getClass();
// TODO: move this logic to java generation at least when using Strings or formatters
if (formatterOpt.isPresent() && ClassUtils.isAssignable(valueType, String.class)) {
if (conversionServiceSupplier == null) {
throw new FhBindingException("Formatter is specified but conversion service is not supplied");
}
String formatter = formatterOpt.get();
FhConversionService conversionService = conversionServiceSupplier.get();
if (conversionService.canConvertToObject(targetType, formatter)) {
return conversionService.parseUsingCustomFormatter((String) newValue, formatter);
}
}
if (valueType != targetType && !targetType.isAssignableFrom(valueType)) {
if (conversionServiceSupplier == null) {
throw new FhBindingException("Value: '" + newValue + "' needs conversion to model of type: '" + targetType.getName() + "', but conversion service is not supplied");
}
// TODO: move this logic to java generation at least when using Strings or formatters
FhConversionService conversionService = conversionServiceSupplier.get();
if (conversionService.canConvert(ReflectionUtils.resolveToRealClass(valueType), targetType)) {
newValue = conversionService.convert(newValue, targetType);
} else {
throw new FhBindingException("Can't convert value: '" + newValue + "' to model of type: '" + targetType.getName() + "'");
}
}
return newValue;
}
}