### Eclipse Workspace Patch 1.0 #P org.eclipse.jface.examples.databinding Index: src/org/eclipse/jface/examples/databinding/snippets/Snippet035Editing.java =================================================================== RCS file: src/org/eclipse/jface/examples/databinding/snippets/Snippet035Editing.java diff -N src/org/eclipse/jface/examples/databinding/snippets/Snippet035Editing.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jface/examples/databinding/snippets/Snippet035Editing.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,243 @@ +/******************************************************************************* + * Copyright (c) 2006, 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + ******************************************************************************/ + +package org.eclipse.jface.examples.databinding.snippets; + +import java.util.Date; + +import org.eclipse.core.databinding.Binding; +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.editing.DateEditing; +import org.eclipse.core.databinding.editing.Editing; +import org.eclipse.core.databinding.editing.IntegerEditing; +import org.eclipse.core.databinding.observable.Realm; +import org.eclipse.core.databinding.observable.list.WritableList; +import org.eclipse.core.databinding.observable.value.IObservableValue; +import org.eclipse.core.databinding.observable.value.WritableValue; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.internal.databinding.provisional.fieldassist.ControlDecorationSupport; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.ListViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +import com.ibm.icu.text.DateFormat; +import com.ibm.icu.text.SimpleDateFormat; + +public class Snippet035Editing { + + public static void main(String[] args) { + Display display = new Display(); + + Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() { + public void run() { + final Shell shell = createShell(); + Display display = Display.getCurrent(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + } + }); + } + + private static Shell createShell() { + Display display = Display.getCurrent(); + Shell shell = new Shell(display); + shell.setLayout(new GridLayout(1, false)); + + createValueSection(shell); + createListSection(shell); + + shell.pack(); + shell.open(); + + return shell; + } + + private static void createValueSection(Composite parent) { + Group section = createSectionGroup(parent, "Value bindings", false); + + DataBindingContext dbc = new DataBindingContext(); + + // Edit a required, positive integer. + Text positiveText = createTextField(section, "Positive value*"); + IntegerEditing positiveEditing = EditingFactory.forInteger().required().positive(); + bindTextField(dbc, positiveText, new WritableValue(), positiveEditing); + + // Edit an integer within the range [1, 100] by using the default validation message. + Text range1Text = createTextField(section, "Value in [1, 100]"); + IntegerEditing range1Editing = EditingFactory.forInteger().range(1, 100); + bindTextField(dbc, range1Text, new WritableValue(new Integer(0), null), range1Editing); + + // Edit an integer within the range [1, 100] by customizing the validation message. + Text range2Text = createTextField(section, "Value in [1, 100]"); + IntegerEditing range2Editing = EditingFactory.forInteger().range(1, 100, "Value lies outside [{0}, {1}]."); + bindTextField(dbc, range2Text, new WritableValue(new Integer(0), null), range2Editing); + } + + private static void createListSection(Composite parent) { + Group section = createSectionGroup(parent, "List bindings", true); + + DataBindingContext dbc = new DataBindingContext(); + + // Edit a date supporting the default input/display patterns. + Text dateText = createTextField(section, "Date"); + DateEditing dateEditing = EditingFactory.forDate(); + final WritableValue dateObservable = new WritableValue(); + final Binding dateBinding = bindTextField(dbc, dateText, dateObservable, dateEditing); + + // Create a list to which the dates are added when the user hits ENTER. + new Label(section, SWT.LEFT); + ListViewer dateListViewer = new ListViewer(section); + GridDataFactory.fillDefaults().grab(true, true).hint(150, 200).applyTo(dateListViewer.getList()); + + dateListViewer.setContentProvider(new ObservableListContentProvider()); + dateListViewer.setLabelProvider(new LabelProvider()); + + // We use the same DateEditing object as for the text field above to + // create a list binding which maps the entered dates to their string + // representation which is then set as input on the ListViewer. + final WritableList targetDateList = new WritableList(); + final WritableList modelDateList = new WritableList(); + dbc.bindList( + targetDateList, + modelDateList, + dateEditing.createTargetListStrategy(), + dateEditing.createModelListStrategy()); + + // Set the list containing the string representation of the dates as input. + dateListViewer.setInput(targetDateList); + + // Add the current date in the text field when the user hits ENTER. + dateText.addSelectionListener(new SelectionAdapter() { + public void widgetDefaultSelected(SelectionEvent e) { + IStatus dateValidationStatus = (IStatus) dateBinding.getValidationStatus().getValue(); + Date date = (Date) dateObservable.getValue(); + if (dateValidationStatus.isOK() && date != null) { + modelDateList.add(date); + } + } + }); + } + + private static Binding bindTextField( + DataBindingContext dbc, + Text text, + IObservableValue modelValue, + Editing editing) { + // Create the binding using the editing object. + Binding binding = dbc.bindValue( + SWTObservables.observeText(text, SWT.Modify), + modelValue, + editing.createTargetValueStrategy(), + editing.createModelValueStrategy()); + + // Decorate the control with the validation status. + ControlDecorationSupport.create(binding, SWT.TOP); + + return binding; + } + + private static Group createSectionGroup(Composite parent, String groupText, boolean grabVertical) { + Group section = new Group(parent, SWT.DEFAULT); + section.setText(groupText); + GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).margins(5, 5).spacing(15, 5).applyTo(section); + GridDataFactory.fillDefaults().grab(true, grabVertical).applyTo(section); + return section; + } + + private static Text createTextField(Composite parent, String labelText) { + Label label = new Label(parent, SWT.LEFT); + label.setText(labelText); + GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.CENTER).applyTo(label); + + Text text = new Text(parent, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).applyTo(text); + + return text; + } + + private static final class EditingFactory { + + private static final String REQUIRED_MESSAGE = "Please specify a value."; + + private static final String INTEGER_PARSE_ERROR_MESSAGE = "The input is invalid."; + + private static final String INTEGER_OUT_OF_RANGE_MESSAGE = "The value lies outside the supported range."; + + private static final String INTEGER_RANGE_MESSAGE = "The value must lie between {0} and {1}."; + + private static final String[] DATE_INPUT_PATTERNS = new String[] { + "dd.MM.yy", + "dd/MM/yy", + "dd.MM.yyyy", + "dd/MM/yyyy" + }; + + private static final String DATE_DISPLAY_PATTERN = "dd.MM.yyyy"; + + private static final String DATE_PARSE_ERROR_MESSAGE = createDateParseErrorMessage(DATE_INPUT_PATTERNS); + + private EditingFactory() { + // prevent instantiation + } + + public static IntegerEditing forInteger() { + return IntegerEditing + .withDefaults(INTEGER_PARSE_ERROR_MESSAGE, INTEGER_OUT_OF_RANGE_MESSAGE) + .requiredMessage(REQUIRED_MESSAGE) + .rangeMessage(INTEGER_RANGE_MESSAGE); + } + + public static DateEditing forDate() { + return DateEditing + .forFormats( + createDateFormats(DATE_INPUT_PATTERNS), + DATE_PARSE_ERROR_MESSAGE, + new SimpleDateFormat(DATE_DISPLAY_PATTERN)) + .requiredMessage(REQUIRED_MESSAGE); + } + + private static DateFormat[] createDateFormats(String[] datePatterns) { + DateFormat[] dateFormats = new DateFormat[datePatterns.length]; + for (int i = 0; i < dateFormats.length; i++) { + dateFormats[i] = new SimpleDateFormat(datePatterns[i]); + } + return dateFormats; + } + + private static String createDateParseErrorMessage(String[] datePatterns) { + StringBuffer messageSb = new StringBuffer(); + messageSb.append("Supported formats: "); + for (int i = 0; i < datePatterns.length; i++) { + if (i > 0) { + messageSb.append(", "); + } + messageSb.append(datePatterns[i]); + } + return messageSb.toString(); + } + } +} #P org.eclipse.core.databinding Index: src/org/eclipse/core/internal/databinding/BindingMessages.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/BindingMessages.java,v retrieving revision 1.6 diff -u -r1.6 BindingMessages.java --- src/org/eclipse/core/internal/databinding/BindingMessages.java 9 May 2008 14:13:00 -0000 1.6 +++ src/org/eclipse/core/internal/databinding/BindingMessages.java 13 Jun 2009 12:07:00 -0000 @@ -18,7 +18,7 @@ /** * @since 1.0 - * + * */ public class BindingMessages { @@ -112,7 +112,7 @@ * Returns the resource object with the given key in the resource bundle for * JFace Data Binding. If there isn't any value under the given key, the key * is returned. - * + * * @param key * the resource name * @return the string @@ -128,16 +128,28 @@ /** * Returns a formatted string with the given key in the resource bundle for * JFace Data Binding. - * + * * @param key * @param arguments * @return formatted string, the key if the key is invalid */ public static String formatString(String key, Object[] arguments) { try { - return MessageFormat.format(bundle.getString(key), arguments); + return formatStringValue(getString(key), arguments); } catch (MissingResourceException e) { return key; } } + + /** + * Returns a formatted string with the given key in the resource bundle for + * JFace Data Binding. + * + * @param pattern + * @param arguments + * @return formatted string, the key if the key is invalid + */ + public static String formatStringValue(String pattern, Object[] arguments) { + return MessageFormat.format(pattern, arguments); + } } Index: src/org/eclipse/core/internal/databinding/conversion/StringToDateConverter.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/conversion/StringToDateConverter.java,v retrieving revision 1.2 diff -u -r1.2 StringToDateConverter.java --- src/org/eclipse/core/internal/databinding/conversion/StringToDateConverter.java 25 May 2009 20:52:19 -0000 1.2 +++ src/org/eclipse/core/internal/databinding/conversion/StringToDateConverter.java 13 Jun 2009 12:07:01 -0000 @@ -15,13 +15,31 @@ import org.eclipse.core.databinding.conversion.IConverter; +import com.ibm.icu.text.DateFormat; /** * Convert a String to a java.util.Date, respecting the current locale * * @since 1.0 */ -public class StringToDateConverter extends DateConversionSupport implements IConverter { +public class StringToDateConverter extends DateConversionSupport implements + IConverter { + + /** + * + */ + public StringToDateConverter() { + super(); + } + + /** + * + * @param formats + */ + public StringToDateConverter(DateFormat[] formats) { + super(formats); + } + public Object convert(Object source) { return parse(source.toString()); } @@ -32,5 +50,5 @@ public Object getToType() { return Date.class; - } + } } Index: src/org/eclipse/core/internal/databinding/conversion/DateConversionSupport.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/conversion/DateConversionSupport.java,v retrieving revision 1.5 diff -u -r1.5 DateConversionSupport.java --- src/org/eclipse/core/internal/databinding/conversion/DateConversionSupport.java 25 May 2009 20:52:20 -0000 1.5 +++ src/org/eclipse/core/internal/databinding/conversion/DateConversionSupport.java 13 Jun 2009 12:07:01 -0000 @@ -31,85 +31,107 @@ *
*/ public abstract class DateConversionSupport { - private final static int DATE_FORMAT=DateFormat.SHORT; - private final static int DEFAULT_FORMATTER_INDEX=0; + private final static int DATE_FORMAT = DateFormat.SHORT; + private final static int DEFAULT_FORMATTER_INDEX = 0; - private final static int NUM_VIRTUAL_FORMATTERS=1; + private final static int NUM_VIRTUAL_FORMATTERS = 1; /** - * Alternative formatters for date, time and date/time. - * Raw milliseconds are covered as a special case. + * Alternative formatters for date, time and date/time. Raw milliseconds are + * covered as a special case. */ - // TODO: These could be shared, but would have to be synchronized. - private DateFormat[] formatters = { - new SimpleDateFormat(BindingMessages.getString(BindingMessages.DATE_FORMAT_DATE_TIME)), - new SimpleDateFormat(BindingMessages.getString(BindingMessages.DATEFORMAT_TIME)), - DateFormat.getDateTimeInstance(DATE_FORMAT, DateFormat.SHORT), - DateFormat.getDateInstance(DATE_FORMAT), - DateFormat.getTimeInstance(DateFormat.SHORT), - DateFormat.getDateTimeInstance(DATE_FORMAT,DateFormat.MEDIUM), - DateFormat.getTimeInstance(DateFormat.MEDIUM) - }; + private final DateFormat[] formatters; + + /** + * + */ + public DateConversionSupport() { + // TODO: These could be shared, but would have to be synchronized. + this(new DateFormat[] { + new SimpleDateFormat(BindingMessages + .getString(BindingMessages.DATE_FORMAT_DATE_TIME)), + new SimpleDateFormat(BindingMessages + .getString(BindingMessages.DATEFORMAT_TIME)), + DateFormat.getDateTimeInstance(DATE_FORMAT, DateFormat.SHORT), + DateFormat.getDateInstance(DATE_FORMAT), + DateFormat.getTimeInstance(DateFormat.SHORT), + DateFormat.getDateTimeInstance(DATE_FORMAT, DateFormat.MEDIUM), + DateFormat.getTimeInstance(DateFormat.MEDIUM) }); + } + + /** + * + * @param formats + */ + public DateConversionSupport(DateFormat[] formats) { + this.formatters = formats; + } /** * Tries all available formatters to parse the given string according to the - * default locale or as a raw millisecond value and returns the result of the - * first successful run. - * - * @param str A string specifying a date according to the default locale or in raw milliseconds - * @return The parsed date, or null, if no available formatter could interpret the input string + * default locale or as a raw millisecond value and returns the result of + * the first successful run. + * + * @param str + * A string specifying a date according to the default locale or + * in raw milliseconds + * @return The parsed date, or null, if no available formatter could + * interpret the input string */ protected Date parse(String str) { for (int formatterIdx = 0; formatterIdx < formatters.length; formatterIdx++) { - Date parsed=parse(str,formatterIdx); - if(parsed!=null) { + Date parsed = parse(str, formatterIdx); + if (parsed != null) { return parsed; } } return null; } - protected Date parse(String str,int formatterIdx) { - if(formatterIdx>=0) { - ParsePosition pos=new ParsePosition(0); - if (str == null) { - return null; - } - Date date=formatters[formatterIdx].parse(str,pos); - if(pos.getErrorIndex()!=-1||pos.getIndex()!=str.length()) { - return null; - } - return date; + protected Date parse(String str, int formatterIdx) { + if (formatterIdx >= 0) { + ParsePosition pos = new ParsePosition(0); + if (str == null) { + return null; + } + Date date = formatters[formatterIdx].parse(str, pos); + if (pos.getErrorIndex() != -1 || pos.getIndex() != str.length()) { + return null; + } + return date; } try { - long millisecs=Long.parseLong(str); + long millisecs = Long.parseLong(str); return new Date(millisecs); - } - catch(NumberFormatException exc) { + } catch (NumberFormatException exc) { } return null; } /** - * Formats the given date with the default formatter according to the default locale. - * @param date a date - * @return a string representation of the given date according to the default locale + * Formats the given date with the default formatter according to the + * default locale. + * + * @param date + * a date + * @return a string representation of the given date according to the + * default locale */ protected String format(Date date) { - return format(date,DEFAULT_FORMATTER_INDEX); + return format(date, DEFAULT_FORMATTER_INDEX); } - protected String format(Date date,int formatterIdx) { + protected String format(Date date, int formatterIdx) { if (date == null) return null; - if(formatterIdx>=0) { + if (formatterIdx >= 0) { return formatters[formatterIdx].format(date); } return String.valueOf(date.getTime()); } protected int numFormatters() { - return formatters.length+NUM_VIRTUAL_FORMATTERS; + return formatters.length + NUM_VIRTUAL_FORMATTERS; } /** @@ -118,13 +140,14 @@ * This is for testing purposes only and should not be a part of the API if * this class was to be exposed. * - * + * * @param index * @return date format */ protected DateFormat getDateFormat(int index) { if (index < 0 || index >= formatters.length) { - throw new IllegalArgumentException("'index' [" + index + "] is out of bounds."); //$NON-NLS-1$//$NON-NLS-2$ + throw new IllegalArgumentException( + "'index' [" + index + "] is out of bounds."); //$NON-NLS-1$//$NON-NLS-2$ } return formatters[index]; Index: src/org/eclipse/core/internal/databinding/conversion/StringToNumberParser.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/conversion/StringToNumberParser.java,v retrieving revision 1.6 diff -u -r1.6 StringToNumberParser.java --- src/org/eclipse/core/internal/databinding/conversion/StringToNumberParser.java 28 Oct 2008 19:54:39 -0000 1.6 +++ src/org/eclipse/core/internal/databinding/conversion/StringToNumberParser.java 13 Jun 2009 12:07:01 -0000 @@ -21,7 +21,7 @@ /** * Utility class for the parsing of strings to numbers. - * + * * @since 1.0 */ public class StringToNumberParser { @@ -73,7 +73,7 @@ /** * The result of a parse operation. - * + * * @since 1.0 */ public static class ParseResult { @@ -84,7 +84,7 @@ * The number as a result of the conversion.null
if the
* value could not be converted or if the type is not a primitive and
* the value was an empty string.
- *
+ *
* @return number
*/
public Number getNumber() {
@@ -94,7 +94,7 @@
/**
* ParsePosition if an error occurred while parsing. null
* if no error occurred.
- *
+ *
* @return parse position
*/
public ParsePosition getPosition() {
@@ -104,7 +104,7 @@
/**
* Formats an appropriate message for a parsing error.
- *
+ *
* @param value
* @param position
* @return message
@@ -115,24 +115,43 @@
.getErrorIndex() : position.getIndex();
if (errorIndex < value.length()) {
- return BindingMessages.formatString(BindingMessages.VALIDATE_NUMBER_PARSE_ERROR,
- new Object[] { value, new Integer(errorIndex + 1),
+ return BindingMessages.formatString(
+ BindingMessages.VALIDATE_NUMBER_PARSE_ERROR, new Object[] {
+ value, new Integer(errorIndex + 1),
new Character(value.charAt(errorIndex)) });
}
- return BindingMessages.formatString(BindingMessages.VALIDATE_NUMBER_PARSE_ERROR_NO_CHARACTER,
+ return BindingMessages.formatString(
+ BindingMessages.VALIDATE_NUMBER_PARSE_ERROR_NO_CHARACTER,
new Object[] { value, new Integer(errorIndex + 1) });
}
/**
* Formats an appropriate message for an out of range error.
- *
+ *
* @param minValue
* @param maxValue
- * @param numberFormat when accessed method synchronizes on instance
+ * @param numberFormat
+ * when accessed method synchronizes on instance
* @return message
*/
public static String createOutOfRangeMessage(Number minValue,
Number maxValue, NumberFormat numberFormat) {
+ return createOutOfRangeMessage(
+ BindingMessages.getString("Validate_NumberOutOfRangeError"), minValue, maxValue, numberFormat); //$NON-NLS-1$
+ }
+
+ /**
+ * Formats an appropriate message for an out of range error.
+ *
+ * @param message
+ * @param minValue
+ * @param maxValue
+ * @param numberFormat
+ * when accessed method synchronizes on instance
+ * @return message
+ */
+ public static String createOutOfRangeMessage(String message,
+ Number minValue, Number maxValue, NumberFormat numberFormat) {
String min = null;
String max = null;
@@ -141,14 +160,14 @@
max = numberFormat.format(maxValue);
}
- return BindingMessages.formatString(
- "Validate_NumberOutOfRangeError", new Object[] { min, max }); //$NON-NLS-1$
+ return BindingMessages.formatStringValue(message, new Object[] { min,
+ max });
}
/**
- * Returns true
if the provided number
is in
- * the range of a integer.
- *
+ * Returns true
if the provided number
is in the
+ * range of a integer.
+ *
* @param number
* @return true
if a valid integer
* @throws IllegalArgumentException
@@ -160,9 +179,10 @@
/**
* Validates the range of the provided number
.
- *
+ *
* @param number
- * @param bitLength number of bits allowed to be in range
+ * @param bitLength
+ * number of bits allowed to be in range
* @return true
if in range
*/
private static boolean checkInteger(Number number, int bitLength) {
@@ -202,9 +222,9 @@
}
/**
- * Returns true
if the provided number
is in
- * the range of a long.
- *
+ * Returns true
if the provided number
is in the
+ * range of a long.
+ *
* @param number
* @return true
if in range
* @throws IllegalArgumentException
@@ -215,19 +235,21 @@
}
/**
- * Returns true
if the provided number
is in
- * the range of a float.
- *
+ * Returns true
if the provided number
is in the
+ * range of a float.
+ *
* @param number
* @return true
if in range
* @throws IllegalArgumentException
* if the number type is unsupported
*/
public static boolean inFloatRange(Number number) {
- return checkDecimal(number, FLOAT_MIN_BIG_DECIMAL, FLOAT_MAX_BIG_DECIMAL);
+ return checkDecimal(number, FLOAT_MIN_BIG_DECIMAL,
+ FLOAT_MAX_BIG_DECIMAL);
}
- private static boolean checkDecimal(Number number, BigDecimal min, BigDecimal max) {
+ private static boolean checkDecimal(Number number, BigDecimal min,
+ BigDecimal max) {
BigDecimal bigDecimal = null;
if (number instanceof Integer || number instanceof Long) {
bigDecimal = new BigDecimal(number.doubleValue());
@@ -265,22 +287,23 @@
}
/**
- * Returns true
if the provided number
is in
- * the range of a double.
- *
+ * Returns true
if the provided number
is in the
+ * range of a double.
+ *
* @param number
* @return true
if in range
* @throws IllegalArgumentException
* if the number type is unsupported
*/
public static boolean inDoubleRange(Number number) {
- return checkDecimal(number, DOUBLE_MIN_BIG_DECIMAL, DOUBLE_MAX_BIG_DECIMAL);
+ return checkDecimal(number, DOUBLE_MIN_BIG_DECIMAL,
+ DOUBLE_MAX_BIG_DECIMAL);
}
/**
- * Returns true
if the provided number
is in
- * the range of a short.
- *
+ * Returns true
if the provided number
is in the
+ * range of a short.
+ *
* @param number
* @return true
if in range
*/
@@ -289,9 +312,9 @@
}
/**
- * Returns true
if the provided number
is in
- * the range of a byte.
- *
+ * Returns true
if the provided number
is in the
+ * range of a byte.
+ *
* @param number
* @return true
if in range
*/
Index: src/org/eclipse/core/internal/databinding/conversion/DateToStringConverter.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/conversion/DateToStringConverter.java,v
retrieving revision 1.2
diff -u -r1.2 DateToStringConverter.java
--- src/org/eclipse/core/internal/databinding/conversion/DateToStringConverter.java 25 May 2009 20:52:19 -0000 1.2
+++ src/org/eclipse/core/internal/databinding/conversion/DateToStringConverter.java 13 Jun 2009 12:07:01 -0000
@@ -15,17 +15,35 @@
import org.eclipse.core.databinding.conversion.IConverter;
+import com.ibm.icu.text.DateFormat;
/**
- * Converts a Java.util.Date to a String using the current locale. Null date
+ * Converts a Java.util.Date to a String using the current locale. Null date
* values are converted to an empty string.
*
* @since 1.0
*/
-public class DateToStringConverter extends DateConversionSupport implements IConverter {
+public class DateToStringConverter extends DateConversionSupport implements
+ IConverter {
+
+ /**
+ *
+ */
+ public DateToStringConverter() {
+ super();
+ }
+
+ /**
+ *
+ * @param format
+ */
+ public DateToStringConverter(DateFormat format) {
+ super(new DateFormat[] { format });
+ }
+
public Object convert(Object source) {
if (source != null)
- return format((Date)source);
+ return format((Date) source);
return ""; //$NON-NLS-1$
}
@@ -35,5 +53,5 @@
public Object getToType() {
return String.class;
- }
+ }
}
Index: src/org/eclipse/core/internal/databinding/validation/StringToIntegerValidator.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/validation/StringToIntegerValidator.java,v
retrieving revision 1.2
diff -u -r1.2 StringToIntegerValidator.java
--- src/org/eclipse/core/internal/databinding/validation/StringToIntegerValidator.java 1 Apr 2007 20:58:13 -0000 1.2
+++ src/org/eclipse/core/internal/databinding/validation/StringToIntegerValidator.java 13 Jun 2009 12:07:01 -0000
@@ -13,7 +13,6 @@
import org.eclipse.core.internal.databinding.conversion.StringToNumberParser;
-
/**
* Validates that a string is of the appropriate format and is in the range of
* an integer.
@@ -31,8 +30,21 @@
super(converter, MIN, MAX);
}
- /* (non-Javadoc)
- * @see org.eclipse.core.internal.databinding.validation.AbstractStringToNumberValidator#inRange(java.lang.Number)
+ /**
+ * @param converter
+ * @param parseErrorMessage
+ * @param outOfRangeMessage
+ */
+ public StringToIntegerValidator(NumberFormatConverter converter,
+ String parseErrorMessage, String outOfRangeMessage) {
+ super(converter, MIN, MAX, parseErrorMessage, outOfRangeMessage);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.core.internal.databinding.validation.
+ * AbstractStringToNumberValidator#inRange(java.lang.Number)
*/
protected boolean isInRange(Number number) {
return StringToNumberParser.inIntegerRange(number);
Index: src/org/eclipse/core/internal/databinding/validation/StringToDateValidator.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/validation/StringToDateValidator.java,v
retrieving revision 1.5
diff -u -r1.5 StringToDateValidator.java
--- src/org/eclipse/core/internal/databinding/validation/StringToDateValidator.java 9 May 2008 14:13:00 -0000 1.5
+++ src/org/eclipse/core/internal/databinding/validation/StringToDateValidator.java 13 Jun 2009 12:07:01 -0000
@@ -28,24 +28,38 @@
public class StringToDateValidator implements IValidator {
private final StringToDateConverter converter;
+ private final String parseErrorMessage;
+
/**
* @param converter
*/
public StringToDateValidator(StringToDateConverter converter) {
+ this(converter, null);
+ }
+
+ /**
+ * @param converter
+ * @param parseErrorMessage
+ */
+ public StringToDateValidator(StringToDateConverter converter,
+ String parseErrorMessage) {
this.converter = converter;
+ this.parseErrorMessage = parseErrorMessage;
}
/*
* (non-Javadoc)
- *
- * @see org.eclipse.core.databinding.validation.IValidator#validate(java.lang.Object)
+ *
+ * @see
+ * org.eclipse.core.databinding.validation.IValidator#validate(java.lang
+ * .Object)
*/
public IStatus validate(Object value) {
- if (value instanceof String && ((String)value).trim().length()==0) {
+ if (value instanceof String && ((String) value).trim().length() == 0) {
return Status.OK_STATUS;
}
Object convertedValue = converter.convert(value);
- //The StringToDateConverter returns null if it can't parse the date.
+ // The StringToDateConverter returns null if it can't parse the date.
if (convertedValue == null) {
return ValidationStatus.error(getErrorMessage());
}
@@ -55,10 +69,16 @@
/*
* (non-Javadoc)
- *
- * @see org.eclipse.core.internal.databinding.validation.WrappedConverterValidator#getErrorMessage()
+ *
+ * @see
+ * org.eclipse.core.internal.databinding.validation.WrappedConverterValidator
+ * #getErrorMessage()
*/
protected String getErrorMessage() {
+ if (parseErrorMessage != null) {
+ return parseErrorMessage;
+ }
+
Date sampleDate = new Date();
// FIXME We need to use the information from the
@@ -73,14 +93,17 @@
samples.append('\'');
samples.append(util.format(sampleDate, 0));
samples.append('\'');
- return BindingMessages.getString(BindingMessages.EXAMPLES) + ": " + samples + ",..."; //$NON-NLS-1$//$NON-NLS-2$
+ return BindingMessages.getString(BindingMessages.EXAMPLES)
+ + ": " + samples + ",..."; //$NON-NLS-1$//$NON-NLS-2$
}
private static class FormatUtil extends DateConversionSupport {
/*
* (non-Javadoc)
- *
- * @see org.eclipse.core.internal.databinding.conversion.DateConversionSupport#numFormatters()
+ *
+ * @see
+ * org.eclipse.core.internal.databinding.conversion.DateConversionSupport
+ * #numFormatters()
*/
protected int numFormatters() {
return super.numFormatters();
@@ -88,8 +111,10 @@
/*
* (non-Javadoc)
- *
- * @see org.eclipse.core.internal.databinding.conversion.DateConversionSupport#format(java.util.Date)
+ *
+ * @see
+ * org.eclipse.core.internal.databinding.conversion.DateConversionSupport
+ * #format(java.util.Date)
*/
protected String format(Date date) {
return super.format(date);
@@ -97,9 +122,10 @@
/*
* (non-Javadoc)
- *
- * @see org.eclipse.core.internal.databinding.conversion.DateConversionSupport#format(java.util.Date,
- * int)
+ *
+ * @see
+ * org.eclipse.core.internal.databinding.conversion.DateConversionSupport
+ * #format(java.util.Date, int)
*/
protected String format(Date date, int formatterIdx) {
return super.format(date, formatterIdx);
Index: src/org/eclipse/core/internal/databinding/validation/AbstractStringToNumberValidator.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/validation/AbstractStringToNumberValidator.java,v
retrieving revision 1.2
diff -u -r1.2 AbstractStringToNumberValidator.java
--- src/org/eclipse/core/internal/databinding/validation/AbstractStringToNumberValidator.java 4 Jul 2007 20:08:45 -0000 1.2
+++ src/org/eclipse/core/internal/databinding/validation/AbstractStringToNumberValidator.java 13 Jun 2009 12:07:01 -0000
@@ -11,6 +11,8 @@
package org.eclipse.core.internal.databinding.validation;
+import java.text.ParsePosition;
+
import org.eclipse.core.databinding.validation.IValidator;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.internal.databinding.conversion.StringToNumberParser;
@@ -19,8 +21,8 @@
import org.eclipse.core.runtime.Status;
/**
- * Validates a number that is to be converted by a {@link NumberFormatConverter}.
- * Validation is comprised of parsing the String and range checks.
+ * Validates a number that is to be converted by a {@link NumberFormatConverter}
+ * . Validation is comprised of parsing the String and range checks.
*
* @since 1.0
*/
@@ -31,20 +33,46 @@
private final Number min;
private final Number max;
- private String outOfRangeMessage;
+ private final String parseErrorMessage;
+ private final String outOfRangeMessage;
+
+ private String formattedOutOfRangeMessage;
/**
* Constructs a new instance.
*
- * @param converter converter and thus formatter to be used in validation
- * @param min minimum value, used for reporting a range error to the user
- * @param max maximum value, used for reporting a range error to the user
+ * @param converter
+ * converter and thus formatter to be used in validation
+ * @param min
+ * minimum value, used for reporting a range error to the user
+ * @param max
+ * maximum value, used for reporting a range error to the user
*/
protected AbstractStringToNumberValidator(NumberFormatConverter converter,
Number min, Number max) {
+ this(converter, min, max, null, null);
+ }
+
+ /**
+ * Constructs a new instance.
+ *
+ * @param converter
+ * converter and thus formatter to be used in validation
+ * @param min
+ * minimum value, used for reporting a range error to the user
+ * @param max
+ * maximum value, used for reporting a range error to the user
+ * @param parseErrorMessage
+ * @param outOfRangeMessage
+ */
+ protected AbstractStringToNumberValidator(NumberFormatConverter converter,
+ Number min, Number max, String parseErrorMessage,
+ String outOfRangeMessage) {
this.converter = converter;
this.min = min;
this.max = max;
+ this.parseErrorMessage = parseErrorMessage;
+ this.outOfRangeMessage = outOfRangeMessage;
if (converter.getToType() instanceof Class) {
Class clazz = (Class) converter.getToType();
@@ -55,7 +83,8 @@
}
/**
- * Validates the provided value
. An error status is returned if:
+ * Validates the provided value
. An error status is returned
+ * if:
* true
if in range
*/
protected abstract boolean isInRange(Number number);
+
+ private String createParseErrorMessage(String input,
+ ParsePosition parsePosition) {
+ if (parseErrorMessage == null) {
+ return StringToNumberParser.createParseErrorMessage(input,
+ parsePosition);
+ }
+ return parseErrorMessage;
+ }
+
+ private String createOutOfRangeMessage() {
+ if (outOfRangeMessage == null) {
+ return StringToNumberParser.createOutOfRangeMessage(min, max,
+ converter.getNumberFormat());
+ }
+ return StringToNumberParser.createOutOfRangeMessage(outOfRangeMessage,
+ min, max, converter.getNumberFormat());
+ }
}
Index: META-INF/MANIFEST.MF
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/META-INF/MANIFEST.MF,v
retrieving revision 1.20
diff -u -r1.20 MANIFEST.MF
--- META-INF/MANIFEST.MF 9 Mar 2009 04:40:48 -0000 1.20
+++ META-INF/MANIFEST.MF 13 Jun 2009 12:07:00 -0000
@@ -8,6 +8,7 @@
Bundle-Localization: plugin
Export-Package: org.eclipse.core.databinding,
org.eclipse.core.databinding.conversion;x-internal:=false,
+ org.eclipse.core.databinding.editing,
org.eclipse.core.databinding.validation;x-internal:=false,
org.eclipse.core.internal.databinding;x-friends:="org.eclipse.core.databinding.beans",
org.eclipse.core.internal.databinding.conversion;x-friends:="org.eclipse.jface.tests.databinding",
Index: src/org/eclipse/core/internal/databinding/validation/NonNullValidator.java
===================================================================
RCS file: src/org/eclipse/core/internal/databinding/validation/NonNullValidator.java
diff -N src/org/eclipse/core/internal/databinding/validation/NonNullValidator.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/core/internal/databinding/validation/NonNullValidator.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.core.internal.databinding.validation;
+
+import org.eclipse.core.databinding.validation.IValidator;
+import org.eclipse.core.databinding.validation.ValidationStatus;
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * @since 1.3
+ */
+public class NonNullValidator implements IValidator {
+
+ private final String validationMessage;
+
+ /**
+ *
+ */
+ public NonNullValidator() {
+ this(null);
+ }
+
+ /**
+ * @param validationMessage
+ */
+ public NonNullValidator(String validationMessage) {
+ // TODO: Externalize
+ this.validationMessage = validationMessage != null ? validationMessage
+ : "The value must not be empty."; //$NON-NLS-1$
+ }
+
+ public IStatus validate(Object value) {
+ if (value == null) {
+ return ValidationStatus.error(validationMessage);
+ }
+ return ValidationStatus.ok();
+ }
+}
Index: src/org/eclipse/core/internal/databinding/validation/ValidatorChain.java
===================================================================
RCS file: src/org/eclipse/core/internal/databinding/validation/ValidatorChain.java
diff -N src/org/eclipse/core/internal/databinding/validation/ValidatorChain.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/core/internal/databinding/validation/ValidatorChain.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.core.internal.databinding.validation;
+
+import org.eclipse.core.databinding.validation.IValidator;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * @since 1.3
+ */
+public class ValidatorChain implements IValidator {
+
+ private final IValidator[] validators;
+
+ /**
+ * @param validators
+ */
+ public ValidatorChain(IValidator[] validators) {
+ this.validators = validators;
+ }
+
+ public IStatus validate(Object value) {
+ // TODO: Define an aggregation strategy.
+ int maxSeverity = IStatus.OK;
+ IStatus maxStatus = Status.OK_STATUS;
+ for (int i = 0; i < validators.length; i++) {
+ IValidator validator = validators[i];
+ IStatus status = validator.validate(value);
+ if (status.getSeverity() > maxSeverity) {
+ maxSeverity = status.getSeverity();
+ maxStatus = status;
+ }
+ }
+ return maxStatus;
+ }
+}
Index: src/org/eclipse/core/internal/databinding/conversion/NumberRangeValidator.java
===================================================================
RCS file: src/org/eclipse/core/internal/databinding/conversion/NumberRangeValidator.java
diff -N src/org/eclipse/core/internal/databinding/conversion/NumberRangeValidator.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/core/internal/databinding/conversion/NumberRangeValidator.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.core.internal.databinding.conversion;
+
+import java.text.MessageFormat;
+
+import org.eclipse.core.databinding.validation.IValidator;
+import org.eclipse.core.databinding.validation.ValidationStatus;
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * @since 1.3
+ */
+public class NumberRangeValidator implements IValidator {
+
+ private final Number min;
+ private final Number max;
+ private final String validationMessage;
+
+ /**
+ *
+ * @param min
+ * @param max
+ */
+ public NumberRangeValidator(Number min, Number max) {
+ this(min, max, null);
+ }
+
+ /**
+ *
+ * @param min
+ * @param max
+ * @param validationMessage
+ */
+ public NumberRangeValidator(Number min, Number max, String validationMessage) {
+ this.min = min;
+ this.max = max;
+ // TODO: Externalize
+ this.validationMessage = validationMessage != null ? validationMessage
+ : "The value must lie in the range [{0}, {1}]"; //$NON-NLS-1$
+ }
+
+ public IStatus validate(Object value) {
+ if (value != null) {
+ Comparable comparableValue = (Comparable) value;
+ if (comparableValue.compareTo(min) < 0
+ || comparableValue.compareTo(max) > 0) {
+ // TODO: Cache message?
+ return ValidationStatus.error(MessageFormat.format(
+ validationMessage, new Number[] { min, max }));
+ }
+ }
+ return ValidationStatus.ok();
+ }
+}
Index: src/org/eclipse/core/databinding/editing/IntegerEditing.java
===================================================================
RCS file: src/org/eclipse/core/databinding/editing/IntegerEditing.java
diff -N src/org/eclipse/core/databinding/editing/IntegerEditing.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/core/databinding/editing/IntegerEditing.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,272 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.core.databinding.editing;
+
+import org.eclipse.core.databinding.conversion.NumberToStringConverter;
+import org.eclipse.core.databinding.conversion.StringToNumberConverter;
+import org.eclipse.core.databinding.validation.IValidator;
+import org.eclipse.core.internal.databinding.conversion.NumberRangeValidator;
+import org.eclipse.core.internal.databinding.validation.NonNullValidator;
+import org.eclipse.core.internal.databinding.validation.StringToIntegerValidator;
+
+import com.ibm.icu.text.NumberFormat;
+
+/**
+ * @since 1.3
+ */
+public final class IntegerEditing extends Editing {
+
+ private static final Integer ONE = new Integer(1);
+ private static final Integer MAX_INTEGER = new Integer(Integer.MAX_VALUE);
+
+ private String requiredMessage = null;
+
+ private String rangeMessage = null;
+
+ // TODO: Externalize
+ private String positiveMessage = "The value must be positive."; //$NON-NLS-1$
+
+ private IntegerEditing(NumberFormat format, String parseErrorMessage,
+ String outOfRangeMessage) {
+ StringToNumberConverter targetConverter = StringToNumberConverter
+ .toInteger(format, false);
+
+ doAddTargetValidator(new StringToIntegerValidator(targetConverter,
+ parseErrorMessage, outOfRangeMessage));
+ doSetTargetConverter(targetConverter);
+ doSetModelConverter(NumberToStringConverter.fromInteger(format, false));
+ }
+
+ /**
+ * Creates a new editing object which defaults the validations and
+ * conversions used for editing based on the platform's locale. Uses the
+ * default validation messages.
+ *
+ * @return The new editing object using the default validations and
+ * conversions for editing.
+ *
+ * @see NumberFormat#getIntegerInstance()
+ */
+ public static IntegerEditing withDefaults() {
+ return withDefaults(null, null);
+ }
+
+ /**
+ * Creates a new editing object which defaults the validations and
+ * conversions used for editing based on the platform's locale. Uses the
+ * specified custom validation messages.
+ *
+ * @param parseErrorMessage
+ * The validation message issued in case the input string cannot
+ * be parsed to an integer.
+ * @param outOfRangeMessage
+ * The validation message issued in case the input string
+ * represents an integer whose value is out of range. Can be
+ * parameterized by the Integer.MIN_VALUE
and
+ * Integer.MAX_VALUE
values.
+ * @return The new editing object using the default validations and
+ * conversions for editing.
+ */
+ public static IntegerEditing withDefaults(String parseErrorMessage,
+ String outOfRangeMessage) {
+ return new IntegerEditing(NumberFormat.getIntegerInstance(),
+ parseErrorMessage, outOfRangeMessage);
+ }
+
+ /**
+ * Creates a new editing object whose validations and conversions used for
+ * editing are based on the given integer format. Uses the default
+ * validation messages.
+ *
+ * @param format
+ * The integer format defining the validations and conversions
+ * used for editing.
+ * @return The new editing object configured by the given integer format.
+ */
+ public static IntegerEditing forFormat(NumberFormat format) {
+ return forFormat(format, null, null);
+ }
+
+ /**
+ * Creates a new editing object whose validations and conversions used for
+ * editing are based on the given integer format. Uses the specified custom
+ * validation messages.
+ *
+ * @param format
+ * The integer format defining the validations and conversions
+ * used for editing.
+ * @param parseErrorMessage
+ * The validation message issued in case the input string cannot
+ * be parsed to an integer.
+ * @param outOfRangeMessage
+ * The validation message issued in case the input string
+ * represents an integer whose value is out of range. Can be
+ * parameterized by the Integer.MIN_VALUE
and
+ * Integer.MAX_VALUE
values.
+ * @return The new editing object configured by the given integer format.
+ */
+ public static IntegerEditing forFormat(NumberFormat format,
+ String parseErrorMessage, String outOfRangeMessage) {
+ return new IntegerEditing(format, parseErrorMessage, outOfRangeMessage);
+ }
+
+ /**
+ * Adds a model validator ensuring that the parsed integer is not
+ * null
. Uses the default validation message.
+ *
+ * @return This editing instance for method chaining.
+ */
+ public IntegerEditing required() {
+ return required(requiredMessage);
+ }
+
+ /**
+ * Adds a model validator ensuring that the parsed integer is not
+ * null
. Uses the specified custom validation message.
+ *
+ * @param message
+ * The validation message issued in case the parsed integer is
+ * null
.
+ * @return This editing instance for method chaining.
+ */
+ public IntegerEditing required(String message) {
+ return addModelValidator(new NonNullValidator(message));
+ }
+
+ /**
+ * Sets the default validation message to be issued in case the parsed
+ * integer is null
.
+ *
+ * @param message
+ * The default validation message to be issued in case the parsed
+ * integer is null
.
+ * @return This editing instance for method chaining.
+ *
+ * @see #required()
+ */
+ public IntegerEditing requiredMessage(String message) {
+ this.requiredMessage = message;
+ return this;
+ }
+
+ /**
+ * Adds a model validator ensuring that the parsed integer is positive. Uses
+ * the default validation message.
+ *
+ * @return This editing instance for method chaining.
+ */
+ public IntegerEditing positive() {
+ return positive(positiveMessage);
+ }
+
+ /**
+ * Adds a model validator ensuring that the parsed integer is positive. Uses
+ * the specified custom validation message.
+ *
+ * @param message
+ * The validation message issued in case the parsed integer is
+ * not positive.
+ * @return This editing instance for method chaining.
+ */
+ public IntegerEditing positive(String message) {
+ return addModelValidator(new NumberRangeValidator(ONE, MAX_INTEGER,
+ message));
+ }
+
+ /**
+ * Sets the default validation message to be issued in case the parsed
+ * integer is not positive.
+ *
+ * @param message
+ * The default validation message to be issued in case the parsed
+ * integer is not positive.
+ * @return This editing instance for method chaining.
+ *
+ * @see #positive()
+ */
+ public IntegerEditing positiveMessage(String message) {
+ this.positiveMessage = message;
+ return this;
+ }
+
+ /**
+ * Adds a model validator ensuring that the parsed integer is within the
+ * given range. Uses the default validation message.
+ *
+ * @param min
+ * The lower bound of the range (inclusive).
+ * @param max
+ * The upper bound of the range (inclusive).
+ * @return This editing instance for method chaining.
+ */
+ public IntegerEditing range(int min, int max) {
+ return range(min, max, rangeMessage);
+ }
+
+ /**
+ * Adds a model validator ensuring that the parsed integer is within the
+ * given range. Uses the specified custom validation message.
+ *
+ * @param min
+ * The lower bound of the range (inclusive).
+ * @param max
+ * The upper bound of the range (inclusive).
+ * @param message
+ * The validation message issued in case the parsed integer is
+ * not within the given range.
+ * @return This editing instance for method chaining.
+ */
+ public IntegerEditing range(int min, int max, String message) {
+ return addModelValidator(new NumberRangeValidator(new Integer(min),
+ new Integer(max), message));
+ }
+
+ /**
+ * Sets the default validation message to be issued in case the parsed
+ * integer is not within a given range.
+ *
+ * @param message
+ * The default validation message to be issued in case the parsed
+ * integer is not within a given range.
+ * @return This editing instance for method chaining.
+ *
+ * @see #range(int, int)
+ */
+ public IntegerEditing rangeMessage(String message) {
+ this.rangeMessage = message;
+ return this;
+ }
+
+ /**
+ * Adds a custom target validator.
+ *
+ * @param validator
+ * The custom target validator to add.
+ * @return This editing instance for method chaining.
+ */
+ public IntegerEditing addTargetValidator(IValidator validator) {
+ doAddTargetValidator(validator);
+ return this;
+ }
+
+ /**
+ * Adds a custom model validator.
+ *
+ * @param validator
+ * The custom model validator to add.
+ * @return This editing instance for method chaining.
+ */
+ public IntegerEditing addModelValidator(IValidator validator) {
+ doAddModelValidator(validator);
+ return this;
+ }
+}
Index: src/org/eclipse/core/databinding/editing/Editing.java
===================================================================
RCS file: src/org/eclipse/core/databinding/editing/Editing.java
diff -N src/org/eclipse/core/databinding/editing/Editing.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/core/databinding/editing/Editing.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,245 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.core.databinding.editing;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.databinding.UpdateListStrategy;
+import org.eclipse.core.databinding.UpdateValueStrategy;
+import org.eclipse.core.databinding.conversion.IConverter;
+import org.eclipse.core.databinding.validation.IValidator;
+import org.eclipse.core.internal.databinding.validation.ValidatorChain;
+
+/**
+ * @since 1.3
+ */
+public abstract class Editing {
+
+ private final List targetValidators = new ArrayList();
+
+ private IConverter targetConverter;
+
+ private final List modelValidators = new ArrayList();
+
+ private IConverter modelConverter;
+
+ protected final void doAddTargetValidator(IValidator targetValidator) {
+ targetValidators.add(targetValidator);
+ }
+
+ protected final void doSetTargetConverter(IConverter targetConverter) {
+ this.targetConverter = targetConverter;
+ }
+
+ protected final void doAddModelValidator(IValidator modelValidator) {
+ modelValidators.add(modelValidator);
+ }
+
+ protected final void doSetModelConverter(IConverter modelConverter) {
+ this.modelConverter = modelConverter;
+ }
+
+ /**
+ * Creates a new target-to-model {@link UpdateValueStrategy} with a default
+ * update policy configured by the current state of this editing object.
+ *
+ * @return A new target-to-model {@link UpdateValueStrategy} configured by
+ * the current state of this editing object.
+ *
+ * @see UpdateValueStrategy#UpdateValueStrategy()
+ */
+ public UpdateValueStrategy createTargetValueStrategy() {
+ return applyToTargetValueStrategy(new UpdateValueStrategy());
+ }
+
+ /**
+ * Creates a new target-to-model {@link UpdateValueStrategy} with the given
+ * update policy configured by the current state of this editing object.
+ *
+ * @param updatePolicy
+ * The update policy to use.
+ * @return A new target-to-model {@link UpdateValueStrategy} configured by
+ * the current state of this editing object.
+ *
+ * @see UpdateValueStrategy#UpdateValueStrategy(int)
+ */
+ public UpdateValueStrategy createTargetValueStrategy(int updatePolicy) {
+ return applyToTargetValueStrategy(new UpdateValueStrategy(updatePolicy));
+ }
+
+ /**
+ * Creates a new model-to-target {@link UpdateValueStrategy} with a default
+ * update policy configured by the current state of this editing object.
+ *
+ * @return A new model-to-target {@link UpdateValueStrategy} configured by
+ * the current state of this editing object.
+ *
+ * @see UpdateValueStrategy#UpdateValueStrategy()
+ */
+ public UpdateValueStrategy createModelValueStrategy() {
+ return applyToModelValueStrategy(new UpdateValueStrategy());
+ }
+
+ /**
+ * Creates a new model-to-target {@link UpdateValueStrategy} with the given
+ * update policy configured by the current state of this editing object.
+ *
+ * @param updatePolicy
+ * The update policy to use.
+ * @return A new model-to-target {@link UpdateValueStrategy} configured by
+ * the current state of this editing object.
+ *
+ * @see UpdateValueStrategy#UpdateValueStrategy(int)
+ */
+ public UpdateValueStrategy createModelValueStrategy(int updatePolicy) {
+ return applyToModelValueStrategy(new UpdateValueStrategy(updatePolicy));
+ }
+
+ /**
+ * Creates a new target-to-model {@link UpdateListStrategy} with a default
+ * update policy configured by the current state of this editing object.
+ *
+ * @return A new target-to-model {@link UpdateListStrategy} configured by
+ * the current state of this editing object.
+ *
+ * @see UpdateListStrategy#UpdateListStrategy()
+ */
+ public UpdateListStrategy createTargetListStrategy() {
+ return applyToTargetListStrategy(new UpdateListStrategy());
+ }
+
+ /**
+ * Creates a new target-to-model {@link UpdateListStrategy} with the given
+ * update policy configured by the current state of this editing object.
+ *
+ * @param updatePolicy
+ * The update policy to use.
+ * @return A new target-to-model {@link UpdateListStrategy} configured by
+ * the current state of this editing object.
+ *
+ * @see UpdateListStrategy#UpdateListStrategy(int)
+ */
+ public UpdateListStrategy createTargetListStrategy(int updatePolicy) {
+ return applyToTargetListStrategy(new UpdateListStrategy(updatePolicy));
+ }
+
+ /**
+ * Creates a new model-to-target {@link UpdateListStrategy} with a default
+ * update policy configured by the current state of this editing object.
+ *
+ * @return A new model-to-target {@link UpdateListStrategy} configured by
+ * the current state of this editing object.
+ *
+ * @see UpdateListStrategy#UpdateListStrategy()
+ */
+ public UpdateListStrategy createModelListStrategy() {
+ return applyToModelListStrategy(new UpdateListStrategy());
+ }
+
+ /**
+ * Creates a new model-to-target {@link UpdateListStrategy} with the given
+ * update policy configured by the current state of this editing object.
+ *
+ * @param updatePolicy
+ * The update policy to use.
+ * @return A new model-to-target {@link UpdateListStrategy} configured by
+ * the current state of this editing object.
+ *
+ * @see UpdateListStrategy#UpdateListStrategy(int)
+ */
+ public UpdateListStrategy createModelListStrategy(int updatePolicy) {
+ return applyToModelListStrategy(new UpdateListStrategy(updatePolicy));
+ }
+
+ /**
+ * Configures an existing target-to-model {@link UpdateValueStrategy} with
+ * the current state of this editing object.
+ *
+ * @param updateStrategy
+ * The {@link UpdateValueStrategy} to configure.
+ * @return The passed-in, configured target-to-model
+ * {@link UpdateValueStrategy}.
+ */
+ public UpdateValueStrategy applyToTargetValueStrategy(
+ UpdateValueStrategy updateStrategy) {
+ updateStrategy.setAfterGetValidator(createTargetValidator());
+ updateStrategy.setConverter(targetConverter);
+ updateStrategy.setAfterConvertValidator(createModelValidator());
+ return updateStrategy;
+ }
+
+ /**
+ * Configures an existing model-to-target {@link UpdateValueStrategy} with
+ * the current state of this editing object.
+ *
+ * @param updateStrategy
+ * The {@link UpdateValueStrategy} to configure.
+ * @return The passed-in, configured model-to-target
+ * {@link UpdateValueStrategy}.
+ */
+ public UpdateValueStrategy applyToModelValueStrategy(
+ UpdateValueStrategy updateStrategy) {
+ updateStrategy.setConverter(modelConverter);
+ return updateStrategy;
+ }
+
+ /**
+ * Configures an existing target-to-model {@link UpdateListStrategy} with
+ * the current state of this editing object.
+ *
+ * @param updateStrategy
+ * The {@link UpdateListStrategy} to configure.
+ * @return The passed-in, configured target-to-model
+ * {@link UpdateListStrategy}.
+ */
+ public UpdateListStrategy applyToTargetListStrategy(
+ UpdateListStrategy updateStrategy) {
+ updateStrategy.setConverter(targetConverter);
+ return updateStrategy;
+ }
+
+ /**
+ * Configures an existing model-to-target {@link UpdateListStrategy} with
+ * the current state of this editing object.
+ *
+ * @param updateStrategy
+ * The {@link UpdateListStrategy} to configure.
+ * @return The passed-in, configured model-to-target
+ * {@link UpdateListStrategy}.
+ */
+ public UpdateListStrategy applyToModelListStrategy(
+ UpdateListStrategy updateStrategy) {
+ updateStrategy.setConverter(modelConverter);
+ return updateStrategy;
+ }
+
+ private IValidator createTargetValidator() {
+ if (!targetValidators.isEmpty()) {
+ ValidatorChain targetValidator = new ValidatorChain(
+ (IValidator[]) targetValidators
+ .toArray(new IValidator[targetValidators.size()]));
+ return targetValidator;
+ }
+ return null;
+ }
+
+ private IValidator createModelValidator() {
+ if (!modelValidators.isEmpty()) {
+ ValidatorChain modelValidator = new ValidatorChain(
+ (IValidator[]) modelValidators
+ .toArray(new IValidator[modelValidators.size()]));
+ return modelValidator;
+ }
+ return null;
+ }
+}
Index: src/org/eclipse/core/databinding/editing/DateEditing.java
===================================================================
RCS file: src/org/eclipse/core/databinding/editing/DateEditing.java
diff -N src/org/eclipse/core/databinding/editing/DateEditing.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/core/databinding/editing/DateEditing.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.core.databinding.editing;
+
+import org.eclipse.core.databinding.validation.IValidator;
+import org.eclipse.core.internal.databinding.conversion.DateToStringConverter;
+import org.eclipse.core.internal.databinding.conversion.StringToDateConverter;
+import org.eclipse.core.internal.databinding.validation.NonNullValidator;
+import org.eclipse.core.internal.databinding.validation.StringToDateValidator;
+
+import com.ibm.icu.text.DateFormat;
+
+/**
+ * @since 1.3
+ */
+public final class DateEditing extends Editing {
+
+ private String requiredMessage = null;
+
+ private DateEditing(DateFormat[] inputFormats, String parseErrorMessage,
+ DateFormat displayFormat) {
+ StringToDateConverter targetConverter;
+ if (inputFormats == null) {
+ targetConverter = new StringToDateConverter();
+ } else {
+ targetConverter = new StringToDateConverter(inputFormats);
+ }
+
+ doAddTargetValidator(new StringToDateValidator(targetConverter,
+ parseErrorMessage));
+ doSetTargetConverter(targetConverter);
+ doSetModelConverter(displayFormat == null ? new DateToStringConverter()
+ : new DateToStringConverter(displayFormat));
+ }
+
+ /**
+ * Creates a new editing object which defaults the validations and
+ * conversions used for editing. Uses the default validation message.
+ *
+ * @return The new editing object using the default validations and
+ * conversions for editing.
+ */
+ public static DateEditing withDefaults() {
+ return withDefaults(null);
+ }
+
+ /**
+ * Creates a new editing object which defaults the validations and
+ * conversions used for editing. Uses the specified custom validation
+ * message.
+ *
+ * @param parseErrorMessage
+ * The validation message issued in case the input string cannot
+ * be parsed to a date.
+ * @return The new editing object using the default validations and
+ * conversions for editing.
+ */
+ public static DateEditing withDefaults(String parseErrorMessage) {
+ return new DateEditing(null, parseErrorMessage, null);
+ }
+
+ /**
+ * Creates a new editing object which supports all the given date formats
+ * for input and which uses the first specified format for displaying a
+ * date. Uses the default validation message.
+ *
+ * @param formats
+ * The date formats supported for reading in and displaying
+ * dates.
+ * @return The new editing object configured by the given date formats.
+ */
+ public static DateEditing forFormats(DateFormat[] formats) {
+ return new DateEditing(formats, null, formats[0]);
+ }
+
+ /**
+ * Creates a new editing object which supports all the given date formats
+ * for input and which uses the first specified format for displaying a
+ * date. Uses the specified custom validation message.
+ *
+ * @param formats
+ * The date formats supported for reading in and displaying
+ * dates.
+ * @param parseErrorMessage
+ * The validation message issued in case the input string cannot
+ * be parsed to a date.
+ * @return The new editing object configured by the given date formats.
+ */
+ public static DateEditing forFormats(DateFormat[] formats,
+ String parseErrorMessage) {
+ return new DateEditing(formats, parseErrorMessage, formats[0]);
+ }
+
+ /**
+ * Creates a new editing object which supports all the given date input
+ * formats and which uses the specified format for displaying a date. Uses
+ * the default validation message.
+ *
+ * @param inputFormats
+ * The date formats supported for reading in dates.
+ * @param displayFormat
+ * The date format for displaying dates.
+ * @return The new editing object configured by the given date formats.
+ */
+ public static DateEditing forFormats(DateFormat[] inputFormats,
+ DateFormat displayFormat) {
+ return new DateEditing(inputFormats, null, displayFormat);
+ }
+
+ /**
+ * Creates a new editing object which supports all the given date input
+ * formats and which uses the specified format for displaying a date. Uses
+ * the specified custom validation message.
+ *
+ * @param inputFormats
+ * The date formats supported for reading in dates.
+ * @param parseErrorMessage
+ * The validation message issued in case the input string cannot
+ * be parsed to a date.
+ * @param displayFormat
+ * The date format for displaying dates.
+ * @return The new editing object configured by the given date formats.
+ */
+ public static DateEditing forFormats(DateFormat[] inputFormats,
+ String parseErrorMessage, DateFormat displayFormat) {
+ return new DateEditing(inputFormats, parseErrorMessage, displayFormat);
+ }
+
+ /**
+ * Adds a model validator ensuring that the parsed date is not
+ * null
. Uses the default validation message.
+ *
+ * @return This editing instance for method chaining.
+ */
+ public DateEditing required() {
+ return required(requiredMessage);
+ }
+
+ /**
+ * Adds a model validator ensuring that the parsed date is not
+ * null
. Uses the specified custom validation message.
+ *
+ * @param message
+ * The validation message issued in case the parsed date is
+ * null
.
+ * @return This editing instance for method chaining.
+ */
+ public DateEditing required(String message) {
+ return addModelValidator(new NonNullValidator(message));
+ }
+
+ /**
+ * Sets the default validation message to be issued in case the parsed date
+ * is null
.
+ *
+ * @param message
+ * The default validation message to be issued in case the parsed
+ * date is null
.
+ * @return This editing instance for method chaining.
+ *
+ * @see #required()
+ */
+ public DateEditing requiredMessage(String message) {
+ this.requiredMessage = message;
+ return this;
+ }
+
+ /**
+ * Adds a custom target validator.
+ *
+ * @param validator
+ * The custom target validator to add.
+ * @return This editing instance for method chaining.
+ */
+ public DateEditing addTargetValidator(IValidator validator) {
+ doAddTargetValidator(validator);
+ return this;
+ }
+
+ /**
+ * Adds a custom model validator.
+ *
+ * @param validator
+ * The custom model validator to add.
+ * @return This editing instance for method chaining.
+ */
+ public DateEditing addModelValidator(IValidator validator) {
+ doAddModelValidator(validator);
+ return this;
+ }
+}