diff --git a/org.springframework.context/src/main/java/org/springframework/model/ui/PresentationModel.java b/org.springframework.context/src/main/java/org/springframework/model/ui/PresentationModel.java index 9cf33a15af..52f174f5a7 100644 --- a/org.springframework.context/src/main/java/org/springframework/model/ui/PresentationModel.java +++ b/org.springframework.context/src/main/java/org/springframework/model/ui/PresentationModel.java @@ -15,7 +15,6 @@ */ package org.springframework.model.ui; - /** * Represents the state and behavior of a presentation independently of the GUI controls used in the interface. * Pulls the state and behavior of a view out into a model class that is part of the presentation. @@ -31,5 +30,23 @@ public interface PresentationModel { * @throws FieldNotFoundException if no such field exists */ FieldModel getFieldModel(String fieldName); + + /** + * If errors are present on this PresentationModel. + * Returns true if at least one FieldModel has {@link BindingStatus#INVALID_SUBMITTED_VALUE invalid submitted values} or is {@link ValidationStatus#INVALID invalid}. + */ + boolean hasErrors(); + /** + * Commit any {@link BindingStatus#DIRTY dirty} fields. + * @throws IllegalStateException if there are field models that have {@link BindingStatus#INVALID_SUBMITTED_VALUE invalid submitted values} or are {@link ValidationStatus#INVALID invalid}. + */ + void commit(); + + /** + * Validate all fields. + * Skips any fields with {@link BindingStatus#INVALID_SUBMITTED_VALUE invalid submitted values}. + */ + void validate(); + } \ No newline at end of file diff --git a/org.springframework.context/src/main/java/org/springframework/model/ui/support/DefaultPresentationModel.java b/org.springframework.context/src/main/java/org/springframework/model/ui/support/DefaultPresentationModel.java index 04d49305b1..0229057b8b 100644 --- a/org.springframework.context/src/main/java/org/springframework/model/ui/support/DefaultPresentationModel.java +++ b/org.springframework.context/src/main/java/org/springframework/model/ui/support/DefaultPresentationModel.java @@ -143,6 +143,20 @@ public class DefaultPresentationModel implements PresentationModel { return field; } + public boolean hasErrors() { + return false; + } + + public void commit() { + + } + + public void validate() { + + } + + // internal helpers + private PropertyFieldModelRule getRule(String fieldName) { PropertyFieldModelRule rule = fieldModelRules.get(fieldName); if (rule == null) { diff --git a/org.springframework.context/src/main/java/org/springframework/model/ui/support/PresentationModelBinder.java b/org.springframework.context/src/main/java/org/springframework/model/ui/support/PresentationModelBinder.java index c452b38ffc..762b2075b1 100644 --- a/org.springframework.context/src/main/java/org/springframework/model/ui/support/PresentationModelBinder.java +++ b/org.springframework.context/src/main/java/org/springframework/model/ui/support/PresentationModelBinder.java @@ -35,28 +35,36 @@ import org.springframework.model.ui.PresentationModel; * @since 3.0 * @see #setMessageSource(MessageSource) * @see #setRequiredFields(String[]) + * @see #setCommitDirtyValue(boolean) * @see #bind(Map, PresentationModel) */ public class PresentationModelBinder extends AbstractBinder { - // subclassing hooks + private boolean commitDirtyValue; + + /** + * Configures if this PresentationModelBinder should eagerly commit the dirty value after a successful field binding. + * Default is false. + */ + public void setCommitDirtyValue(boolean commitDirtyValue) { + this.commitDirtyValue = commitDirtyValue; + } + + // subclass hooks @Override protected FieldBinder createFieldBinder(PresentationModel model) { - return new FieldModelBinder(model, getMessageSource()); + return new FieldModelBinder(model); } // internal helpers - private static class FieldModelBinder implements FieldBinder { + private class FieldModelBinder implements FieldBinder { private PresentationModel presentationModel; - private MessageSource messageSource; - - public FieldModelBinder(PresentationModel presentationModel, MessageSource messageSource) { + public FieldModelBinder(PresentationModel presentationModel) { this.presentationModel = presentationModel; - this.messageSource = messageSource; } public BindingResult bind(String fieldName, Object value) { @@ -64,13 +72,13 @@ public class PresentationModelBinder extends AbstractBinder { try { field = presentationModel.getFieldModel(fieldName); } catch (FieldNotFoundException e) { - return new FieldNotFoundResult(fieldName, value, messageSource); + return new FieldNotFoundResult(fieldName, value, getMessageSource()); } if (!field.isEditable()) { - return new FieldNotEditableResult(fieldName, value, messageSource); + return new FieldNotEditableResult(fieldName, value, getMessageSource()); } else { field.applySubmittedValue(value); - if (field.getBindingStatus() == BindingStatus.DIRTY) { + if (field.getBindingStatus() == BindingStatus.DIRTY && commitDirtyValue) { field.commit(); } return new AlertBindingResult(fieldName, value, field.getStatusAlert()); diff --git a/org.springframework.context/src/test/java/org/springframework/model/ui/support/PresentationModelBinderTests.java b/org.springframework.context/src/test/java/org/springframework/model/ui/support/PresentationModelBinderTests.java index dff89c33a0..5ff6af946a 100644 --- a/org.springframework.context/src/test/java/org/springframework/model/ui/support/PresentationModelBinderTests.java +++ b/org.springframework.context/src/test/java/org/springframework/model/ui/support/PresentationModelBinderTests.java @@ -48,6 +48,7 @@ public class PresentationModelBinderTests { bean = new TestBean(); presentationModel = new DefaultPresentationModel(bean); binder = new PresentationModelBinder(); + binder.setCommitDirtyValue(true); LocaleContextHolder.setLocale(Locale.US); } diff --git a/org.springframework.context/src/test/java/org/springframework/model/ui/support/WebBinderTests.java b/org.springframework.context/src/test/java/org/springframework/model/ui/support/WebBinderTests.java index a6617a189c..aaa4085186 100644 --- a/org.springframework.context/src/test/java/org/springframework/model/ui/support/WebBinderTests.java +++ b/org.springframework.context/src/test/java/org/springframework/model/ui/support/WebBinderTests.java @@ -34,7 +34,8 @@ public class WebBinderTests { public void setUp() { LocaleContextHolder.setLocale(Locale.US); presentationModel = new DefaultPresentationModel(bean); - binder = new WebBinder(); + binder = new WebBinder(); + binder.setCommitDirtyValue(true); } @After