git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@1595 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
Keith Donald 2009-07-22 20:02:35 +00:00
parent a9e4f59234
commit 4831d2a832
4 changed files with 58 additions and 34 deletions

View File

@ -70,8 +70,17 @@ public interface Binding {
* Is {@link BindingStatus#INVALID_SOURCE_VALUE} if a source value could not be applied. * Is {@link BindingStatus#INVALID_SOURCE_VALUE} if a source value could not be applied.
* Is {@link BindingStatus#COMMIT_FAILURE} if a buffered value could not be committed. * Is {@link BindingStatus#COMMIT_FAILURE} if a buffered value could not be committed.
*/ */
BindingStatus getStatus(); BindingStatus getBindingStatus();
/**
* The current validation status.
* Initially {@link ValidationStatus#NOT_VALIDATED}.
* Is {@link ValidationStatus#VALID} after value is successfully validated.
* Is {@link ValidationStatus#INVALID} after value fails validation.
* Resets to {@value ValidationStatus#NOT_VALIDATED} when value changes.
*/
ValidationStatus getValidationStatus();
/** /**
* An alert that communicates current status to the user. * An alert that communicates current status to the user.
* Returns <code>null</code> if {@link BindingStatus#CLEAN} and {@link ValidationStatus#NOT_VALIDATED}. * Returns <code>null</code> if {@link BindingStatus#CLEAN} and {@link ValidationStatus#NOT_VALIDATED}.
@ -99,6 +108,13 @@ public interface Binding {
*/ */
Object getInvalidSourceValue(); Object getInvalidSourceValue();
/**
* Validate the model value.
* Sets to {@link ValidationStatus#VALID} if succeeds.
* Sets to {@link ValidationStatus#INVALID} if fails.
*/
void validate();
/** /**
* Commit the buffered value to the model. * Commit the buffered value to the model.
* Sets to {@link BindingStatus#COMMITTED} if succeeds. * Sets to {@link BindingStatus#COMMITTED} if succeeds.

View File

@ -135,7 +135,7 @@ public class GenericBinder implements Binder {
return new PropertyNotEditableResult(property, value, messageSource); return new PropertyNotEditableResult(property, value, messageSource);
} else { } else {
binding.applySourceValue(value); binding.applySourceValue(value);
if (binding.getStatus() == BindingStatus.DIRTY) { if (binding.getBindingStatus() == BindingStatus.DIRTY) {
binding.commit(); binding.commit();
} }
return new BindingStatusResult(property, value, binding.getStatusAlert()); return new BindingStatusResult(property, value, binding.getStatusAlert());

View File

@ -36,6 +36,7 @@ import org.springframework.ui.alert.Alert;
import org.springframework.ui.alert.Severity; import org.springframework.ui.alert.Severity;
import org.springframework.ui.binding.Binding; import org.springframework.ui.binding.Binding;
import org.springframework.ui.binding.BindingStatus; import org.springframework.ui.binding.BindingStatus;
import org.springframework.ui.binding.ValidationStatus;
import org.springframework.ui.format.Formatter; import org.springframework.ui.format.Formatter;
import org.springframework.ui.message.MessageBuilder; import org.springframework.ui.message.MessageBuilder;
import org.springframework.ui.message.ResolvableArgument; import org.springframework.ui.message.ResolvableArgument;
@ -43,12 +44,12 @@ import org.springframework.ui.message.ResolvableArgument;
public class GenericBinding implements Binding { public class GenericBinding implements Binding {
private ValueModel valueModel; private ValueModel valueModel;
private BindingContext bindingContext; private BindingContext bindingContext;
private ValueBuffer buffer; private ValueBuffer buffer;
private BindingStatus status; private BindingStatus bindingStatus;
private Object sourceValue; private Object sourceValue;
@ -58,7 +59,7 @@ public class GenericBinding implements Binding {
this.valueModel = valueModel; this.valueModel = valueModel;
this.bindingContext = bindingContext; this.bindingContext = bindingContext;
buffer = new ValueBuffer(valueModel); buffer = new ValueBuffer(valueModel);
status = BindingStatus.CLEAN; bindingStatus = BindingStatus.CLEAN;
} }
// implementing Binding // implementing Binding
@ -68,7 +69,7 @@ public class GenericBinding implements Binding {
} }
public Object getValue() { public Object getValue() {
if (status == BindingStatus.DIRTY || status == BindingStatus.COMMIT_FAILURE) { if (bindingStatus == BindingStatus.DIRTY || bindingStatus == BindingStatus.COMMIT_FAILURE) {
return buffer.getValue(); return buffer.getValue();
} else { } else {
return valueModel.getValue(); return valueModel.getValue();
@ -99,15 +100,15 @@ public class GenericBinding implements Binding {
Object parsed = bindingContext.getFormatter().parse((String) sourceValue, getLocale()); Object parsed = bindingContext.getFormatter().parse((String) sourceValue, getLocale());
buffer.setValue(coerseToValueType(parsed)); buffer.setValue(coerseToValueType(parsed));
sourceValue = null; sourceValue = null;
status = BindingStatus.DIRTY; bindingStatus = BindingStatus.DIRTY;
} catch (ParseException e) { } catch (ParseException e) {
this.sourceValue = sourceValue; this.sourceValue = sourceValue;
invalidSourceValueCause = e; invalidSourceValueCause = e;
status = BindingStatus.INVALID_SOURCE_VALUE; bindingStatus = BindingStatus.INVALID_SOURCE_VALUE;
} catch (ConversionFailedException e) { } catch (ConversionFailedException e) {
this.sourceValue = sourceValue; this.sourceValue = sourceValue;
invalidSourceValueCause = e; invalidSourceValueCause = e;
status = BindingStatus.INVALID_SOURCE_VALUE; bindingStatus = BindingStatus.INVALID_SOURCE_VALUE;
} }
} else if (sourceValue instanceof String[]) { } else if (sourceValue instanceof String[]) {
Object parsed; Object parsed;
@ -127,7 +128,7 @@ public class GenericBinding implements Binding {
} catch (ParseException e) { } catch (ParseException e) {
this.sourceValue = sourceValue; this.sourceValue = sourceValue;
invalidSourceValueCause = e; invalidSourceValueCause = e;
status = BindingStatus.INVALID_SOURCE_VALUE; bindingStatus = BindingStatus.INVALID_SOURCE_VALUE;
break; break;
} }
} }
@ -143,49 +144,53 @@ public class GenericBinding implements Binding {
} catch (ParseException e) { } catch (ParseException e) {
this.sourceValue = sourceValue; this.sourceValue = sourceValue;
invalidSourceValueCause = e; invalidSourceValueCause = e;
status = BindingStatus.INVALID_SOURCE_VALUE; bindingStatus = BindingStatus.INVALID_SOURCE_VALUE;
break; break;
} }
} }
parsed = list; parsed = list;
} }
if (status != BindingStatus.INVALID_SOURCE_VALUE) { if (bindingStatus != BindingStatus.INVALID_SOURCE_VALUE) {
try { try {
buffer.setValue(coerseToValueType(parsed)); buffer.setValue(coerseToValueType(parsed));
sourceValue = null; sourceValue = null;
status = BindingStatus.DIRTY; bindingStatus = BindingStatus.DIRTY;
} catch (ConversionFailedException e) { } catch (ConversionFailedException e) {
this.sourceValue = sourceValue; this.sourceValue = sourceValue;
invalidSourceValueCause = e; invalidSourceValueCause = e;
status = BindingStatus.INVALID_SOURCE_VALUE; bindingStatus = BindingStatus.INVALID_SOURCE_VALUE;
} }
} }
} else { } else {
try { try {
buffer.setValue(coerseToValueType(sourceValue)); buffer.setValue(coerseToValueType(sourceValue));
sourceValue = null; sourceValue = null;
status = BindingStatus.DIRTY; bindingStatus = BindingStatus.DIRTY;
} catch (ConversionFailedException e) { } catch (ConversionFailedException e) {
this.sourceValue = sourceValue; this.sourceValue = sourceValue;
invalidSourceValueCause = e; invalidSourceValueCause = e;
status = BindingStatus.INVALID_SOURCE_VALUE; bindingStatus = BindingStatus.INVALID_SOURCE_VALUE;
} }
} }
} }
public Object getInvalidSourceValue() { public Object getInvalidSourceValue() {
if (status != BindingStatus.INVALID_SOURCE_VALUE) { if (bindingStatus != BindingStatus.INVALID_SOURCE_VALUE) {
throw new IllegalStateException("No invalid source value"); throw new IllegalStateException("No invalid source value");
} }
return sourceValue; return sourceValue;
} }
public BindingStatus getStatus() { public BindingStatus getBindingStatus() {
return status; return bindingStatus;
}
public ValidationStatus getValidationStatus() {
return ValidationStatus.NOT_VALIDATED;
} }
public Alert getStatusAlert() { public Alert getStatusAlert() {
if (status == BindingStatus.INVALID_SOURCE_VALUE) { if (bindingStatus == BindingStatus.INVALID_SOURCE_VALUE) {
return new AbstractAlert() { return new AbstractAlert() {
public String getCode() { public String getCode() {
return "typeMismatch"; return "typeMismatch";
@ -217,7 +222,7 @@ public class GenericBinding implements Binding {
return Severity.ERROR; return Severity.ERROR;
} }
}; };
} else if (status == BindingStatus.COMMIT_FAILURE) { } else if (bindingStatus == BindingStatus.COMMIT_FAILURE) {
return new AbstractAlert() { return new AbstractAlert() {
public String getCode() { public String getCode() {
return "internalError"; return "internalError";
@ -232,7 +237,7 @@ public class GenericBinding implements Binding {
return Severity.FATAL; return Severity.FATAL;
} }
}; };
} else if (status == BindingStatus.COMMITTED) { } else if (bindingStatus == BindingStatus.COMMITTED) {
return new AbstractAlert() { return new AbstractAlert() {
public String getCode() { public String getCode() {
return "bindSuccess"; return "bindSuccess";
@ -251,15 +256,18 @@ public class GenericBinding implements Binding {
} }
} }
public void validate() {
}
public void commit() { public void commit() {
assertEditable(); assertEditable();
assertEnabled(); assertEnabled();
if (status == BindingStatus.DIRTY) { if (bindingStatus == BindingStatus.DIRTY) {
buffer.flush(); buffer.flush();
if (buffer.flushFailed()) { if (buffer.flushFailed()) {
status = BindingStatus.COMMIT_FAILURE; bindingStatus = BindingStatus.COMMIT_FAILURE;
} else { } else {
status = BindingStatus.COMMITTED; bindingStatus = BindingStatus.COMMITTED;
} }
} else { } else {
throw new IllegalStateException("Binding is not dirty; nothing to commit"); throw new IllegalStateException("Binding is not dirty; nothing to commit");
@ -267,13 +275,13 @@ public class GenericBinding implements Binding {
} }
public void revert() { public void revert() {
if (status == BindingStatus.INVALID_SOURCE_VALUE) { if (bindingStatus == BindingStatus.INVALID_SOURCE_VALUE) {
sourceValue = null; sourceValue = null;
invalidSourceValueCause = null; invalidSourceValueCause = null;
status = BindingStatus.CLEAN; bindingStatus = BindingStatus.CLEAN;
} else if (status == BindingStatus.DIRTY || status == BindingStatus.COMMIT_FAILURE) { } else if (bindingStatus == BindingStatus.DIRTY || bindingStatus == BindingStatus.COMMIT_FAILURE) {
buffer.clear(); buffer.clear();
status = BindingStatus.CLEAN; bindingStatus = BindingStatus.CLEAN;
} else { } else {
throw new IllegalStateException("Nothing to revert"); throw new IllegalStateException("Nothing to revert");
} }
@ -318,7 +326,7 @@ public class GenericBinding implements Binding {
} }
// internal helpers // internal helpers
private String format(Object value, Formatter formatter) { private String format(Object value, Formatter formatter) {
Class<?> formattedType = getFormattedObjectType(formatter.getClass()); Class<?> formattedType = getFormattedObjectType(formatter.getClass());
value = bindingContext.getTypeConverter().convert(value, formattedType); value = bindingContext.getTypeConverter().convert(value, formattedType);

View File

@ -156,13 +156,13 @@ public class GenericBinderTests {
assertEquals(null, b.getValue()); assertEquals(null, b.getValue());
assertEquals("", b.getRenderValue()); assertEquals("", b.getRenderValue());
b.applySourceValue("$23.56"); b.applySourceValue("$23.56");
assertEquals(BindingStatus.DIRTY, b.getStatus()); assertEquals(BindingStatus.DIRTY, b.getBindingStatus());
assertEquals(new BigDecimal("23.56"), b.getValue()); assertEquals(new BigDecimal("23.56"), b.getValue());
assertEquals("$23.56", b.getRenderValue()); assertEquals("$23.56", b.getRenderValue());
b.commit(); b.commit();
assertEquals(new BigDecimal("23.56"), b.getValue()); assertEquals(new BigDecimal("23.56"), b.getValue());
assertEquals("$23.56", b.getRenderValue()); assertEquals("$23.56", b.getRenderValue());
assertEquals(BindingStatus.COMMITTED, b.getStatus()); assertEquals(BindingStatus.COMMITTED, b.getBindingStatus());
} }
@Test @Test
@ -173,7 +173,7 @@ public class GenericBinderTests {
b.applySourceValue("2,300"); b.applySourceValue("2,300");
assertEquals("2,300", b.getRenderValue()); assertEquals("2,300", b.getRenderValue());
b.commit(); b.commit();
assertEquals(BindingStatus.COMMITTED, b.getStatus()); assertEquals(BindingStatus.COMMITTED, b.getBindingStatus());
assertEquals("2,300", b.getRenderValue()); assertEquals("2,300", b.getRenderValue());
} }
@ -228,7 +228,7 @@ public class GenericBinderTests {
assertTrue(b.isList()); assertTrue(b.isList());
assertEquals(null, b.getValue()); assertEquals(null, b.getValue());
b.applySourceValue(new String[] { "BAR", "BOGUS", "BOOP" }); b.applySourceValue(new String[] { "BAR", "BOGUS", "BOOP" });
assertEquals(BindingStatus.INVALID_SOURCE_VALUE, b.getStatus()); assertEquals(BindingStatus.INVALID_SOURCE_VALUE, b.getBindingStatus());
assertEquals("typeMismatch", b.getStatusAlert().getCode()); assertEquals("typeMismatch", b.getStatusAlert().getCode());
} }