Skip to content

Commit

Permalink
Merge branch 'main' into issues/19379-flow-components-in-react
Browse files Browse the repository at this point in the history
  • Loading branch information
platosha authored Jun 3, 2024
2 parents 0e0c4ce + a463b40 commit 1419681
Show file tree
Hide file tree
Showing 55 changed files with 1,482 additions and 360 deletions.
11 changes: 6 additions & 5 deletions flow-data/src/main/java/com/vaadin/flow/data/binder/Binder.java
Original file line number Diff line number Diff line change
Expand Up @@ -1444,14 +1444,15 @@ private BindingValidationStatus<TARGET> doValidation() {
* @return the value context
*/
protected ValueContext createValueContext() {
return createValueContext(field);
return createValueContext(binder, field);
}

static ValueContext createValueContext(HasValue<?, ?> field) {
static ValueContext createValueContext(Binder binder,
HasValue<?, ?> field) {
if (field instanceof Component) {
return new ValueContext((Component) field, field);
return new ValueContext(binder, (Component) field, field);
}
return new ValueContext(null, field, findLocale());
return new ValueContext(binder, null, field, findLocale());
}

/**
Expand Down Expand Up @@ -2858,7 +2859,7 @@ private List<BindingValidationStatus<?>> validateBindings() {
private List<ValidationResult> validateBean(BEAN bean) {
Objects.requireNonNull(bean, "bean cannot be null");
return validators.stream()
.map(validator -> validator.apply(bean, new ValueContext()))
.map(validator -> validator.apply(bean, new ValueContext(this)))
.collect(Collectors.collectingAndThen(Collectors.toList(),
Collections::unmodifiableList));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@ public static boolean testConvertedDefaultValue(
Converter converter = ((BindingBuilderImpl<?, ?, ?>) binding)
.getConverterValidatorChain();

Binder<?> binder = ((BindingBuilderImpl<?, ?, ?>) binding)
.getBinder();
Result<?> result = converter.convertToModel(field.getEmptyValue(),
BindingImpl.createValueContext(field));
BindingImpl.createValueContext(binder, field));

if (!result.isError()) {
Object convertedEmptyValue = result
Expand Down
119 changes: 119 additions & 0 deletions flow-data/src/main/java/com/vaadin/flow/data/binder/ValueContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,111 @@
*/
public class ValueContext implements Serializable {

private final Binder<?> binder;
private final Component component;
private final HasValue<?, ?> hasValue;
private final Locale locale;

/**
* Constructor for {@code ValueContext} without a {@code Locale}.
*
* @param binder
* the Binder using the value context
*/
public ValueContext(Binder<?> binder) {
this.binder = binder;
component = null;
hasValue = null;
locale = findLocale(component);
}

/**
* Constructor for {@code ValueContext} without a {@code Component}.
*
* @param binder
* the Binder using the value context
* @param locale
* The locale used with conversion. Can be null.
*/
public ValueContext(Binder binder, Locale locale) {
this.binder = binder;
component = null;
this.locale = locale;
hasValue = null;
}

/**
* Constructor for {@code ValueContext}.
*
* @param binder
* the Binder using the value context
* @param component
* The component related to current value. Can be null. If the
* component implements {@link HasValue}, it will be returned by
* {@link #getHasValue()} as well.
*/
public ValueContext(Binder binder, Component component) {
this.binder = binder;
Objects.requireNonNull(component,
"Component can't be null in ValueContext construction");
this.component = component;
if (component instanceof HasValue) {
hasValue = (HasValue<?, ?>) component;
} else {
hasValue = null;
}
locale = findLocale(component);
}

/**
* Constructor for {@code ValueContext}.
*
* @param binder
* the Binder using the value context
* @param component
* The component related to current value. Can be null.
* @param hasValue
* The value source related to current value. Can be null.
*/
public ValueContext(Binder binder, Component component,
HasValue<?, ?> hasValue) {
this.binder = binder;
Objects.requireNonNull(component,
"Component can't be null in ValueContext construction");
this.component = component;
this.hasValue = hasValue;
locale = findLocale(component);
}

/**
* Constructor for {@code ValueContext}.
*
* @param binder
* the Binder using the value context
* @param component
* The component can be {@code null}.
* @param locale
* The locale used with conversion. Can be {@code null}.
* @param hasValue
* The value source related to current value. Can be
* {@code null}.
*/
public ValueContext(Binder binder, Component component,
HasValue<?, ?> hasValue, Locale locale) {
this.binder = binder;
this.component = component;
this.hasValue = hasValue;
this.locale = locale;
}

/**
* Constructor for {@code ValueContext} without a {@code Locale}.
*
* @deprecated Use the version with binder reference instead
*/
@Deprecated
public ValueContext() {
this.binder = null;
component = null;
hasValue = null;
locale = findLocale(component);
Expand All @@ -51,8 +148,11 @@ public ValueContext() {
*
* @param locale
* The locale used with conversion. Can be null.
* @deprecated Use the version with binder reference instead
*/
@Deprecated
public ValueContext(Locale locale) {
this.binder = null;
component = null;
this.locale = locale;
hasValue = null;
Expand All @@ -65,8 +165,11 @@ public ValueContext(Locale locale) {
* The component related to current value. Can be null. If the
* component implements {@link HasValue}, it will be returned by
* {@link #getHasValue()} as well.
* @deprecated Use the version with binder reference instead
*/
@Deprecated
public ValueContext(Component component) {
this.binder = null;
Objects.requireNonNull(component,
"Component can't be null in ValueContext construction");
this.component = component;
Expand All @@ -85,8 +188,11 @@ public ValueContext(Component component) {
* The component related to current value. Can be null.
* @param hasValue
* The value source related to current value. Can be null.
* @deprecated Use the version with binder reference instead
*/
@Deprecated
public ValueContext(Component component, HasValue<?, ?> hasValue) {
this.binder = null;
Objects.requireNonNull(component,
"Component can't be null in ValueContext construction");
this.component = component;
Expand All @@ -104,9 +210,12 @@ public ValueContext(Component component, HasValue<?, ?> hasValue) {
* @param hasValue
* The value source related to current value. Can be
* {@code null}.
* @deprecated Use the version with binder reference instead
*/
@Deprecated
public ValueContext(Component component, HasValue<?, ?> hasValue,
Locale locale) {
this.binder = null;
this.component = component;
this.hasValue = hasValue;
this.locale = locale;
Expand Down Expand Up @@ -157,4 +266,14 @@ public Optional<Locale> getLocale() {
public Optional<HasValue<?, ?>> getHasValue() {
return Optional.ofNullable(hasValue);
}

/**
* Returns an {@code Optional} for the {@code Binder} owning this value
* context.
*
* @return the optional of {@code Binder}
*/
public Optional<Binder<?>> getBinder() {
return Optional.ofNullable(binder);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ public class ValueContextTest extends UI {
private static final Locale COMPONENT_LOCALE = Locale.FRENCH;
private TestTextField textField;

private Binder<PasswordBean> binder;
private TestTextField passwordField;
private TestTextField confirmPasswordField;

@Test
public void locale_from_component() {
setLocale(COMPONENT_LOCALE);
Expand Down Expand Up @@ -103,12 +107,48 @@ public void getLocale_localeComesFromComponentUI() {
Assert.assertEquals(Locale.GERMAN, context.getLocale().get());
}

@Test
public void testWithBinder() {

// Test password mismatch
PasswordBean passwordBean = new PasswordBean();
binder.setBean(passwordBean);
passwordField.setValue("abc123");
confirmPasswordField.setValue("def456");
BinderValidationStatus<PasswordBean> status = binder.validate();
Assert.assertEquals(1, status.getFieldValidationErrors().size());
Assert.assertEquals(status.getFieldValidationErrors().iterator().next()
.getMessage().get(), "Passwords must match");

// Test password match
confirmPasswordField.setValue("abc123");
status = binder.validate();
Assert.assertEquals(0, status.getFieldValidationErrors().size());
}

@Before
public void setUp() {
setLocale(UI_LOCALE);
UI.setCurrent(this);
textField = new TestTextField();
add(textField);

binder = new Binder<>(PasswordBean.class);
passwordField = new TestTextField();
confirmPasswordField = new TestTextField();
binder.forField(passwordField).bind("password");
binder.forField(confirmPasswordField)
.withValidator((confirmValue, valueContext) -> {
Binder<?> ctxBinder = valueContext.getBinder().get();
Assert.assertSame(ctxBinder, binder);
TestTextField passwordField = (TestTextField) ctxBinder
.getBinding("password").get().getField();
return !Objects.equals(confirmValue,
passwordField.getValue())
? ValidationResult
.error("Passwords must match")
: ValidationResult.ok();
}).bind("confirmPassword");
}

@After
Expand All @@ -119,4 +159,28 @@ public void tearDown() {
@Override
public void init(VaadinRequest request) {
}

// PasswordBean

public static class PasswordBean {

private String password;
private String confirmPassword;

public String getPassword() {
return this.password;
}

public void setPassword(final String password) {
this.password = password;
}

public String getConfirmPassword() {
return this.confirmPassword;
}

public void setConfirmPassword(final String confirmPassword) {
this.confirmPassword = confirmPassword;
}
}
}
2 changes: 1 addition & 1 deletion flow-plugins/flow-dev-bundle-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.26.1</version>
<version>1.26.2</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ public boolean isFrontendHotdeploy() {
return frontendHotdeploy;
}
File frontendDirectory = BuildFrontendUtil.getFrontendDirectory(this);
return FrontendUtils.isHillaUsed(frontendDirectory);
return isHillaUsed(project, frontendDirectory);
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions flow-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.26.1</version>
<version>1.26.2</version>
</dependency>
<!-- TESTING DEPENDENCIES -->
<dependency>
Expand All @@ -147,7 +147,7 @@
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.7.2</version>
<version>2.7.3</version>
<scope>test</scope>
</dependency>

Expand Down
Loading

0 comments on commit 1419681

Please sign in to comment.