View | Details | Raw Unified | Return to bug 183055 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jface/examples/databinding/snippets/Snippet035Editing.java (+243 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.examples.databinding.snippets;
13
14
import java.util.Date;
15
16
import org.eclipse.core.databinding.Binding;
17
import org.eclipse.core.databinding.DataBindingContext;
18
import org.eclipse.core.databinding.editing.DateEditing;
19
import org.eclipse.core.databinding.editing.Editing;
20
import org.eclipse.core.databinding.editing.IntegerEditing;
21
import org.eclipse.core.databinding.observable.Realm;
22
import org.eclipse.core.databinding.observable.list.WritableList;
23
import org.eclipse.core.databinding.observable.value.IObservableValue;
24
import org.eclipse.core.databinding.observable.value.WritableValue;
25
import org.eclipse.core.runtime.IStatus;
26
import org.eclipse.jface.databinding.swt.SWTObservables;
27
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
28
import org.eclipse.jface.internal.databinding.provisional.fieldassist.ControlDecorationSupport;
29
import org.eclipse.jface.layout.GridDataFactory;
30
import org.eclipse.jface.layout.GridLayoutFactory;
31
import org.eclipse.jface.viewers.LabelProvider;
32
import org.eclipse.jface.viewers.ListViewer;
33
import org.eclipse.swt.SWT;
34
import org.eclipse.swt.events.SelectionAdapter;
35
import org.eclipse.swt.events.SelectionEvent;
36
import org.eclipse.swt.layout.GridLayout;
37
import org.eclipse.swt.widgets.Composite;
38
import org.eclipse.swt.widgets.Display;
39
import org.eclipse.swt.widgets.Group;
40
import org.eclipse.swt.widgets.Label;
41
import org.eclipse.swt.widgets.Shell;
42
import org.eclipse.swt.widgets.Text;
43
44
import com.ibm.icu.text.DateFormat;
45
import com.ibm.icu.text.SimpleDateFormat;
46
47
public class Snippet035Editing {
48
49
	public static void main(String[] args) {
50
		Display display = new Display();
51
52
		Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
53
			public void run() {
54
				final Shell shell = createShell();
55
				Display display = Display.getCurrent();
56
				while (!shell.isDisposed()) {
57
					if (!display.readAndDispatch()) {
58
						display.sleep();
59
					}
60
				}
61
			}
62
		});
63
	}
64
65
	private static Shell createShell() {
66
		Display display = Display.getCurrent();
67
		Shell shell = new Shell(display);
68
		shell.setLayout(new GridLayout(1, false));
69
70
		createValueSection(shell);
71
		createListSection(shell);
72
73
		shell.pack();
74
		shell.open();
75
76
		return shell;
77
	}
78
79
	private static void createValueSection(Composite parent) {
80
		Group section = createSectionGroup(parent, "Value bindings", false);
81
82
		DataBindingContext dbc = new DataBindingContext();
83
84
		// Edit a required, positive integer.
85
		Text positiveText = createTextField(section, "Positive value*");
86
		IntegerEditing positiveEditing = EditingFactory.forInteger().required().positive();
87
		bindTextField(dbc, positiveText, new WritableValue(), positiveEditing);
88
89
		// Edit an integer within the range [1, 100] by using the default validation message.
90
		Text range1Text = createTextField(section, "Value in [1, 100]");
91
		IntegerEditing range1Editing = EditingFactory.forInteger().range(1, 100);
92
		bindTextField(dbc, range1Text, new WritableValue(new Integer(0), null), range1Editing);
93
94
		// Edit an integer within the range [1, 100] by customizing the validation message.
95
		Text range2Text = createTextField(section, "Value in [1, 100]");
96
		IntegerEditing range2Editing = EditingFactory.forInteger().range(1, 100, "Value lies outside [{0}, {1}].");
97
		bindTextField(dbc, range2Text, new WritableValue(new Integer(0), null), range2Editing);
98
	}
99
100
	private static void createListSection(Composite parent) {
101
		Group section = createSectionGroup(parent, "List bindings", true);
102
103
		DataBindingContext dbc = new DataBindingContext();
104
105
		// Edit a date supporting the default input/display patterns.
106
		Text dateText = createTextField(section, "Date");
107
		DateEditing dateEditing = EditingFactory.forDate();
108
		final WritableValue dateObservable = new WritableValue();
109
		final Binding dateBinding = bindTextField(dbc, dateText, dateObservable, dateEditing);
110
111
		// Create a list to which the dates are added when the user hits ENTER.
112
		new Label(section, SWT.LEFT);
113
		ListViewer dateListViewer = new ListViewer(section);
114
		GridDataFactory.fillDefaults().grab(true, true).hint(150, 200).applyTo(dateListViewer.getList());
115
116
		dateListViewer.setContentProvider(new ObservableListContentProvider());
117
		dateListViewer.setLabelProvider(new LabelProvider());
118
119
		// We use the same DateEditing object as for the text field above to
120
		// create a list binding which maps the entered dates to their string
121
		// representation which is then set as input on the ListViewer.
122
		final WritableList targetDateList = new WritableList();
123
		final WritableList modelDateList = new WritableList();
124
		dbc.bindList(
125
				targetDateList,
126
				modelDateList,
127
				dateEditing.createTargetListStrategy(),
128
				dateEditing.createModelListStrategy());
129
130
		// Set the list containing the string representation of the dates as input.
131
		dateListViewer.setInput(targetDateList);
132
133
		// Add the current date in the text field when the user hits ENTER.
134
		dateText.addSelectionListener(new SelectionAdapter() {
135
			public void widgetDefaultSelected(SelectionEvent e) {
136
				IStatus dateValidationStatus = (IStatus) dateBinding.getValidationStatus().getValue();
137
				Date date = (Date) dateObservable.getValue();
138
				if (dateValidationStatus.isOK() && date != null) {
139
					modelDateList.add(date);
140
				}
141
			}
142
		});
143
	}
144
145
	private static Binding bindTextField(
146
			DataBindingContext dbc,
147
			Text text,
148
			IObservableValue modelValue,
149
			Editing editing) {
150
		// Create the binding using the editing object.
151
		Binding binding = dbc.bindValue(
152
				SWTObservables.observeText(text, SWT.Modify),
153
				modelValue,
154
				editing.createTargetValueStrategy(),
155
				editing.createModelValueStrategy());
156
157
		// Decorate the control with the validation status.
158
		ControlDecorationSupport.create(binding, SWT.TOP);
159
160
		return binding;
161
	}
162
163
	private static Group createSectionGroup(Composite parent, String groupText, boolean grabVertical) {
164
		Group section = new Group(parent, SWT.DEFAULT);
165
		section.setText(groupText);
166
		GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).margins(5, 5).spacing(15, 5).applyTo(section);
167
		GridDataFactory.fillDefaults().grab(true, grabVertical).applyTo(section);
168
		return section;
169
	}
170
171
	private static Text createTextField(Composite parent, String labelText) {
172
		Label label = new Label(parent, SWT.LEFT);
173
		label.setText(labelText);
174
		GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.CENTER).applyTo(label);
175
176
		Text text = new Text(parent, SWT.BORDER);
177
		GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).applyTo(text);
178
179
		return text;
180
	}
181
182
	private static final class EditingFactory {
183
184
		private static final String REQUIRED_MESSAGE = "Please specify a value.";
185
186
		private static final String INTEGER_PARSE_ERROR_MESSAGE = "The input is invalid.";
187
188
		private static final String INTEGER_OUT_OF_RANGE_MESSAGE = "The value lies outside the supported range.";
189
190
		private static final String INTEGER_RANGE_MESSAGE = "The value must lie between {0} and {1}.";
191
192
		private static final String[] DATE_INPUT_PATTERNS = new String[] {
193
			"dd.MM.yy",
194
			"dd/MM/yy",
195
			"dd.MM.yyyy",
196
			"dd/MM/yyyy"
197
		};
198
199
		private static final String DATE_DISPLAY_PATTERN = "dd.MM.yyyy";
200
201
		private static final String DATE_PARSE_ERROR_MESSAGE = createDateParseErrorMessage(DATE_INPUT_PATTERNS);
202
203
		private EditingFactory() {
204
			// prevent instantiation
205
		}
206
207
		public static IntegerEditing forInteger() {
208
			return IntegerEditing
209
					.withDefaults(INTEGER_PARSE_ERROR_MESSAGE, INTEGER_OUT_OF_RANGE_MESSAGE)
210
					.requiredMessage(REQUIRED_MESSAGE)
211
					.rangeMessage(INTEGER_RANGE_MESSAGE);
212
		}
213
214
		public static DateEditing forDate() {
215
			return DateEditing
216
					.forFormats(
217
							createDateFormats(DATE_INPUT_PATTERNS),
218
							DATE_PARSE_ERROR_MESSAGE,
219
							new SimpleDateFormat(DATE_DISPLAY_PATTERN))
220
					.requiredMessage(REQUIRED_MESSAGE);
221
		}
222
223
		private static DateFormat[] createDateFormats(String[] datePatterns) {
224
			DateFormat[] dateFormats = new DateFormat[datePatterns.length];
225
			for (int i = 0; i < dateFormats.length; i++) {
226
				dateFormats[i] = new SimpleDateFormat(datePatterns[i]);
227
			}
228
			return dateFormats;
229
		}
230
231
		private static String createDateParseErrorMessage(String[] datePatterns) {
232
			StringBuffer messageSb = new StringBuffer();
233
			messageSb.append("Supported formats: ");
234
			for (int i = 0; i < datePatterns.length; i++) {
235
				if (i > 0) {
236
					messageSb.append(", ");
237
				}
238
				messageSb.append(datePatterns[i]);
239
			}
240
			return messageSb.toString();
241
		}
242
	}
243
}
(-)src/org/eclipse/core/internal/databinding/BindingMessages.java (-4 / +16 lines)
Lines 18-24 Link Here
18
18
19
/**
19
/**
20
 * @since 1.0
20
 * @since 1.0
21
 *
21
 * 
22
 */
22
 */
23
public class BindingMessages {
23
public class BindingMessages {
24
24
Lines 112-118 Link Here
112
	 * Returns the resource object with the given key in the resource bundle for
112
	 * Returns the resource object with the given key in the resource bundle for
113
	 * JFace Data Binding. If there isn't any value under the given key, the key
113
	 * JFace Data Binding. If there isn't any value under the given key, the key
114
	 * is returned.
114
	 * is returned.
115
	 *
115
	 * 
116
	 * @param key
116
	 * @param key
117
	 *            the resource name
117
	 *            the resource name
118
	 * @return the string
118
	 * @return the string
Lines 128-143 Link Here
128
	/**
128
	/**
129
	 * Returns a formatted string with the given key in the resource bundle for
129
	 * Returns a formatted string with the given key in the resource bundle for
130
	 * JFace Data Binding.
130
	 * JFace Data Binding.
131
	 *
131
	 * 
132
	 * @param key
132
	 * @param key
133
	 * @param arguments
133
	 * @param arguments
134
	 * @return formatted string, the key if the key is invalid
134
	 * @return formatted string, the key if the key is invalid
135
	 */
135
	 */
136
	public static String formatString(String key, Object[] arguments) {
136
	public static String formatString(String key, Object[] arguments) {
137
		try {
137
		try {
138
			return MessageFormat.format(bundle.getString(key), arguments);
138
			return formatStringValue(getString(key), arguments);
139
		} catch (MissingResourceException e) {
139
		} catch (MissingResourceException e) {
140
			return key;
140
			return key;
141
		}
141
		}
142
	}
142
	}
143
144
	/**
145
	 * Returns a formatted string with the given key in the resource bundle for
146
	 * JFace Data Binding.
147
	 * 
148
	 * @param pattern
149
	 * @param arguments
150
	 * @return formatted string, the key if the key is invalid
151
	 */
152
	public static String formatStringValue(String pattern, Object[] arguments) {
153
		return MessageFormat.format(pattern, arguments);
154
	}
143
}
155
}
(-)src/org/eclipse/core/internal/databinding/conversion/StringToDateConverter.java (-2 / +20 lines)
Lines 15-27 Link Here
15
15
16
import org.eclipse.core.databinding.conversion.IConverter;
16
import org.eclipse.core.databinding.conversion.IConverter;
17
17
18
import com.ibm.icu.text.DateFormat;
18
19
19
/**
20
/**
20
 * Convert a String to a java.util.Date, respecting the current locale
21
 * Convert a String to a java.util.Date, respecting the current locale
21
 * 
22
 * 
22
 * @since 1.0
23
 * @since 1.0
23
 */
24
 */
24
public class StringToDateConverter extends DateConversionSupport implements IConverter {
25
public class StringToDateConverter extends DateConversionSupport implements
26
		IConverter {
27
28
	/**
29
	 * 
30
	 */
31
	public StringToDateConverter() {
32
		super();
33
	}
34
35
	/**
36
	 * 
37
	 * @param formats
38
	 */
39
	public StringToDateConverter(DateFormat[] formats) {
40
		super(formats);
41
	}
42
25
	public Object convert(Object source) {
43
	public Object convert(Object source) {
26
		return parse(source.toString());
44
		return parse(source.toString());
27
	}
45
	}
Lines 32-36 Link Here
32
50
33
	public Object getToType() {
51
	public Object getToType() {
34
		return Date.class;
52
		return Date.class;
35
	}	
53
	}
36
}
54
}
(-)src/org/eclipse/core/internal/databinding/conversion/DateConversionSupport.java (-45 / +68 lines)
Lines 31-115 Link Here
31
 * </p>
31
 * </p>
32
 */
32
 */
33
public abstract class DateConversionSupport {
33
public abstract class DateConversionSupport {
34
	private final static int DATE_FORMAT=DateFormat.SHORT;
34
	private final static int DATE_FORMAT = DateFormat.SHORT;
35
	private final static int DEFAULT_FORMATTER_INDEX=0;
35
	private final static int DEFAULT_FORMATTER_INDEX = 0;
36
36
37
	private final static int NUM_VIRTUAL_FORMATTERS=1;
37
	private final static int NUM_VIRTUAL_FORMATTERS = 1;
38
38
39
	/**
39
	/**
40
	 * Alternative formatters for date, time and date/time.
40
	 * Alternative formatters for date, time and date/time. Raw milliseconds are
41
	 * Raw milliseconds are covered as a special case.
41
	 * covered as a special case.
42
	 */
42
	 */
43
	// TODO: These could be shared, but would have to be synchronized.
43
	private final DateFormat[] formatters;
44
	private DateFormat[] formatters = {
44
45
			new SimpleDateFormat(BindingMessages.getString(BindingMessages.DATE_FORMAT_DATE_TIME)),
45
	/**
46
			new SimpleDateFormat(BindingMessages.getString(BindingMessages.DATEFORMAT_TIME)),
46
	 * 
47
			DateFormat.getDateTimeInstance(DATE_FORMAT, DateFormat.SHORT),
47
	 */
48
			DateFormat.getDateInstance(DATE_FORMAT),
48
	public DateConversionSupport() {
49
			DateFormat.getTimeInstance(DateFormat.SHORT),
49
		// TODO: These could be shared, but would have to be synchronized.
50
            DateFormat.getDateTimeInstance(DATE_FORMAT,DateFormat.MEDIUM),
50
		this(new DateFormat[] {
51
            DateFormat.getTimeInstance(DateFormat.MEDIUM)
51
				new SimpleDateFormat(BindingMessages
52
	};
52
						.getString(BindingMessages.DATE_FORMAT_DATE_TIME)),
53
				new SimpleDateFormat(BindingMessages
54
						.getString(BindingMessages.DATEFORMAT_TIME)),
55
				DateFormat.getDateTimeInstance(DATE_FORMAT, DateFormat.SHORT),
56
				DateFormat.getDateInstance(DATE_FORMAT),
57
				DateFormat.getTimeInstance(DateFormat.SHORT),
58
				DateFormat.getDateTimeInstance(DATE_FORMAT, DateFormat.MEDIUM),
59
				DateFormat.getTimeInstance(DateFormat.MEDIUM) });
60
	}
61
62
	/**
63
	 * 
64
	 * @param formats
65
	 */
66
	public DateConversionSupport(DateFormat[] formats) {
67
		this.formatters = formats;
68
	}
53
69
54
	/**
70
	/**
55
	 * Tries all available formatters to parse the given string according to the
71
	 * Tries all available formatters to parse the given string according to the
56
	 * default locale or as a raw millisecond value and returns the result of the
72
	 * default locale or as a raw millisecond value and returns the result of
57
	 * first successful run.
73
	 * the first successful run.
58
	 *
74
	 * 
59
	 * @param str A string specifying a date according to the default locale or in raw milliseconds
75
	 * @param str
60
	 * @return The parsed date, or null, if no available formatter could interpret the input string
76
	 *            A string specifying a date according to the default locale or
77
	 *            in raw milliseconds
78
	 * @return The parsed date, or null, if no available formatter could
79
	 *         interpret the input string
61
	 */
80
	 */
62
	protected Date parse(String str) {
81
	protected Date parse(String str) {
63
		for (int formatterIdx = 0; formatterIdx < formatters.length; formatterIdx++) {
82
		for (int formatterIdx = 0; formatterIdx < formatters.length; formatterIdx++) {
64
			Date parsed=parse(str,formatterIdx);
83
			Date parsed = parse(str, formatterIdx);
65
			if(parsed!=null) {
84
			if (parsed != null) {
66
				return parsed;
85
				return parsed;
67
			}
86
			}
68
		}
87
		}
69
		return null;
88
		return null;
70
	}
89
	}
71
90
72
	protected Date parse(String str,int formatterIdx) {
91
	protected Date parse(String str, int formatterIdx) {
73
		if(formatterIdx>=0) {
92
		if (formatterIdx >= 0) {
74
				ParsePosition pos=new ParsePosition(0);
93
			ParsePosition pos = new ParsePosition(0);
75
				if (str == null) {
94
			if (str == null) {
76
					return null;
95
				return null;
77
				}
96
			}
78
				Date date=formatters[formatterIdx].parse(str,pos);
97
			Date date = formatters[formatterIdx].parse(str, pos);
79
				if(pos.getErrorIndex()!=-1||pos.getIndex()!=str.length()) {
98
			if (pos.getErrorIndex() != -1 || pos.getIndex() != str.length()) {
80
					return null;
99
				return null;
81
				}
100
			}
82
				return date;
101
			return date;
83
		}
102
		}
84
		try {
103
		try {
85
			long millisecs=Long.parseLong(str);
104
			long millisecs = Long.parseLong(str);
86
			return new Date(millisecs);
105
			return new Date(millisecs);
87
		}
106
		} catch (NumberFormatException exc) {
88
		catch(NumberFormatException exc) {
89
		}
107
		}
90
		return null;
108
		return null;
91
	}
109
	}
92
110
93
	/**
111
	/**
94
	 * Formats the given date with the default formatter according to the default locale.
112
	 * Formats the given date with the default formatter according to the
95
	 * @param date a date
113
	 * default locale.
96
	 * @return a string representation of the given date according to the default locale
114
	 * 
115
	 * @param date
116
	 *            a date
117
	 * @return a string representation of the given date according to the
118
	 *         default locale
97
	 */
119
	 */
98
	protected String format(Date date) {
120
	protected String format(Date date) {
99
		return format(date,DEFAULT_FORMATTER_INDEX);
121
		return format(date, DEFAULT_FORMATTER_INDEX);
100
	}
122
	}
101
123
102
	protected String format(Date date,int formatterIdx) {
124
	protected String format(Date date, int formatterIdx) {
103
		if (date == null)
125
		if (date == null)
104
			return null;
126
			return null;
105
		if(formatterIdx>=0) {
127
		if (formatterIdx >= 0) {
106
			return formatters[formatterIdx].format(date);
128
			return formatters[formatterIdx].format(date);
107
		}
129
		}
108
		return String.valueOf(date.getTime());
130
		return String.valueOf(date.getTime());
109
	}
131
	}
110
132
111
	protected int numFormatters() {
133
	protected int numFormatters() {
112
		return formatters.length+NUM_VIRTUAL_FORMATTERS;
134
		return formatters.length + NUM_VIRTUAL_FORMATTERS;
113
	}
135
	}
114
136
115
	/**
137
	/**
Lines 118-130 Link Here
118
	 * This is for testing purposes only and should not be a part of the API if
140
	 * This is for testing purposes only and should not be a part of the API if
119
	 * this class was to be exposed.
141
	 * this class was to be exposed.
120
	 * </p>
142
	 * </p>
121
	 *
143
	 * 
122
	 * @param index
144
	 * @param index
123
	 * @return date format
145
	 * @return date format
124
	 */
146
	 */
125
	protected DateFormat getDateFormat(int index) {
147
	protected DateFormat getDateFormat(int index) {
126
		if (index < 0 || index >= formatters.length) {
148
		if (index < 0 || index >= formatters.length) {
127
			throw new IllegalArgumentException("'index' [" + index + "] is out of bounds.");  //$NON-NLS-1$//$NON-NLS-2$
149
			throw new IllegalArgumentException(
150
					"'index' [" + index + "] is out of bounds."); //$NON-NLS-1$//$NON-NLS-2$
128
		}
151
		}
129
152
130
		return formatters[index];
153
		return formatters[index];
(-)src/org/eclipse/core/internal/databinding/conversion/StringToNumberParser.java (-35 / +58 lines)
Lines 21-27 Link Here
21
21
22
/**
22
/**
23
 * Utility class for the parsing of strings to numbers.
23
 * Utility class for the parsing of strings to numbers.
24
 *
24
 * 
25
 * @since 1.0
25
 * @since 1.0
26
 */
26
 */
27
public class StringToNumberParser {
27
public class StringToNumberParser {
Lines 73-79 Link Here
73
73
74
	/**
74
	/**
75
	 * The result of a parse operation.
75
	 * The result of a parse operation.
76
	 *
76
	 * 
77
	 * @since 1.0
77
	 * @since 1.0
78
	 */
78
	 */
79
	public static class ParseResult {
79
	public static class ParseResult {
Lines 84-90 Link Here
84
		 * The number as a result of the conversion. <code>null</code> if the
84
		 * The number as a result of the conversion. <code>null</code> if the
85
		 * value could not be converted or if the type is not a primitive and
85
		 * value could not be converted or if the type is not a primitive and
86
		 * the value was an empty string.
86
		 * the value was an empty string.
87
		 *
87
		 * 
88
		 * @return number
88
		 * @return number
89
		 */
89
		 */
90
		public Number getNumber() {
90
		public Number getNumber() {
Lines 94-100 Link Here
94
		/**
94
		/**
95
		 * ParsePosition if an error occurred while parsing. <code>null</code>
95
		 * ParsePosition if an error occurred while parsing. <code>null</code>
96
		 * if no error occurred.
96
		 * if no error occurred.
97
		 *
97
		 * 
98
		 * @return parse position
98
		 * @return parse position
99
		 */
99
		 */
100
		public ParsePosition getPosition() {
100
		public ParsePosition getPosition() {
Lines 104-110 Link Here
104
104
105
	/**
105
	/**
106
	 * Formats an appropriate message for a parsing error.
106
	 * Formats an appropriate message for a parsing error.
107
	 *
107
	 * 
108
	 * @param value
108
	 * @param value
109
	 * @param position
109
	 * @param position
110
	 * @return message
110
	 * @return message
Lines 115-138 Link Here
115
				.getErrorIndex() : position.getIndex();
115
				.getErrorIndex() : position.getIndex();
116
116
117
		if (errorIndex < value.length()) {
117
		if (errorIndex < value.length()) {
118
			return BindingMessages.formatString(BindingMessages.VALIDATE_NUMBER_PARSE_ERROR,
118
			return BindingMessages.formatString(
119
					new Object[] { value, new Integer(errorIndex + 1),
119
					BindingMessages.VALIDATE_NUMBER_PARSE_ERROR, new Object[] {
120
							value, new Integer(errorIndex + 1),
120
							new Character(value.charAt(errorIndex)) });
121
							new Character(value.charAt(errorIndex)) });
121
		}
122
		}
122
		return BindingMessages.formatString(BindingMessages.VALIDATE_NUMBER_PARSE_ERROR_NO_CHARACTER,
123
		return BindingMessages.formatString(
124
				BindingMessages.VALIDATE_NUMBER_PARSE_ERROR_NO_CHARACTER,
123
				new Object[] { value, new Integer(errorIndex + 1) });
125
				new Object[] { value, new Integer(errorIndex + 1) });
124
	}
126
	}
125
127
126
	/**
128
	/**
127
	 * Formats an appropriate message for an out of range error.
129
	 * Formats an appropriate message for an out of range error.
128
	 *
130
	 * 
129
	 * @param minValue
131
	 * @param minValue
130
	 * @param maxValue
132
	 * @param maxValue
131
	 * @param numberFormat when accessed method synchronizes on instance
133
	 * @param numberFormat
134
	 *            when accessed method synchronizes on instance
132
	 * @return message
135
	 * @return message
133
	 */
136
	 */
134
	public static String createOutOfRangeMessage(Number minValue,
137
	public static String createOutOfRangeMessage(Number minValue,
135
			Number maxValue, NumberFormat numberFormat) {
138
			Number maxValue, NumberFormat numberFormat) {
139
		return createOutOfRangeMessage(
140
				BindingMessages.getString("Validate_NumberOutOfRangeError"), minValue, maxValue, numberFormat); //$NON-NLS-1$
141
	}
142
143
	/**
144
	 * Formats an appropriate message for an out of range error.
145
	 * 
146
	 * @param message
147
	 * @param minValue
148
	 * @param maxValue
149
	 * @param numberFormat
150
	 *            when accessed method synchronizes on instance
151
	 * @return message
152
	 */
153
	public static String createOutOfRangeMessage(String message,
154
			Number minValue, Number maxValue, NumberFormat numberFormat) {
136
		String min = null;
155
		String min = null;
137
		String max = null;
156
		String max = null;
138
157
Lines 141-154 Link Here
141
			max = numberFormat.format(maxValue);
160
			max = numberFormat.format(maxValue);
142
		}
161
		}
143
162
144
		return BindingMessages.formatString(
163
		return BindingMessages.formatStringValue(message, new Object[] { min,
145
				"Validate_NumberOutOfRangeError", new Object[] { min, max }); //$NON-NLS-1$
164
				max });
146
	}
165
	}
147
166
148
	/**
167
	/**
149
	 * Returns <code>true</code> if the provided <code>number</code> is in
168
	 * Returns <code>true</code> if the provided <code>number</code> is in the
150
	 * the range of a integer.
169
	 * range of a integer.
151
	 *
170
	 * 
152
	 * @param number
171
	 * @param number
153
	 * @return <code>true</code> if a valid integer
172
	 * @return <code>true</code> if a valid integer
154
	 * @throws IllegalArgumentException
173
	 * @throws IllegalArgumentException
Lines 160-168 Link Here
160
179
161
	/**
180
	/**
162
	 * Validates the range of the provided <code>number</code>.
181
	 * Validates the range of the provided <code>number</code>.
163
	 *
182
	 * 
164
	 * @param number
183
	 * @param number
165
	 * @param bitLength number of bits allowed to be in range
184
	 * @param bitLength
185
	 *            number of bits allowed to be in range
166
	 * @return <code>true</code> if in range
186
	 * @return <code>true</code> if in range
167
	 */
187
	 */
168
	private static boolean checkInteger(Number number, int bitLength) {
188
	private static boolean checkInteger(Number number, int bitLength) {
Lines 202-210 Link Here
202
	}
222
	}
203
223
204
	/**
224
	/**
205
	 * Returns <code>true</code> if the provided <code>number</code> is in
225
	 * Returns <code>true</code> if the provided <code>number</code> is in the
206
	 * the range of a long.
226
	 * range of a long.
207
	 *
227
	 * 
208
	 * @param number
228
	 * @param number
209
	 * @return <code>true</code> if in range
229
	 * @return <code>true</code> if in range
210
	 * @throws IllegalArgumentException
230
	 * @throws IllegalArgumentException
Lines 215-233 Link Here
215
	}
235
	}
216
236
217
	/**
237
	/**
218
	 * Returns <code>true</code> if the provided <code>number</code> is in
238
	 * Returns <code>true</code> if the provided <code>number</code> is in the
219
	 * the range of a float.
239
	 * range of a float.
220
	 *
240
	 * 
221
	 * @param number
241
	 * @param number
222
	 * @return <code>true</code> if in range
242
	 * @return <code>true</code> if in range
223
	 * @throws IllegalArgumentException
243
	 * @throws IllegalArgumentException
224
	 *             if the number type is unsupported
244
	 *             if the number type is unsupported
225
	 */
245
	 */
226
	public static boolean inFloatRange(Number number) {
246
	public static boolean inFloatRange(Number number) {
227
		return checkDecimal(number, FLOAT_MIN_BIG_DECIMAL, FLOAT_MAX_BIG_DECIMAL);
247
		return checkDecimal(number, FLOAT_MIN_BIG_DECIMAL,
248
				FLOAT_MAX_BIG_DECIMAL);
228
	}
249
	}
229
250
230
	private static boolean checkDecimal(Number number, BigDecimal min, BigDecimal max) {
251
	private static boolean checkDecimal(Number number, BigDecimal min,
252
			BigDecimal max) {
231
		BigDecimal bigDecimal = null;
253
		BigDecimal bigDecimal = null;
232
		if (number instanceof Integer || number instanceof Long) {
254
		if (number instanceof Integer || number instanceof Long) {
233
			bigDecimal = new BigDecimal(number.doubleValue());
255
			bigDecimal = new BigDecimal(number.doubleValue());
Lines 265-286 Link Here
265
	}
287
	}
266
288
267
	/**
289
	/**
268
	 * Returns <code>true</code> if the provided <code>number</code> is in
290
	 * Returns <code>true</code> if the provided <code>number</code> is in the
269
	 * the range of a double.
291
	 * range of a double.
270
	 *
292
	 * 
271
	 * @param number
293
	 * @param number
272
	 * @return <code>true</code> if in range
294
	 * @return <code>true</code> if in range
273
	 * @throws IllegalArgumentException
295
	 * @throws IllegalArgumentException
274
	 *             if the number type is unsupported
296
	 *             if the number type is unsupported
275
	 */
297
	 */
276
	public static boolean inDoubleRange(Number number) {
298
	public static boolean inDoubleRange(Number number) {
277
		return checkDecimal(number, DOUBLE_MIN_BIG_DECIMAL, DOUBLE_MAX_BIG_DECIMAL);
299
		return checkDecimal(number, DOUBLE_MIN_BIG_DECIMAL,
300
				DOUBLE_MAX_BIG_DECIMAL);
278
	}
301
	}
279
302
280
	/**
303
	/**
281
	 * Returns <code>true</code> if the provided <code>number</code> is in
304
	 * Returns <code>true</code> if the provided <code>number</code> is in the
282
	 * the range of a short.
305
	 * range of a short.
283
	 *
306
	 * 
284
	 * @param number
307
	 * @param number
285
	 * @return <code>true</code> if in range
308
	 * @return <code>true</code> if in range
286
	 */
309
	 */
Lines 289-297 Link Here
289
	}
312
	}
290
313
291
	/**
314
	/**
292
	 * Returns <code>true</code> if the provided <code>number</code> is in
315
	 * Returns <code>true</code> if the provided <code>number</code> is in the
293
	 * the range of a byte.
316
	 * range of a byte.
294
	 *
317
	 * 
295
	 * @param number
318
	 * @param number
296
	 * @return <code>true</code> if in range
319
	 * @return <code>true</code> if in range
297
	 */
320
	 */
(-)src/org/eclipse/core/internal/databinding/conversion/DateToStringConverter.java (-4 / +22 lines)
Lines 15-31 Link Here
15
15
16
import org.eclipse.core.databinding.conversion.IConverter;
16
import org.eclipse.core.databinding.conversion.IConverter;
17
17
18
import com.ibm.icu.text.DateFormat;
18
19
19
/**
20
/**
20
 * Converts a Java.util.Date to a String using the current locale.  Null date
21
 * Converts a Java.util.Date to a String using the current locale. Null date
21
 * values are converted to an empty string.
22
 * values are converted to an empty string.
22
 * 
23
 * 
23
 * @since 1.0
24
 * @since 1.0
24
 */
25
 */
25
public class DateToStringConverter extends DateConversionSupport implements IConverter {	
26
public class DateToStringConverter extends DateConversionSupport implements
27
		IConverter {
28
29
	/**
30
	 * 
31
	 */
32
	public DateToStringConverter() {
33
		super();
34
	}
35
36
	/**
37
	 * 
38
	 * @param format
39
	 */
40
	public DateToStringConverter(DateFormat format) {
41
		super(new DateFormat[] { format });
42
	}
43
26
	public Object convert(Object source) {
44
	public Object convert(Object source) {
27
		if (source != null)
45
		if (source != null)
28
			return format((Date)source);
46
			return format((Date) source);
29
		return ""; //$NON-NLS-1$
47
		return ""; //$NON-NLS-1$
30
	}
48
	}
31
49
Lines 35-39 Link Here
35
53
36
	public Object getToType() {
54
	public Object getToType() {
37
		return String.class;
55
		return String.class;
38
	}	
56
	}
39
}
57
}
(-)src/org/eclipse/core/internal/databinding/validation/StringToIntegerValidator.java (-3 / +15 lines)
Lines 13-19 Link Here
13
13
14
import org.eclipse.core.internal.databinding.conversion.StringToNumberParser;
14
import org.eclipse.core.internal.databinding.conversion.StringToNumberParser;
15
15
16
17
/**
16
/**
18
 * Validates that a string is of the appropriate format and is in the range of
17
 * Validates that a string is of the appropriate format and is in the range of
19
 * an integer.
18
 * an integer.
Lines 31-38 Link Here
31
		super(converter, MIN, MAX);
30
		super(converter, MIN, MAX);
32
	}
31
	}
33
32
34
	/* (non-Javadoc)
33
	/**
35
	 * @see org.eclipse.core.internal.databinding.validation.AbstractStringToNumberValidator#inRange(java.lang.Number)
34
	 * @param converter
35
	 * @param parseErrorMessage
36
	 * @param outOfRangeMessage
37
	 */
38
	public StringToIntegerValidator(NumberFormatConverter converter,
39
			String parseErrorMessage, String outOfRangeMessage) {
40
		super(converter, MIN, MAX, parseErrorMessage, outOfRangeMessage);
41
	}
42
43
	/*
44
	 * (non-Javadoc)
45
	 * 
46
	 * @seeorg.eclipse.core.internal.databinding.validation.
47
	 * AbstractStringToNumberValidator#inRange(java.lang.Number)
36
	 */
48
	 */
37
	protected boolean isInRange(Number number) {
49
	protected boolean isInRange(Number number) {
38
		return StringToNumberParser.inIntegerRange(number);
50
		return StringToNumberParser.inIntegerRange(number);
(-)src/org/eclipse/core/internal/databinding/validation/StringToDateValidator.java (-14 / +40 lines)
Lines 28-51 Link Here
28
public class StringToDateValidator implements IValidator {
28
public class StringToDateValidator implements IValidator {
29
	private final StringToDateConverter converter;
29
	private final StringToDateConverter converter;
30
30
31
	private final String parseErrorMessage;
32
31
	/**
33
	/**
32
	 * @param converter
34
	 * @param converter
33
	 */
35
	 */
34
	public StringToDateValidator(StringToDateConverter converter) {
36
	public StringToDateValidator(StringToDateConverter converter) {
37
		this(converter, null);
38
	}
39
40
	/**
41
	 * @param converter
42
	 * @param parseErrorMessage
43
	 */
44
	public StringToDateValidator(StringToDateConverter converter,
45
			String parseErrorMessage) {
35
		this.converter = converter;
46
		this.converter = converter;
47
		this.parseErrorMessage = parseErrorMessage;
36
	}
48
	}
37
49
38
	/*
50
	/*
39
	 * (non-Javadoc)
51
	 * (non-Javadoc)
40
	 *
52
	 * 
41
	 * @see org.eclipse.core.databinding.validation.IValidator#validate(java.lang.Object)
53
	 * @see
54
	 * org.eclipse.core.databinding.validation.IValidator#validate(java.lang
55
	 * .Object)
42
	 */
56
	 */
43
	public IStatus validate(Object value) {
57
	public IStatus validate(Object value) {
44
		if (value instanceof String && ((String)value).trim().length()==0) {
58
		if (value instanceof String && ((String) value).trim().length() == 0) {
45
			return Status.OK_STATUS;
59
			return Status.OK_STATUS;
46
		}
60
		}
47
		Object convertedValue = converter.convert(value);
61
		Object convertedValue = converter.convert(value);
48
		//The StringToDateConverter returns null if it can't parse the date.
62
		// The StringToDateConverter returns null if it can't parse the date.
49
		if (convertedValue == null) {
63
		if (convertedValue == null) {
50
			return ValidationStatus.error(getErrorMessage());
64
			return ValidationStatus.error(getErrorMessage());
51
		}
65
		}
Lines 55-64 Link Here
55
69
56
	/*
70
	/*
57
	 * (non-Javadoc)
71
	 * (non-Javadoc)
58
	 *
72
	 * 
59
	 * @see org.eclipse.core.internal.databinding.validation.WrappedConverterValidator#getErrorMessage()
73
	 * @see
74
	 * org.eclipse.core.internal.databinding.validation.WrappedConverterValidator
75
	 * #getErrorMessage()
60
	 */
76
	 */
61
	protected String getErrorMessage() {
77
	protected String getErrorMessage() {
78
		if (parseErrorMessage != null) {
79
			return parseErrorMessage;
80
		}
81
62
		Date sampleDate = new Date();
82
		Date sampleDate = new Date();
63
83
64
		// FIXME We need to use the information from the
84
		// FIXME We need to use the information from the
Lines 73-86 Link Here
73
		samples.append('\'');
93
		samples.append('\'');
74
		samples.append(util.format(sampleDate, 0));
94
		samples.append(util.format(sampleDate, 0));
75
		samples.append('\'');
95
		samples.append('\'');
76
		return BindingMessages.getString(BindingMessages.EXAMPLES) + ": " + samples + ",..."; //$NON-NLS-1$//$NON-NLS-2$
96
		return BindingMessages.getString(BindingMessages.EXAMPLES)
97
				+ ": " + samples + ",..."; //$NON-NLS-1$//$NON-NLS-2$
77
	}
98
	}
78
99
79
	private static class FormatUtil extends DateConversionSupport {
100
	private static class FormatUtil extends DateConversionSupport {
80
		/*
101
		/*
81
		 * (non-Javadoc)
102
		 * (non-Javadoc)
82
		 *
103
		 * 
83
		 * @see org.eclipse.core.internal.databinding.conversion.DateConversionSupport#numFormatters()
104
		 * @see
105
		 * org.eclipse.core.internal.databinding.conversion.DateConversionSupport
106
		 * #numFormatters()
84
		 */
107
		 */
85
		protected int numFormatters() {
108
		protected int numFormatters() {
86
			return super.numFormatters();
109
			return super.numFormatters();
Lines 88-95 Link Here
88
111
89
		/*
112
		/*
90
		 * (non-Javadoc)
113
		 * (non-Javadoc)
91
		 *
114
		 * 
92
		 * @see org.eclipse.core.internal.databinding.conversion.DateConversionSupport#format(java.util.Date)
115
		 * @see
116
		 * org.eclipse.core.internal.databinding.conversion.DateConversionSupport
117
		 * #format(java.util.Date)
93
		 */
118
		 */
94
		protected String format(Date date) {
119
		protected String format(Date date) {
95
			return super.format(date);
120
			return super.format(date);
Lines 97-105 Link Here
97
122
98
		/*
123
		/*
99
		 * (non-Javadoc)
124
		 * (non-Javadoc)
100
		 *
125
		 * 
101
		 * @see org.eclipse.core.internal.databinding.conversion.DateConversionSupport#format(java.util.Date,
126
		 * @see
102
		 *      int)
127
		 * org.eclipse.core.internal.databinding.conversion.DateConversionSupport
128
		 * #format(java.util.Date, int)
103
		 */
129
		 */
104
		protected String format(Date date, int formatterIdx) {
130
		protected String format(Date date, int formatterIdx) {
105
			return super.format(date, formatterIdx);
131
			return super.format(date, formatterIdx);
(-)src/org/eclipse/core/internal/databinding/validation/AbstractStringToNumberValidator.java (-14 / +59 lines)
Lines 11-16 Link Here
11
11
12
package org.eclipse.core.internal.databinding.validation;
12
package org.eclipse.core.internal.databinding.validation;
13
13
14
import java.text.ParsePosition;
15
14
import org.eclipse.core.databinding.validation.IValidator;
16
import org.eclipse.core.databinding.validation.IValidator;
15
import org.eclipse.core.databinding.validation.ValidationStatus;
17
import org.eclipse.core.databinding.validation.ValidationStatus;
16
import org.eclipse.core.internal.databinding.conversion.StringToNumberParser;
18
import org.eclipse.core.internal.databinding.conversion.StringToNumberParser;
Lines 19-26 Link Here
19
import org.eclipse.core.runtime.Status;
21
import org.eclipse.core.runtime.Status;
20
22
21
/**
23
/**
22
 * Validates a number that is to be converted by a {@link NumberFormatConverter}.
24
 * Validates a number that is to be converted by a {@link NumberFormatConverter}
23
 * Validation is comprised of parsing the String and range checks.
25
 * . Validation is comprised of parsing the String and range checks.
24
 * 
26
 * 
25
 * @since 1.0
27
 * @since 1.0
26
 */
28
 */
Lines 31-50 Link Here
31
	private final Number min;
33
	private final Number min;
32
	private final Number max;
34
	private final Number max;
33
35
34
	private String outOfRangeMessage;
36
	private final String parseErrorMessage;
37
	private final String outOfRangeMessage;
38
39
	private String formattedOutOfRangeMessage;
35
40
36
	/**
41
	/**
37
	 * Constructs a new instance.
42
	 * Constructs a new instance.
38
	 * 
43
	 * 
39
	 * @param converter converter and thus formatter to be used in validation
44
	 * @param converter
40
	 * @param min minimum value, used for reporting a range error to the user
45
	 *            converter and thus formatter to be used in validation
41
	 * @param max maximum value, used for reporting a range error to the user
46
	 * @param min
47
	 *            minimum value, used for reporting a range error to the user
48
	 * @param max
49
	 *            maximum value, used for reporting a range error to the user
42
	 */
50
	 */
43
	protected AbstractStringToNumberValidator(NumberFormatConverter converter,
51
	protected AbstractStringToNumberValidator(NumberFormatConverter converter,
44
			Number min, Number max) {
52
			Number min, Number max) {
53
		this(converter, min, max, null, null);
54
	}
55
56
	/**
57
	 * Constructs a new instance.
58
	 * 
59
	 * @param converter
60
	 *            converter and thus formatter to be used in validation
61
	 * @param min
62
	 *            minimum value, used for reporting a range error to the user
63
	 * @param max
64
	 *            maximum value, used for reporting a range error to the user
65
	 * @param parseErrorMessage
66
	 * @param outOfRangeMessage
67
	 */
68
	protected AbstractStringToNumberValidator(NumberFormatConverter converter,
69
			Number min, Number max, String parseErrorMessage,
70
			String outOfRangeMessage) {
45
		this.converter = converter;
71
		this.converter = converter;
46
		this.min = min;
72
		this.min = min;
47
		this.max = max;
73
		this.max = max;
74
		this.parseErrorMessage = parseErrorMessage;
75
		this.outOfRangeMessage = outOfRangeMessage;
48
76
49
		if (converter.getToType() instanceof Class) {
77
		if (converter.getToType() instanceof Class) {
50
			Class clazz = (Class) converter.getToType();
78
			Class clazz = (Class) converter.getToType();
Lines 55-61 Link Here
55
	}
83
	}
56
84
57
	/**
85
	/**
58
	 * Validates the provided <code>value</code>.  An error status is returned if:
86
	 * Validates the provided <code>value</code>. An error status is returned
87
	 * if:
59
	 * <ul>
88
	 * <ul>
60
	 * <li>The value cannot be parsed.</li>
89
	 * <li>The value cannot be parsed.</li>
61
	 * <li>The value is out of range.</li>
90
	 * <li>The value is out of range.</li>
Lines 69-85 Link Here
69
98
70
		if (result.getNumber() != null) {
99
		if (result.getNumber() != null) {
71
			if (!isInRange(result.getNumber())) {
100
			if (!isInRange(result.getNumber())) {
72
				if (outOfRangeMessage == null) {
101
				if (formattedOutOfRangeMessage == null) {
73
					outOfRangeMessage = StringToNumberParser
102
					formattedOutOfRangeMessage = createOutOfRangeMessage();
74
							.createOutOfRangeMessage(min, max, converter
75
									.getNumberFormat());
76
				}
103
				}
77
104
78
				return ValidationStatus.error(outOfRangeMessage);
105
				return ValidationStatus.error(formattedOutOfRangeMessage);
79
			}
106
			}
80
		} else if (result.getPosition() != null) {
107
		} else if (result.getPosition() != null) {
81
			String parseErrorMessage = StringToNumberParser.createParseErrorMessage(
108
			String parseErrorMessage = createParseErrorMessage((String) value,
82
					(String) value, result.getPosition());
109
					result.getPosition());
83
110
84
			return ValidationStatus.error(parseErrorMessage);
111
			return ValidationStatus.error(parseErrorMessage);
85
		}
112
		}
Lines 94-97 Link Here
94
	 * @return <code>true</code> if in range
121
	 * @return <code>true</code> if in range
95
	 */
122
	 */
96
	protected abstract boolean isInRange(Number number);
123
	protected abstract boolean isInRange(Number number);
124
125
	private String createParseErrorMessage(String input,
126
			ParsePosition parsePosition) {
127
		if (parseErrorMessage == null) {
128
			return StringToNumberParser.createParseErrorMessage(input,
129
					parsePosition);
130
		}
131
		return parseErrorMessage;
132
	}
133
134
	private String createOutOfRangeMessage() {
135
		if (outOfRangeMessage == null) {
136
			return StringToNumberParser.createOutOfRangeMessage(min, max,
137
					converter.getNumberFormat());
138
		}
139
		return StringToNumberParser.createOutOfRangeMessage(outOfRangeMessage,
140
				min, max, converter.getNumberFormat());
141
	}
97
}
142
}
(-)META-INF/MANIFEST.MF (+1 lines)
Lines 8-13 Link Here
8
Bundle-Localization: plugin
8
Bundle-Localization: plugin
9
Export-Package: org.eclipse.core.databinding,
9
Export-Package: org.eclipse.core.databinding,
10
 org.eclipse.core.databinding.conversion;x-internal:=false,
10
 org.eclipse.core.databinding.conversion;x-internal:=false,
11
 org.eclipse.core.databinding.editing,
11
 org.eclipse.core.databinding.validation;x-internal:=false,
12
 org.eclipse.core.databinding.validation;x-internal:=false,
12
 org.eclipse.core.internal.databinding;x-friends:="org.eclipse.core.databinding.beans",
13
 org.eclipse.core.internal.databinding;x-friends:="org.eclipse.core.databinding.beans",
13
 org.eclipse.core.internal.databinding.conversion;x-friends:="org.eclipse.jface.tests.databinding",
14
 org.eclipse.core.internal.databinding.conversion;x-friends:="org.eclipse.jface.tests.databinding",
(-)src/org/eclipse/core/internal/databinding/validation/NonNullValidator.java (+47 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.validation;
13
14
import org.eclipse.core.databinding.validation.IValidator;
15
import org.eclipse.core.databinding.validation.ValidationStatus;
16
import org.eclipse.core.runtime.IStatus;
17
18
/**
19
 * @since 1.3
20
 */
21
public class NonNullValidator implements IValidator {
22
23
	private final String validationMessage;
24
25
	/**
26
	 * 
27
	 */
28
	public NonNullValidator() {
29
		this(null);
30
	}
31
32
	/**
33
	 * @param validationMessage
34
	 */
35
	public NonNullValidator(String validationMessage) {
36
		// TODO: Externalize
37
		this.validationMessage = validationMessage != null ? validationMessage
38
				: "The value must not be empty."; //$NON-NLS-1$
39
	}
40
41
	public IStatus validate(Object value) {
42
		if (value == null) {
43
			return ValidationStatus.error(validationMessage);
44
		}
45
		return ValidationStatus.ok();
46
	}
47
}
(-)src/org/eclipse/core/internal/databinding/validation/ValidatorChain.java (+46 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.validation;
13
14
import org.eclipse.core.databinding.validation.IValidator;
15
import org.eclipse.core.runtime.IStatus;
16
import org.eclipse.core.runtime.Status;
17
18
/**
19
 * @since 1.3
20
 */
21
public class ValidatorChain implements IValidator {
22
23
	private final IValidator[] validators;
24
25
	/**
26
	 * @param validators
27
	 */
28
	public ValidatorChain(IValidator[] validators) {
29
		this.validators = validators;
30
	}
31
32
	public IStatus validate(Object value) {
33
		// TODO: Define an aggregation strategy.
34
		int maxSeverity = IStatus.OK;
35
		IStatus maxStatus = Status.OK_STATUS;
36
		for (int i = 0; i < validators.length; i++) {
37
			IValidator validator = validators[i];
38
			IStatus status = validator.validate(value);
39
			if (status.getSeverity() > maxSeverity) {
40
				maxSeverity = status.getSeverity();
41
				maxStatus = status;
42
			}
43
		}
44
		return maxStatus;
45
	}
46
}
(-)src/org/eclipse/core/internal/databinding/conversion/NumberRangeValidator.java (+64 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.conversion;
13
14
import java.text.MessageFormat;
15
16
import org.eclipse.core.databinding.validation.IValidator;
17
import org.eclipse.core.databinding.validation.ValidationStatus;
18
import org.eclipse.core.runtime.IStatus;
19
20
/**
21
 * @since 1.3
22
 */
23
public class NumberRangeValidator implements IValidator {
24
25
	private final Number min;
26
	private final Number max;
27
	private final String validationMessage;
28
29
	/**
30
	 * 
31
	 * @param min
32
	 * @param max
33
	 */
34
	public NumberRangeValidator(Number min, Number max) {
35
		this(min, max, null);
36
	}
37
38
	/**
39
	 * 
40
	 * @param min
41
	 * @param max
42
	 * @param validationMessage
43
	 */
44
	public NumberRangeValidator(Number min, Number max, String validationMessage) {
45
		this.min = min;
46
		this.max = max;
47
		// TODO: Externalize
48
		this.validationMessage = validationMessage != null ? validationMessage
49
				: "The value must lie in the range [{0}, {1}]"; //$NON-NLS-1$
50
	}
51
52
	public IStatus validate(Object value) {
53
		if (value != null) {
54
			Comparable comparableValue = (Comparable) value;
55
			if (comparableValue.compareTo(min) < 0
56
					|| comparableValue.compareTo(max) > 0) {
57
				// TODO: Cache message?
58
				return ValidationStatus.error(MessageFormat.format(
59
						validationMessage, new Number[] { min, max }));
60
			}
61
		}
62
		return ValidationStatus.ok();
63
	}
64
}
(-)src/org/eclipse/core/databinding/editing/IntegerEditing.java (+272 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.editing;
13
14
import org.eclipse.core.databinding.conversion.NumberToStringConverter;
15
import org.eclipse.core.databinding.conversion.StringToNumberConverter;
16
import org.eclipse.core.databinding.validation.IValidator;
17
import org.eclipse.core.internal.databinding.conversion.NumberRangeValidator;
18
import org.eclipse.core.internal.databinding.validation.NonNullValidator;
19
import org.eclipse.core.internal.databinding.validation.StringToIntegerValidator;
20
21
import com.ibm.icu.text.NumberFormat;
22
23
/**
24
 * @since 1.3
25
 */
26
public final class IntegerEditing extends Editing {
27
28
	private static final Integer ONE = new Integer(1);
29
	private static final Integer MAX_INTEGER = new Integer(Integer.MAX_VALUE);
30
31
	private String requiredMessage = null;
32
33
	private String rangeMessage = null;
34
35
	// TODO: Externalize
36
	private String positiveMessage = "The value must be positive."; //$NON-NLS-1$
37
38
	private IntegerEditing(NumberFormat format, String parseErrorMessage,
39
			String outOfRangeMessage) {
40
		StringToNumberConverter targetConverter = StringToNumberConverter
41
				.toInteger(format, false);
42
43
		doAddTargetValidator(new StringToIntegerValidator(targetConverter,
44
				parseErrorMessage, outOfRangeMessage));
45
		doSetTargetConverter(targetConverter);
46
		doSetModelConverter(NumberToStringConverter.fromInteger(format, false));
47
	}
48
49
	/**
50
	 * Creates a new editing object which defaults the validations and
51
	 * conversions used for editing based on the platform's locale. Uses the
52
	 * default validation messages.
53
	 * 
54
	 * @return The new editing object using the default validations and
55
	 *         conversions for editing.
56
	 * 
57
	 * @see NumberFormat#getIntegerInstance()
58
	 */
59
	public static IntegerEditing withDefaults() {
60
		return withDefaults(null, null);
61
	}
62
63
	/**
64
	 * Creates a new editing object which defaults the validations and
65
	 * conversions used for editing based on the platform's locale. Uses the
66
	 * specified custom validation messages.
67
	 * 
68
	 * @param parseErrorMessage
69
	 *            The validation message issued in case the input string cannot
70
	 *            be parsed to an integer.
71
	 * @param outOfRangeMessage
72
	 *            The validation message issued in case the input string
73
	 *            represents an integer whose value is out of range. Can be
74
	 *            parameterized by the <code>Integer.MIN_VALUE</code> and
75
	 *            <code>Integer.MAX_VALUE</code> values.
76
	 * @return The new editing object using the default validations and
77
	 *         conversions for editing.
78
	 */
79
	public static IntegerEditing withDefaults(String parseErrorMessage,
80
			String outOfRangeMessage) {
81
		return new IntegerEditing(NumberFormat.getIntegerInstance(),
82
				parseErrorMessage, outOfRangeMessage);
83
	}
84
85
	/**
86
	 * Creates a new editing object whose validations and conversions used for
87
	 * editing are based on the given integer format. Uses the default
88
	 * validation messages.
89
	 * 
90
	 * @param format
91
	 *            The integer format defining the validations and conversions
92
	 *            used for editing.
93
	 * @return The new editing object configured by the given integer format.
94
	 */
95
	public static IntegerEditing forFormat(NumberFormat format) {
96
		return forFormat(format, null, null);
97
	}
98
99
	/**
100
	 * Creates a new editing object whose validations and conversions used for
101
	 * editing are based on the given integer format. Uses the specified custom
102
	 * validation messages.
103
	 * 
104
	 * @param format
105
	 *            The integer format defining the validations and conversions
106
	 *            used for editing.
107
	 * @param parseErrorMessage
108
	 *            The validation message issued in case the input string cannot
109
	 *            be parsed to an integer.
110
	 * @param outOfRangeMessage
111
	 *            The validation message issued in case the input string
112
	 *            represents an integer whose value is out of range. Can be
113
	 *            parameterized by the <code>Integer.MIN_VALUE</code> and
114
	 *            <code>Integer.MAX_VALUE</code> values.
115
	 * @return The new editing object configured by the given integer format.
116
	 */
117
	public static IntegerEditing forFormat(NumberFormat format,
118
			String parseErrorMessage, String outOfRangeMessage) {
119
		return new IntegerEditing(format, parseErrorMessage, outOfRangeMessage);
120
	}
121
122
	/**
123
	 * Adds a model validator ensuring that the parsed integer is not
124
	 * <code>null</code>. Uses the default validation message.
125
	 * 
126
	 * @return This editing instance for method chaining.
127
	 */
128
	public IntegerEditing required() {
129
		return required(requiredMessage);
130
	}
131
132
	/**
133
	 * Adds a model validator ensuring that the parsed integer is not
134
	 * <code>null</code>. Uses the specified custom validation message.
135
	 * 
136
	 * @param message
137
	 *            The validation message issued in case the parsed integer is
138
	 *            <code>null</code>.
139
	 * @return This editing instance for method chaining.
140
	 */
141
	public IntegerEditing required(String message) {
142
		return addModelValidator(new NonNullValidator(message));
143
	}
144
145
	/**
146
	 * Sets the default validation message to be issued in case the parsed
147
	 * integer is <code>null</code>.
148
	 * 
149
	 * @param message
150
	 *            The default validation message to be issued in case the parsed
151
	 *            integer is <code>null</code>.
152
	 * @return This editing instance for method chaining.
153
	 * 
154
	 * @see #required()
155
	 */
156
	public IntegerEditing requiredMessage(String message) {
157
		this.requiredMessage = message;
158
		return this;
159
	}
160
161
	/**
162
	 * Adds a model validator ensuring that the parsed integer is positive. Uses
163
	 * the default validation message.
164
	 * 
165
	 * @return This editing instance for method chaining.
166
	 */
167
	public IntegerEditing positive() {
168
		return positive(positiveMessage);
169
	}
170
171
	/**
172
	 * Adds a model validator ensuring that the parsed integer is positive. Uses
173
	 * the specified custom validation message.
174
	 * 
175
	 * @param message
176
	 *            The validation message issued in case the parsed integer is
177
	 *            not positive.
178
	 * @return This editing instance for method chaining.
179
	 */
180
	public IntegerEditing positive(String message) {
181
		return addModelValidator(new NumberRangeValidator(ONE, MAX_INTEGER,
182
				message));
183
	}
184
185
	/**
186
	 * Sets the default validation message to be issued in case the parsed
187
	 * integer is not positive.
188
	 * 
189
	 * @param message
190
	 *            The default validation message to be issued in case the parsed
191
	 *            integer is not positive.
192
	 * @return This editing instance for method chaining.
193
	 * 
194
	 * @see #positive()
195
	 */
196
	public IntegerEditing positiveMessage(String message) {
197
		this.positiveMessage = message;
198
		return this;
199
	}
200
201
	/**
202
	 * Adds a model validator ensuring that the parsed integer is within the
203
	 * given range. Uses the default validation message.
204
	 * 
205
	 * @param min
206
	 *            The lower bound of the range (inclusive).
207
	 * @param max
208
	 *            The upper bound of the range (inclusive).
209
	 * @return This editing instance for method chaining.
210
	 */
211
	public IntegerEditing range(int min, int max) {
212
		return range(min, max, rangeMessage);
213
	}
214
215
	/**
216
	 * Adds a model validator ensuring that the parsed integer is within the
217
	 * given range. Uses the specified custom validation message.
218
	 * 
219
	 * @param min
220
	 *            The lower bound of the range (inclusive).
221
	 * @param max
222
	 *            The upper bound of the range (inclusive).
223
	 * @param message
224
	 *            The validation message issued in case the parsed integer is
225
	 *            not within the given range.
226
	 * @return This editing instance for method chaining.
227
	 */
228
	public IntegerEditing range(int min, int max, String message) {
229
		return addModelValidator(new NumberRangeValidator(new Integer(min),
230
				new Integer(max), message));
231
	}
232
233
	/**
234
	 * Sets the default validation message to be issued in case the parsed
235
	 * integer is not within a given range.
236
	 * 
237
	 * @param message
238
	 *            The default validation message to be issued in case the parsed
239
	 *            integer is not within a given range.
240
	 * @return This editing instance for method chaining.
241
	 * 
242
	 * @see #range(int, int)
243
	 */
244
	public IntegerEditing rangeMessage(String message) {
245
		this.rangeMessage = message;
246
		return this;
247
	}
248
249
	/**
250
	 * Adds a custom target validator.
251
	 * 
252
	 * @param validator
253
	 *            The custom target validator to add.
254
	 * @return This editing instance for method chaining.
255
	 */
256
	public IntegerEditing addTargetValidator(IValidator validator) {
257
		doAddTargetValidator(validator);
258
		return this;
259
	}
260
261
	/**
262
	 * Adds a custom model validator.
263
	 * 
264
	 * @param validator
265
	 *            The custom model validator to add.
266
	 * @return This editing instance for method chaining.
267
	 */
268
	public IntegerEditing addModelValidator(IValidator validator) {
269
		doAddModelValidator(validator);
270
		return this;
271
	}
272
}
(-)src/org/eclipse/core/databinding/editing/Editing.java (+245 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.editing;
13
14
import java.util.ArrayList;
15
import java.util.List;
16
17
import org.eclipse.core.databinding.UpdateListStrategy;
18
import org.eclipse.core.databinding.UpdateValueStrategy;
19
import org.eclipse.core.databinding.conversion.IConverter;
20
import org.eclipse.core.databinding.validation.IValidator;
21
import org.eclipse.core.internal.databinding.validation.ValidatorChain;
22
23
/**
24
 * @since 1.3
25
 */
26
public abstract class Editing {
27
28
	private final List targetValidators = new ArrayList();
29
30
	private IConverter targetConverter;
31
32
	private final List modelValidators = new ArrayList();
33
34
	private IConverter modelConverter;
35
36
	protected final void doAddTargetValidator(IValidator targetValidator) {
37
		targetValidators.add(targetValidator);
38
	}
39
40
	protected final void doSetTargetConverter(IConverter targetConverter) {
41
		this.targetConverter = targetConverter;
42
	}
43
44
	protected final void doAddModelValidator(IValidator modelValidator) {
45
		modelValidators.add(modelValidator);
46
	}
47
48
	protected final void doSetModelConverter(IConverter modelConverter) {
49
		this.modelConverter = modelConverter;
50
	}
51
52
	/**
53
	 * Creates a new target-to-model {@link UpdateValueStrategy} with a default
54
	 * update policy configured by the current state of this editing object.
55
	 * 
56
	 * @return A new target-to-model {@link UpdateValueStrategy} configured by
57
	 *         the current state of this editing object.
58
	 * 
59
	 * @see UpdateValueStrategy#UpdateValueStrategy()
60
	 */
61
	public UpdateValueStrategy createTargetValueStrategy() {
62
		return applyToTargetValueStrategy(new UpdateValueStrategy());
63
	}
64
65
	/**
66
	 * Creates a new target-to-model {@link UpdateValueStrategy} with the given
67
	 * update policy configured by the current state of this editing object.
68
	 * 
69
	 * @param updatePolicy
70
	 *            The update policy to use.
71
	 * @return A new target-to-model {@link UpdateValueStrategy} configured by
72
	 *         the current state of this editing object.
73
	 * 
74
	 * @see UpdateValueStrategy#UpdateValueStrategy(int)
75
	 */
76
	public UpdateValueStrategy createTargetValueStrategy(int updatePolicy) {
77
		return applyToTargetValueStrategy(new UpdateValueStrategy(updatePolicy));
78
	}
79
80
	/**
81
	 * Creates a new model-to-target {@link UpdateValueStrategy} with a default
82
	 * update policy configured by the current state of this editing object.
83
	 * 
84
	 * @return A new model-to-target {@link UpdateValueStrategy} configured by
85
	 *         the current state of this editing object.
86
	 * 
87
	 * @see UpdateValueStrategy#UpdateValueStrategy()
88
	 */
89
	public UpdateValueStrategy createModelValueStrategy() {
90
		return applyToModelValueStrategy(new UpdateValueStrategy());
91
	}
92
93
	/**
94
	 * Creates a new model-to-target {@link UpdateValueStrategy} with the given
95
	 * update policy configured by the current state of this editing object.
96
	 * 
97
	 * @param updatePolicy
98
	 *            The update policy to use.
99
	 * @return A new model-to-target {@link UpdateValueStrategy} configured by
100
	 *         the current state of this editing object.
101
	 * 
102
	 * @see UpdateValueStrategy#UpdateValueStrategy(int)
103
	 */
104
	public UpdateValueStrategy createModelValueStrategy(int updatePolicy) {
105
		return applyToModelValueStrategy(new UpdateValueStrategy(updatePolicy));
106
	}
107
108
	/**
109
	 * Creates a new target-to-model {@link UpdateListStrategy} with a default
110
	 * update policy configured by the current state of this editing object.
111
	 * 
112
	 * @return A new target-to-model {@link UpdateListStrategy} configured by
113
	 *         the current state of this editing object.
114
	 * 
115
	 * @see UpdateListStrategy#UpdateListStrategy()
116
	 */
117
	public UpdateListStrategy createTargetListStrategy() {
118
		return applyToTargetListStrategy(new UpdateListStrategy());
119
	}
120
121
	/**
122
	 * Creates a new target-to-model {@link UpdateListStrategy} with the given
123
	 * update policy configured by the current state of this editing object.
124
	 * 
125
	 * @param updatePolicy
126
	 *            The update policy to use.
127
	 * @return A new target-to-model {@link UpdateListStrategy} configured by
128
	 *         the current state of this editing object.
129
	 * 
130
	 * @see UpdateListStrategy#UpdateListStrategy(int)
131
	 */
132
	public UpdateListStrategy createTargetListStrategy(int updatePolicy) {
133
		return applyToTargetListStrategy(new UpdateListStrategy(updatePolicy));
134
	}
135
136
	/**
137
	 * Creates a new model-to-target {@link UpdateListStrategy} with a default
138
	 * update policy configured by the current state of this editing object.
139
	 * 
140
	 * @return A new model-to-target {@link UpdateListStrategy} configured by
141
	 *         the current state of this editing object.
142
	 * 
143
	 * @see UpdateListStrategy#UpdateListStrategy()
144
	 */
145
	public UpdateListStrategy createModelListStrategy() {
146
		return applyToModelListStrategy(new UpdateListStrategy());
147
	}
148
149
	/**
150
	 * Creates a new model-to-target {@link UpdateListStrategy} with the given
151
	 * update policy configured by the current state of this editing object.
152
	 * 
153
	 * @param updatePolicy
154
	 *            The update policy to use.
155
	 * @return A new model-to-target {@link UpdateListStrategy} configured by
156
	 *         the current state of this editing object.
157
	 * 
158
	 * @see UpdateListStrategy#UpdateListStrategy(int)
159
	 */
160
	public UpdateListStrategy createModelListStrategy(int updatePolicy) {
161
		return applyToModelListStrategy(new UpdateListStrategy(updatePolicy));
162
	}
163
164
	/**
165
	 * Configures an existing target-to-model {@link UpdateValueStrategy} with
166
	 * the current state of this editing object.
167
	 * 
168
	 * @param updateStrategy
169
	 *            The {@link UpdateValueStrategy} to configure.
170
	 * @return The passed-in, configured target-to-model
171
	 *         {@link UpdateValueStrategy}.
172
	 */
173
	public UpdateValueStrategy applyToTargetValueStrategy(
174
			UpdateValueStrategy updateStrategy) {
175
		updateStrategy.setAfterGetValidator(createTargetValidator());
176
		updateStrategy.setConverter(targetConverter);
177
		updateStrategy.setAfterConvertValidator(createModelValidator());
178
		return updateStrategy;
179
	}
180
181
	/**
182
	 * Configures an existing model-to-target {@link UpdateValueStrategy} with
183
	 * the current state of this editing object.
184
	 * 
185
	 * @param updateStrategy
186
	 *            The {@link UpdateValueStrategy} to configure.
187
	 * @return The passed-in, configured model-to-target
188
	 *         {@link UpdateValueStrategy}.
189
	 */
190
	public UpdateValueStrategy applyToModelValueStrategy(
191
			UpdateValueStrategy updateStrategy) {
192
		updateStrategy.setConverter(modelConverter);
193
		return updateStrategy;
194
	}
195
196
	/**
197
	 * Configures an existing target-to-model {@link UpdateListStrategy} with
198
	 * the current state of this editing object.
199
	 * 
200
	 * @param updateStrategy
201
	 *            The {@link UpdateListStrategy} to configure.
202
	 * @return The passed-in, configured target-to-model
203
	 *         {@link UpdateListStrategy}.
204
	 */
205
	public UpdateListStrategy applyToTargetListStrategy(
206
			UpdateListStrategy updateStrategy) {
207
		updateStrategy.setConverter(targetConverter);
208
		return updateStrategy;
209
	}
210
211
	/**
212
	 * Configures an existing model-to-target {@link UpdateListStrategy} with
213
	 * the current state of this editing object.
214
	 * 
215
	 * @param updateStrategy
216
	 *            The {@link UpdateListStrategy} to configure.
217
	 * @return The passed-in, configured model-to-target
218
	 *         {@link UpdateListStrategy}.
219
	 */
220
	public UpdateListStrategy applyToModelListStrategy(
221
			UpdateListStrategy updateStrategy) {
222
		updateStrategy.setConverter(modelConverter);
223
		return updateStrategy;
224
	}
225
226
	private IValidator createTargetValidator() {
227
		if (!targetValidators.isEmpty()) {
228
			ValidatorChain targetValidator = new ValidatorChain(
229
					(IValidator[]) targetValidators
230
							.toArray(new IValidator[targetValidators.size()]));
231
			return targetValidator;
232
		}
233
		return null;
234
	}
235
236
	private IValidator createModelValidator() {
237
		if (!modelValidators.isEmpty()) {
238
			ValidatorChain modelValidator = new ValidatorChain(
239
					(IValidator[]) modelValidators
240
							.toArray(new IValidator[modelValidators.size()]));
241
			return modelValidator;
242
		}
243
		return null;
244
	}
245
}
(-)src/org/eclipse/core/databinding/editing/DateEditing.java (+200 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.editing;
13
14
import org.eclipse.core.databinding.validation.IValidator;
15
import org.eclipse.core.internal.databinding.conversion.DateToStringConverter;
16
import org.eclipse.core.internal.databinding.conversion.StringToDateConverter;
17
import org.eclipse.core.internal.databinding.validation.NonNullValidator;
18
import org.eclipse.core.internal.databinding.validation.StringToDateValidator;
19
20
import com.ibm.icu.text.DateFormat;
21
22
/**
23
 * @since 1.3
24
 */
25
public final class DateEditing extends Editing {
26
27
	private String requiredMessage = null;
28
29
	private DateEditing(DateFormat[] inputFormats, String parseErrorMessage,
30
			DateFormat displayFormat) {
31
		StringToDateConverter targetConverter;
32
		if (inputFormats == null) {
33
			targetConverter = new StringToDateConverter();
34
		} else {
35
			targetConverter = new StringToDateConverter(inputFormats);
36
		}
37
38
		doAddTargetValidator(new StringToDateValidator(targetConverter,
39
				parseErrorMessage));
40
		doSetTargetConverter(targetConverter);
41
		doSetModelConverter(displayFormat == null ? new DateToStringConverter()
42
				: new DateToStringConverter(displayFormat));
43
	}
44
45
	/**
46
	 * Creates a new editing object which defaults the validations and
47
	 * conversions used for editing. Uses the default validation message.
48
	 * 
49
	 * @return The new editing object using the default validations and
50
	 *         conversions for editing.
51
	 */
52
	public static DateEditing withDefaults() {
53
		return withDefaults(null);
54
	}
55
56
	/**
57
	 * Creates a new editing object which defaults the validations and
58
	 * conversions used for editing. Uses the specified custom validation
59
	 * message.
60
	 * 
61
	 * @param parseErrorMessage
62
	 *            The validation message issued in case the input string cannot
63
	 *            be parsed to a date.
64
	 * @return The new editing object using the default validations and
65
	 *         conversions for editing.
66
	 */
67
	public static DateEditing withDefaults(String parseErrorMessage) {
68
		return new DateEditing(null, parseErrorMessage, null);
69
	}
70
71
	/**
72
	 * Creates a new editing object which supports all the given date formats
73
	 * for input and which uses the first specified format for displaying a
74
	 * date. Uses the default validation message.
75
	 * 
76
	 * @param formats
77
	 *            The date formats supported for reading in and displaying
78
	 *            dates.
79
	 * @return The new editing object configured by the given date formats.
80
	 */
81
	public static DateEditing forFormats(DateFormat[] formats) {
82
		return new DateEditing(formats, null, formats[0]);
83
	}
84
85
	/**
86
	 * Creates a new editing object which supports all the given date formats
87
	 * for input and which uses the first specified format for displaying a
88
	 * date. Uses the specified custom validation message.
89
	 * 
90
	 * @param formats
91
	 *            The date formats supported for reading in and displaying
92
	 *            dates.
93
	 * @param parseErrorMessage
94
	 *            The validation message issued in case the input string cannot
95
	 *            be parsed to a date.
96
	 * @return The new editing object configured by the given date formats.
97
	 */
98
	public static DateEditing forFormats(DateFormat[] formats,
99
			String parseErrorMessage) {
100
		return new DateEditing(formats, parseErrorMessage, formats[0]);
101
	}
102
103
	/**
104
	 * Creates a new editing object which supports all the given date input
105
	 * formats and which uses the specified format for displaying a date. Uses
106
	 * the default validation message.
107
	 * 
108
	 * @param inputFormats
109
	 *            The date formats supported for reading in dates.
110
	 * @param displayFormat
111
	 *            The date format for displaying dates.
112
	 * @return The new editing object configured by the given date formats.
113
	 */
114
	public static DateEditing forFormats(DateFormat[] inputFormats,
115
			DateFormat displayFormat) {
116
		return new DateEditing(inputFormats, null, displayFormat);
117
	}
118
119
	/**
120
	 * Creates a new editing object which supports all the given date input
121
	 * formats and which uses the specified format for displaying a date. Uses
122
	 * the specified custom validation message.
123
	 * 
124
	 * @param inputFormats
125
	 *            The date formats supported for reading in dates.
126
	 * @param parseErrorMessage
127
	 *            The validation message issued in case the input string cannot
128
	 *            be parsed to a date.
129
	 * @param displayFormat
130
	 *            The date format for displaying dates.
131
	 * @return The new editing object configured by the given date formats.
132
	 */
133
	public static DateEditing forFormats(DateFormat[] inputFormats,
134
			String parseErrorMessage, DateFormat displayFormat) {
135
		return new DateEditing(inputFormats, parseErrorMessage, displayFormat);
136
	}
137
138
	/**
139
	 * Adds a model validator ensuring that the parsed date is not
140
	 * <code>null</code>. Uses the default validation message.
141
	 * 
142
	 * @return This editing instance for method chaining.
143
	 */
144
	public DateEditing required() {
145
		return required(requiredMessage);
146
	}
147
148
	/**
149
	 * Adds a model validator ensuring that the parsed date is not
150
	 * <code>null</code>. Uses the specified custom validation message.
151
	 * 
152
	 * @param message
153
	 *            The validation message issued in case the parsed date is
154
	 *            <code>null</code>.
155
	 * @return This editing instance for method chaining.
156
	 */
157
	public DateEditing required(String message) {
158
		return addModelValidator(new NonNullValidator(message));
159
	}
160
161
	/**
162
	 * Sets the default validation message to be issued in case the parsed date
163
	 * is <code>null</code>.
164
	 * 
165
	 * @param message
166
	 *            The default validation message to be issued in case the parsed
167
	 *            date is <code>null</code>.
168
	 * @return This editing instance for method chaining.
169
	 * 
170
	 * @see #required()
171
	 */
172
	public DateEditing requiredMessage(String message) {
173
		this.requiredMessage = message;
174
		return this;
175
	}
176
177
	/**
178
	 * Adds a custom target validator.
179
	 * 
180
	 * @param validator
181
	 *            The custom target validator to add.
182
	 * @return This editing instance for method chaining.
183
	 */
184
	public DateEditing addTargetValidator(IValidator validator) {
185
		doAddTargetValidator(validator);
186
		return this;
187
	}
188
189
	/**
190
	 * Adds a custom model validator.
191
	 * 
192
	 * @param validator
193
	 *            The custom model validator to add.
194
	 * @return This editing instance for method chaining.
195
	 */
196
	public DateEditing addModelValidator(IValidator validator) {
197
		doAddModelValidator(validator);
198
		return this;
199
	}
200
}

Return to bug 183055