Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 160440 Details for
Bug 183055
[DataBinding] New Editing and Constraints API
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
first draft of the patch using Java5
editing5.patch (text/plain), 272.65 KB, created by
Ovidio Mallo
on 2010-02-28 18:46:42 EST
(
hide
)
Description:
first draft of the patch using Java5
Filename:
MIME Type:
Creator:
Ovidio Mallo
Created:
2010-02-28 18:46:42 EST
Size:
272.65 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jface.examples.databinding >Index: .settings/org.eclipse.jdt.ui.prefs >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface.examples.databinding/.settings/org.eclipse.jdt.ui.prefs,v >retrieving revision 1.6 >diff -u -r1.6 org.eclipse.jdt.ui.prefs >--- .settings/org.eclipse.jdt.ui.prefs 16 Feb 2009 23:03:20 -0000 1.6 >+++ .settings/org.eclipse.jdt.ui.prefs 28 Feb 2010 23:33:34 -0000 >@@ -1,4 +1,4 @@ >-#Tue Feb 10 16:06:02 MST 2009 >+#Thu Jan 07 19:11:04 CET 2010 > cleanup.add_default_serial_version_id=true > cleanup.add_generated_serial_version_id=false > cleanup.add_missing_annotations=true >@@ -51,7 +51,7 @@ > cleanup_profile=org.eclipse.jdt.ui.default.eclipse_clean_up_profile > cleanup_settings_version=2 > eclipse.preferences.version=1 >-editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true >+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=false > formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile > formatter_settings_version=11 > org.eclipse.jdt.ui.exception.name=e >@@ -78,7 +78,7 @@ > sp_cleanup.always_use_this_for_non_static_method_access=false > sp_cleanup.convert_to_enhanced_for_loop=false > sp_cleanup.correct_indentation=false >-sp_cleanup.format_source_code=true >+sp_cleanup.format_source_code=false > sp_cleanup.format_source_code_changes_only=false > sp_cleanup.make_local_variable_final=false > sp_cleanup.make_parameters_final=false >Index: META-INF/MANIFEST.MF >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface.examples.databinding/META-INF/MANIFEST.MF,v >retrieving revision 1.21 >diff -u -r1.21 MANIFEST.MF >--- META-INF/MANIFEST.MF 24 Aug 2009 21:33:42 -0000 1.21 >+++ META-INF/MANIFEST.MF 28 Feb 2010 23:33:34 -0000 >@@ -17,5 +17,6 @@ > org.eclipse.jface.examples.databinding.mask.internal;x-internal:=true, > org.eclipse.jface.examples.databinding.model;x-internal:=false, > org.eclipse.jface.examples.databinding.radioGroup;x-internal:=false >-Import-Package: com.ibm.icu.text >+Import-Package: com.ibm.icu.math, >+ com.ibm.icu.text > Bundle-RequiredExecutionEnvironment: J2SE-1.5 >Index: src/org/eclipse/jface/examples/databinding/util/ObservableMapEditingSupport.java >=================================================================== >RCS file: src/org/eclipse/jface/examples/databinding/util/ObservableMapEditingSupport.java >diff -N src/org/eclipse/jface/examples/databinding/util/ObservableMapEditingSupport.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/examples/databinding/util/ObservableMapEditingSupport.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,88 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.jface.examples.databinding.util; >+ >+import org.eclipse.core.databinding.editing.Editing; >+import org.eclipse.core.databinding.observable.map.IObservableMap; >+import org.eclipse.core.databinding.util.Policy; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.core.runtime.MultiStatus; >+import org.eclipse.jface.dialogs.MessageDialog; >+import org.eclipse.jface.viewers.CellEditor; >+import org.eclipse.jface.viewers.ColumnViewer; >+import org.eclipse.jface.viewers.EditingSupport; >+import org.eclipse.jface.viewers.TextCellEditor; >+import org.eclipse.swt.widgets.Composite; >+ >+/** >+ * @since 3.2 >+ */ >+public class ObservableMapEditingSupport extends EditingSupport { >+ >+ private final IObservableMap attributeMap; >+ >+ private final Editing editing; >+ >+ private final CellEditor cellEditor; >+ >+ public ObservableMapEditingSupport(ColumnViewer viewer, IObservableMap attributeMap, Editing editing) { >+ super(viewer); >+ this.attributeMap = attributeMap; >+ this.editing = editing; >+ this.cellEditor = new TextCellEditor((Composite) getViewer().getControl()); >+ } >+ >+ protected boolean canEdit(Object element) { >+ return true; >+ } >+ >+ protected CellEditor getCellEditor(Object element) { >+ return cellEditor; >+ } >+ >+ protected Object getValue(Object element) { >+ return editing.convertToTarget(attributeMap.get(element)); >+ } >+ >+ protected void setValue(Object element, Object value) { >+ MultiStatus validationStatus = new MultiStatus(Policy.JFACE_DATABINDING, 0, null, null); >+ Object modelValue = editing.convertToModel(value, validationStatus); >+ if (handleValidation(validationStatus)) { >+ attributeMap.put(element, modelValue); >+ } >+ } >+ >+ private boolean handleValidation(IStatus validationStatus) { >+ if (validationStatus.matches(IStatus.ERROR | IStatus.CANCEL)) { >+ MessageDialog.openError(getViewer().getControl().getShell(), "Validation Error", getValidationMessage(validationStatus)); >+ return false; >+ } >+ return true; >+ } >+ >+ private static String getValidationMessage(IStatus validationStatus) { >+ if (!validationStatus.isMultiStatus()) { >+ return validationStatus.getMessage(); >+ } >+ >+ MultiStatus multiStatus = (MultiStatus) validationStatus; >+ StringBuffer sb = new StringBuffer(); >+ IStatus[] childStatus = multiStatus.getChildren(); >+ for (int i = 0; i < childStatus.length; i++) { >+ if (i > 0) { >+ sb.append('\n'); >+ } >+ sb.append(getValidationMessage(childStatus[i])); >+ } >+ return sb.toString(); >+ } >+} >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,283 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.jface.examples.databinding.snippets; >+ >+import java.util.Calendar; >+import java.util.Date; >+ >+import org.eclipse.core.databinding.Binding; >+import org.eclipse.core.databinding.DataBindingContext; >+import org.eclipse.core.databinding.editing.BooleanEditing; >+import org.eclipse.core.databinding.editing.DateEditing; >+import org.eclipse.core.databinding.editing.Editing; >+import org.eclipse.core.databinding.editing.NumberEditing; >+import org.eclipse.core.databinding.editing.StringEditing; >+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.databinding.validation.IValidator; >+import org.eclipse.core.databinding.validation.ValidationStatus; >+import org.eclipse.core.databinding.validation.constraint.Constraints; >+import org.eclipse.core.databinding.validation.constraint.NumberConstraints; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.jface.databinding.fieldassist.ControlDecorationSupport; >+import org.eclipse.jface.databinding.swt.ISWTObservableValue; >+import org.eclipse.jface.databinding.swt.SWTObservables; >+import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; >+import org.eclipse.jface.examples.databinding.util.EditingFactory; >+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.FocusAdapter; >+import org.eclipse.swt.events.FocusEvent; >+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.Control; >+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.MessageFormat; >+ >+public class Snippet035Editing { >+ >+ private DataBindingContext dbc; >+ >+ public static void main(String[] args) { >+ Display display = new Display(); >+ >+ Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() { >+ public void run() { >+ Shell shell = new Snippet035Editing().createShell(); >+ Display display = Display.getCurrent(); >+ while (!shell.isDisposed()) { >+ if (!display.readAndDispatch()) { >+ display.sleep(); >+ } >+ } >+ } >+ }); >+ } >+ >+ private Shell createShell() { >+ Display display = Display.getCurrent(); >+ Shell shell = new Shell(display); >+ shell.setText("Editing"); >+ shell.setLayout(new GridLayout(1, false)); >+ >+ dbc = new DataBindingContext(); >+ >+ createValueSection(shell); >+ createListSection(shell); >+ >+ shell.pack(); >+ shell.open(); >+ >+ return shell; >+ } >+ >+ private void createValueSection(Composite parent) { >+ Group section = createSectionGroup(parent, "Value bindings", false); >+ >+ // Edit an e-mail address. >+ Text emailText = createTextField(section, "E-Mail*"); >+ StringEditing emailEditing = EditingFactory.forEmailString(); >+ emailEditing.modelConstraints().required(); >+ bindTextField(emailText, new WritableValue(), emailEditing); >+ >+ // Edit a required, positive short using the default validation message. >+ Text positiveText = createTextField(section, "Positive short*"); >+ NumberEditing<Short> positiveEditing = EditingFactory.forShort(); >+ positiveEditing.modelConstraints().required().positive(); >+ bindTextField(positiveText, new WritableValue(), positiveEditing); >+ >+ // Edit a required double with a maximum of five significant and two >+ // fractional digits. >+ Text priceText = createTextField(section, "Price [$]*"); >+ NumberEditing<Double> priceEditing = EditingFactory.forDouble(); >+ priceEditing.modelConstraints().required().maxPrecision(5).maxScale(2); >+ bindTextField(priceText, new WritableValue(), priceEditing); >+ >+ // Edit an integer within the range [1, 100] using the default >+ // validation message. >+ Text rangeText = createTextField(section, "Value in [1, 100]"); >+ NumberEditing<Integer> rangeEditing = EditingFactory.forInteger(); >+ rangeEditing.modelConstraints().range(1, 100); >+ bindTextField(rangeText, new WritableValue(0, null), rangeEditing); >+ >+ // Edit a percentage value which must lie within [0, 100] using a custom >+ // validation message which indicates that the value actually represents >+ // a percentage value. Note that the constraint message must be specified >+ // before the actual constraint. >+ Text percentText = createTextField(section, "Percentage [%]"); >+ NumberEditing<Integer> percentEditing = EditingFactory.forInteger(); >+ percentEditing.modelConstraints() >+ .rangeMessage("Please specify a percentage value within [{0}, {1}].") >+ .range(0, 100); >+ bindTextField(percentText, new WritableValue(-1, null), percentEditing); >+ >+ // Edit a hex integer within the range [0x00, 0xff]. The range validation >+ // message will display the range boundaries in hex format as well. >+ Text hexText = createTextField(section, "Hex value in [0x00, 0xff]"); >+ NumberEditing<Integer> hexEditing = EditingFactory.forHexInteger(2); >+ hexEditing.modelConstraints().range(0x00, 0xff); >+ bindTextField(hexText, new WritableValue(0, null), hexEditing); >+ >+ // Edit a boolean value. >+ Text boolText = createTextField(section, "Boolean value"); >+ BooleanEditing boolEditing = EditingFactory.forBoolean(); >+ bindTextField(boolText, new WritableValue(true, null), boolEditing); >+ >+ // Edit a value within [1, 10] or [20, 30]. >+ Text rangesText = createTextField(section, "Value in [1, 10] or [20, 30]"); >+ NumberEditing<Integer> rangesEditing = EditingFactory.forInteger(); >+ rangesEditing.modelConstraints().addValidator(new RangesValidator(1, 10, 20, 30)); >+ bindTextField(rangesText, new WritableValue(), rangesEditing); >+ } >+ >+ private void createListSection(Composite parent) { >+ Group section = createSectionGroup(parent, "List bindings", true); >+ >+ // Our date should be >= 01.01.1990. >+ Calendar year1990Calendar = Calendar.getInstance(); >+ year1990Calendar.clear(); >+ year1990Calendar.set(1990, 0, 1); >+ Date year1990 = year1990Calendar.getTime(); >+ >+ // Edit a date supporting the default input/display patterns. >+ Text dateText = createTextField(section, "Date"); >+ DateEditing dateEditing = EditingFactory.forDate(); >+ dateEditing.modelConstraints().afterEqual(year1990); >+ final WritableValue dateObservable = new WritableValue(); >+ final Binding dateBinding = bindTextField(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(); >+ dateEditing.bindList(dbc, targetDateList, modelDateList); >+ >+ // 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 Binding bindTextField(Text text, IObservableValue modelValue, Editing editing) { >+ // Create the binding using the editing object. >+ ISWTObservableValue textObservable = SWTObservables.observeText(text, SWT.Modify); >+ Binding binding = editing.bindValue(dbc, textObservable, modelValue); >+ >+ // Decorate the control with the validation status. >+ ControlDecorationSupport.create(binding, SWT.TOP); >+ >+ // Re-format when the text field looses the focus in order to always >+ // display the model in the default format in case multiple input formats >+ // are supported. >+ formatOnFocusOut(text, binding); >+ >+ return binding; >+ } >+ >+ private static void formatOnFocusOut(final Control control, final Binding binding) { >+ control.addFocusListener(new FocusAdapter() { >+ public void focusLost(FocusEvent e) { >+ IStatus dateValidationStatus = (IStatus) binding.getValidationStatus().getValue(); >+ if (dateValidationStatus.isOK()) { >+ binding.updateModelToTarget(); >+ } >+ } >+ }); >+ } >+ >+ private static Group createSectionGroup(Composite parent, String groupText, boolean grabVertical) { >+ Group section = new Group(parent, SWT.SHADOW_ETCHED_IN); >+ 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); >+ >+ final Text text = new Text(parent, SWT.BORDER); >+ GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).applyTo(text); >+ >+ // Select the text when gaining focus. >+ text.addFocusListener(new FocusAdapter() { >+ public void focusGained(FocusEvent e) { >+ text.selectAll(); >+ } >+ }); >+ >+ return text; >+ } >+ >+ private static final class RangesValidator implements IValidator { >+ >+ private final String validationMessage; >+ >+ private final IValidator validator; >+ >+ public RangesValidator(int min1, int max1, int min2, int max2) { >+ this.validationMessage = MessageFormat.format( >+ "The value must lie within [{0}, {1}] or [{2}, {3}].", >+ new Object[] { min1, max1, min2, max2 }); >+ this.validator = >+ new NumberConstraints<Integer>() >+ .range(min1, max1) >+ .range(min2, max2) >+ .aggregationPolicy(Constraints.Aggregation.MIN_SEVERITY) >+ .createValidator(); >+ } >+ >+ public IStatus validate(Object value) { >+ if (!validator.validate(value).isOK()) { >+ return ValidationStatus.error(validationMessage); >+ } >+ return ValidationStatus.ok(); >+ } >+ } >+} >Index: src/org/eclipse/jface/examples/databinding/util/EditingFactory.java >=================================================================== >RCS file: src/org/eclipse/jface/examples/databinding/util/EditingFactory.java >diff -N src/org/eclipse/jface/examples/databinding/util/EditingFactory.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/examples/databinding/util/EditingFactory.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,205 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.jface.examples.databinding.util; >+ >+import java.util.Locale; >+ >+import org.eclipse.core.databinding.editing.BooleanEditing; >+import org.eclipse.core.databinding.editing.DateEditing; >+import org.eclipse.core.databinding.editing.NumberEditing; >+import org.eclipse.core.databinding.editing.StringEditing; >+ >+import com.ibm.icu.text.DateFormat; >+import com.ibm.icu.text.NumberFormat; >+ >+/** >+ * @since 3.2 >+ */ >+public final class EditingFactory { >+ >+ private static final String REQUIRED_MESSAGE = "Please specify a value."; >+ >+ private static final String NUMBER_PARSE_ERROR_MESSAGE = "The input is invalid."; >+ >+ private static final String NUMBER_OUT_OF_RANGE_MESSAGE = "The value lies outside the supported range."; >+ >+ private static final String NUMBER_RANGE_MESSAGE = "The value must lie between {0} and {1}."; >+ >+ private static final String[] BOOLEAN_TRUE_VALUES = new String[] { >+ "yes", "y", "true", "1" >+ }; >+ >+ private static final String[] BOOLEAN_FALSE_VALUES = new String[] { >+ "no", "n", "false", "0" >+ }; >+ >+ private static final String[] DATE_INPUT_PATTERNS = new String[] { >+ "yyMMdd", >+ "yyyyMMdd" >+ }; >+ >+ private static final String DATE_DISPLAY_PATTERN = "yyyyMMdd"; >+ >+ private static final String DATE_PARSE_ERROR_MESSAGE = createDateParseErrorMessage(DATE_INPUT_PATTERNS); >+ >+ private static final String EMAIL_REGEX = "\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}\\b"; >+ >+ private static final String EMAIL_ERROR_MESSAGE = "Please specify a valid e-mail address."; >+ >+ private EditingFactory() { >+ // prevent instantiation >+ } >+ >+ public static StringEditing forString() { >+ return StringEditing.strippedToNull(); >+ } >+ >+ public static StringEditing forEmailString() { >+ StringEditing editing = StringEditing.strippedToNull(); >+ editing.modelConstraints() >+ .matchesMessage(EMAIL_ERROR_MESSAGE) >+ .matches(EMAIL_REGEX); >+ return editing; >+ } >+ >+ public static NumberEditing<Long> forLong() { >+ return forLong(Locale.getDefault()); >+ } >+ >+ public static NumberEditing<Long> forLong(Locale locale) { >+ NumberEditing<Long> editing = NumberEditing.forLongFormat( >+ NumberFormat.getIntegerInstance(locale), >+ NUMBER_PARSE_ERROR_MESSAGE, >+ NUMBER_OUT_OF_RANGE_MESSAGE); >+ configure(editing, locale); >+ return editing; >+ } >+ >+ public static NumberEditing<Integer> forInteger() { >+ return forInteger(Locale.getDefault()); >+ } >+ >+ public static NumberEditing<Integer> forInteger(Locale locale) { >+ NumberEditing<Integer> editing = NumberEditing.forIntegerFormat( >+ NumberFormat.getIntegerInstance(locale), >+ NUMBER_PARSE_ERROR_MESSAGE, >+ NUMBER_OUT_OF_RANGE_MESSAGE); >+ configure(editing, locale); >+ return editing; >+ } >+ >+ public static NumberEditing<Short> forShort() { >+ return forShort(Locale.getDefault()); >+ } >+ >+ public static NumberEditing<Short> forShort(Locale locale) { >+ NumberEditing<Short> editing = NumberEditing.forShortFormat( >+ NumberFormat.getIntegerInstance(locale), >+ NUMBER_PARSE_ERROR_MESSAGE, >+ NUMBER_OUT_OF_RANGE_MESSAGE); >+ configure(editing, locale); >+ return editing; >+ } >+ >+ public static NumberEditing<Byte> forByte() { >+ return forByte(Locale.getDefault()); >+ } >+ >+ public static NumberEditing<Byte> forByte(Locale locale) { >+ NumberEditing<Byte> editing = NumberEditing.forByteFormat( >+ NumberFormat.getIntegerInstance(locale), >+ NUMBER_PARSE_ERROR_MESSAGE, >+ NUMBER_OUT_OF_RANGE_MESSAGE); >+ configure(editing, locale); >+ return editing; >+ } >+ >+ public static NumberEditing<Integer> forHexInteger(int digits) { >+ RadixNumberFormat hexFormat = RadixNumberFormat.getHexInstance("0x", digits); >+ NumberEditing<Integer> editing = NumberEditing.forIntegerFormat( >+ hexFormat, >+ NUMBER_PARSE_ERROR_MESSAGE, >+ NUMBER_OUT_OF_RANGE_MESSAGE); >+ configure(editing, Locale.getDefault()); >+ editing.modelConstraints().numberFormat(hexFormat); >+ return editing; >+ } >+ >+ public static NumberEditing<Double> forDouble() { >+ return forDouble(Locale.getDefault()); >+ } >+ >+ public static NumberEditing<Double> forDouble(Locale locale) { >+ NumberEditing<Double> editing = NumberEditing.forDoubleFormat( >+ NumberFormat.getNumberInstance(locale), >+ NUMBER_PARSE_ERROR_MESSAGE, >+ NUMBER_OUT_OF_RANGE_MESSAGE); >+ configure(editing, locale); >+ return editing; >+ } >+ >+ private static void configure(NumberEditing<?> editing, Locale locale) { >+ editing.modelConstraints() >+ .numberFormat(NumberFormat.getNumberInstance(locale)) >+ .scaleFormat(NumberFormat.getIntegerInstance(locale)) >+ .precisionFormat(NumberFormat.getIntegerInstance(locale)) >+ .requiredMessage(REQUIRED_MESSAGE) >+ .rangeMessage(NUMBER_RANGE_MESSAGE); >+ } >+ >+ public static BooleanEditing forBoolean() { >+ BooleanEditing editing = >+ BooleanEditing.forStringValues( >+ BOOLEAN_TRUE_VALUES, >+ BOOLEAN_FALSE_VALUES); >+ configure(editing); >+ return editing; >+ } >+ >+ private static void configure(BooleanEditing editing) { >+ editing.modelConstraints().requiredMessage(REQUIRED_MESSAGE); >+ } >+ >+ public static DateEditing forDate() { >+ return forDate(Locale.getDefault()); >+ } >+ >+ public static DateEditing forDate(Locale locale) { >+ DateEditing editing = DateEditing >+ .forFormats( >+ createDateFormats(DATE_INPUT_PATTERNS, locale), >+ DATE_PARSE_ERROR_MESSAGE, >+ DateFormat.getPatternInstance(DATE_DISPLAY_PATTERN, locale)); >+ editing.modelConstraints().requiredMessage(REQUIRED_MESSAGE); >+ return editing; >+ } >+ >+ private static DateFormat[] createDateFormats(String[] datePatterns, Locale locale) { >+ DateFormat[] dateFormats = new DateFormat[datePatterns.length]; >+ for (int i = 0; i < dateFormats.length; i++) { >+ dateFormats[i] = DateFormat.getPatternInstance(datePatterns[i], locale); >+ } >+ 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(); >+ } >+} >Index: src/org/eclipse/jface/examples/databinding/util/RadixNumberFormat.java >=================================================================== >RCS file: src/org/eclipse/jface/examples/databinding/util/RadixNumberFormat.java >diff -N src/org/eclipse/jface/examples/databinding/util/RadixNumberFormat.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/examples/databinding/util/RadixNumberFormat.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,99 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.jface.examples.databinding.util; >+ >+import java.math.BigInteger; >+import java.text.FieldPosition; >+import java.text.ParsePosition; >+ >+import com.ibm.icu.math.BigDecimal; >+import com.ibm.icu.text.NumberFormat; >+ >+/** >+ * @since 3.2 >+ * >+ */ >+public class RadixNumberFormat extends NumberFormat { >+ >+ private static final long serialVersionUID = 411884077848863891L; >+ >+ private final int radix; >+ >+ private final String prefix; >+ >+ private final int digits; >+ >+ private RadixNumberFormat(int radix, String prefix, int digits) { >+ this.radix = radix; >+ this.prefix = prefix != null ? prefix : ""; >+ this.digits = digits; >+ } >+ >+ public static RadixNumberFormat getHexInstance() { >+ return getHexInstance(null, 0); >+ } >+ >+ public static RadixNumberFormat getHexInstance(String prefix, int digits) { >+ return new RadixNumberFormat(16, prefix, digits); >+ } >+ >+ public StringBuffer format(double number, StringBuffer toAppendTo, >+ FieldPosition pos) { >+ return format((long) number, toAppendTo, pos); >+ } >+ >+ public StringBuffer format(long number, StringBuffer toAppendTo, >+ FieldPosition pos) { >+ return toAppendTo.append(prefix).append(addPadding(Long.toString(number, radix))); >+ } >+ >+ public StringBuffer format(BigInteger number, StringBuffer toAppendTo, >+ FieldPosition pos) { >+ return toAppendTo.append(prefix).append(addPadding(number.toString(radix))); >+ } >+ >+ public StringBuffer format(BigDecimal number, StringBuffer toAppendTo, >+ FieldPosition pos) { >+ throw new UnsupportedOperationException(); >+ } >+ >+ public Number parse(String text, ParsePosition parsePosition) { >+ if (text.length() == 0) { >+ return null; >+ } >+ >+ parsePosition.setIndex(parsePosition.getIndex() + text.length()); >+ >+ try { >+ if (text.startsWith(prefix)) { >+ return Integer.parseInt(text.substring(prefix.length()), radix); >+ } >+ return Integer.parseInt(text, radix); >+ } catch (NumberFormatException e) { >+ parsePosition.setErrorIndex(0); >+ return null; >+ } >+ } >+ >+ private String addPadding(String numberText) { >+ if (numberText.length() >= digits) { >+ return numberText; >+ } >+ >+ StringBuffer sb = new StringBuffer(); >+ for (int i = numberText.length(); i < digits; i++) { >+ sb.append('0'); >+ } >+ sb.append(numberText); >+ return sb.toString(); >+ } >+} >Index: src/org/eclipse/jface/examples/databinding/util/ObservableMapEditingCellLabelProvider.java >=================================================================== >RCS file: src/org/eclipse/jface/examples/databinding/util/ObservableMapEditingCellLabelProvider.java >diff -N src/org/eclipse/jface/examples/databinding/util/ObservableMapEditingCellLabelProvider.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/examples/databinding/util/ObservableMapEditingCellLabelProvider.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,40 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.jface.examples.databinding.util; >+ >+import org.eclipse.core.databinding.editing.Editing; >+import org.eclipse.core.databinding.observable.map.IObservableMap; >+import org.eclipse.jface.databinding.viewers.ObservableMapCellLabelProvider; >+import org.eclipse.jface.viewers.ViewerCell; >+ >+/** >+ * @since 3.2 >+ */ >+public class ObservableMapEditingCellLabelProvider extends >+ ObservableMapCellLabelProvider { >+ >+ private final IObservableMap attributeMap; >+ >+ private final Editing editing; >+ >+ public ObservableMapEditingCellLabelProvider(IObservableMap attributeMap, Editing editing) { >+ super(attributeMap); >+ this.attributeMap = attributeMap; >+ this.editing = editing; >+ } >+ >+ public void update(ViewerCell cell) { >+ Object element = cell.getElement(); >+ Object attribute = attributeMap.get(element); >+ cell.setText((String) editing.convertToTarget(attribute)); >+ } >+} >Index: src/org/eclipse/jface/examples/databinding/snippets/Snippet036EditingTable.java >=================================================================== >RCS file: src/org/eclipse/jface/examples/databinding/snippets/Snippet036EditingTable.java >diff -N src/org/eclipse/jface/examples/databinding/snippets/Snippet036EditingTable.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/examples/databinding/snippets/Snippet036EditingTable.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,261 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+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.beans.BeansObservables; >+import org.eclipse.core.databinding.editing.DateEditing; >+import org.eclipse.core.databinding.editing.Editing; >+import org.eclipse.core.databinding.editing.NumberEditing; >+import org.eclipse.core.databinding.editing.StringEditing; >+import org.eclipse.core.databinding.observable.Realm; >+import org.eclipse.core.databinding.observable.list.WritableList; >+import org.eclipse.core.databinding.observable.map.IObservableMap; >+import org.eclipse.core.databinding.observable.set.IObservableSet; >+import org.eclipse.core.databinding.observable.value.IObservableValue; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.jface.databinding.fieldassist.ControlDecorationSupport; >+import org.eclipse.jface.databinding.swt.ISWTObservableValue; >+import org.eclipse.jface.databinding.swt.SWTObservables; >+import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; >+import org.eclipse.jface.databinding.viewers.ViewersObservables; >+import org.eclipse.jface.examples.databinding.ModelObject; >+import org.eclipse.jface.examples.databinding.util.EditingFactory; >+import org.eclipse.jface.examples.databinding.util.ObservableMapEditingCellLabelProvider; >+import org.eclipse.jface.examples.databinding.util.ObservableMapEditingSupport; >+import org.eclipse.jface.layout.GridDataFactory; >+import org.eclipse.jface.layout.GridLayoutFactory; >+import org.eclipse.jface.viewers.StructuredSelection; >+import org.eclipse.jface.viewers.TableViewer; >+import org.eclipse.jface.viewers.TableViewerColumn; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.events.FocusAdapter; >+import org.eclipse.swt.events.FocusEvent; >+import org.eclipse.swt.layout.GridLayout; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Control; >+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; >+ >+public class Snippet036EditingTable { >+ >+ private StringEditing nameEditing; >+ >+ private NumberEditing<Integer> ageEditing; >+ >+ private DateEditing bdayEditing; >+ >+ private DataBindingContext dbc; >+ >+ private TableViewer tableViewer; >+ >+ public static void main(String[] args) { >+ Display display = new Display(); >+ >+ Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() { >+ public void run() { >+ Shell shell = new Snippet036EditingTable().createShell(); >+ Display display = Display.getCurrent(); >+ while (!shell.isDisposed()) { >+ if (!display.readAndDispatch()) { >+ display.sleep(); >+ } >+ } >+ } >+ }); >+ } >+ >+ private Shell createShell() { >+ Display display = Display.getCurrent(); >+ Shell shell = new Shell(display); >+ shell.setText("Editing"); >+ shell.setLayout(new GridLayout(2, false)); >+ >+ nameEditing = EditingFactory.forString(); >+ nameEditing.modelConstraints().required(); >+ >+ ageEditing = EditingFactory.forInteger(); >+ ageEditing.modelConstraints().required().nonNegative(); >+ >+ bdayEditing = EditingFactory.forDate(); >+ bdayEditing.modelConstraints().before(new Date()); >+ >+ dbc = new DataBindingContext(); >+ >+ createTableSection(shell); >+ createFieldSection(shell); >+ >+ shell.pack(); >+ shell.open(); >+ >+ return shell; >+ } >+ >+ private void createTableSection(Composite parent) { >+ Group section = createSectionGroup(parent, 1); >+ >+ tableViewer = new TableViewer(section, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION); >+ GridDataFactory.fillDefaults().grab(true, true).hint(350, 250).applyTo(tableViewer.getTable()); >+ tableViewer.getTable().setHeaderVisible(true); >+ tableViewer.getTable().setLinesVisible(true); >+ >+ ObservableListContentProvider contentProvider = new ObservableListContentProvider(); >+ tableViewer.setContentProvider(contentProvider); >+ IObservableSet contentElements = contentProvider.getKnownElements(); >+ >+ IObservableMap nameMap = BeansObservables.observeMap(contentElements, "name"); >+ createColumn("Name*", 150, nameMap, nameEditing); >+ >+ IObservableMap ageMap = BeansObservables.observeMap(contentElements, "age"); >+ createColumn("Age*", 50, ageMap, ageEditing); >+ >+ IObservableMap bdayMap = BeansObservables.observeMap(contentElements, "birthday"); >+ createColumn("Birthday", 80, bdayMap, bdayEditing); >+ >+ WritableList people = new WritableList(); >+ people.add(new Person("John Doe", 27)); >+ people.add(new Person("Steve Northover", 33)); >+ people.add(new Person("Grant Gayed", 54)); >+ people.add(new Person("Veronika Irvine", 25)); >+ people.add(new Person("Mike Wilson", 44)); >+ people.add(new Person("Christophe Cornu", 37)); >+ people.add(new Person("Lynne Kues", 65)); >+ people.add(new Person("Silenio Quarti", 15)); >+ >+ tableViewer.setInput(people); >+ >+ tableViewer.setSelection(new StructuredSelection(people.get(0))); >+ } >+ >+ private TableViewerColumn createColumn(String text, int width, IObservableMap attributeMap, Editing modelEditing) { >+ TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE); >+ column.getColumn().setText(text); >+ column.getColumn().setWidth(width); >+ column.setLabelProvider(new ObservableMapEditingCellLabelProvider(attributeMap, modelEditing)); >+ column.setEditingSupport(new ObservableMapEditingSupport(tableViewer, attributeMap, modelEditing)); >+ return column; >+ } >+ >+ private void createFieldSection(Composite parent) { >+ final Group section = createSectionGroup(parent, 2); >+ >+ final IObservableValue personObservable = ViewersObservables.observeSingleSelection(tableViewer); >+ >+ Text nameText = createTextField(section, "Name*"); >+ IObservableValue nameObservable = BeansObservables.observeDetailValue(personObservable, "name", null); >+ bindTextField(nameText, nameObservable, nameEditing); >+ >+ Text ageText = createTextField(section, "Age*"); >+ IObservableValue ageObservable = BeansObservables.observeDetailValue(personObservable, "age", null); >+ bindTextField(ageText, ageObservable, ageEditing); >+ >+ Text bdayText = createTextField(section, "Birthday"); >+ IObservableValue bdayObservable = BeansObservables.observeDetailValue(personObservable, "birthday", null); >+ bindTextField(bdayText, bdayObservable, bdayEditing); >+ } >+ >+ private Binding bindTextField( >+ Text text, >+ IObservableValue modelValue, >+ Editing editing) { >+ // Create the binding using the editing object. >+ ISWTObservableValue textObservable = SWTObservables.observeText(text, SWT.Modify); >+ Binding binding = editing.bindValue(dbc, textObservable, modelValue); >+ >+ // Decorate the control with the validation status. >+ ControlDecorationSupport.create(binding, SWT.TOP); >+ >+ formatOnFocusOut(text, binding); >+ >+ return binding; >+ } >+ >+ private static void formatOnFocusOut(final Control control, final Binding binding) { >+ control.addFocusListener(new FocusAdapter() { >+ public void focusLost(FocusEvent e) { >+ IStatus dateValidationStatus = (IStatus) binding.getValidationStatus().getValue(); >+ if (dateValidationStatus.isOK()) { >+ binding.updateModelToTarget(); >+ } >+ } >+ }); >+ } >+ >+ private Group createSectionGroup(Composite parent, int numColumns) { >+ Group section = new Group(parent, SWT.SHADOW_ETCHED_IN); >+ GridLayoutFactory.fillDefaults().numColumns(numColumns).equalWidth(false).margins(5, 5).spacing(15, 5).applyTo(section); >+ GridDataFactory.fillDefaults().grab(true, true).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); >+ >+ final Text text = new Text(parent, SWT.BORDER); >+ GridDataFactory.fillDefaults().grab(true, false).hint(200, SWT.DEFAULT).applyTo(text); >+ >+ // Select the text when gaining focus. >+ text.addFocusListener(new FocusAdapter() { >+ public void focusGained(FocusEvent e) { >+ text.selectAll(); >+ } >+ }); >+ >+ return text; >+ } >+ >+ public static final class Person extends ModelObject { >+ >+ private String name; >+ >+ private int age; >+ >+ private Date birthday; >+ >+ public Person(String name, int age) { >+ this.name = name; >+ this.age = age; >+ } >+ >+ public String getName() { >+ return name; >+ } >+ >+ public void setName(String name) { >+ firePropertyChange("name", this.name, this.name = name); >+ } >+ >+ public int getAge() { >+ return age; >+ } >+ >+ public void setAge(int age) { >+ firePropertyChange("age", this.age, this.age = age); >+ } >+ >+ public Date getBirthday() { >+ return birthday; >+ } >+ >+ public void setBirthday(Date birthday) { >+ firePropertyChange("birthday", this.birthday, this.birthday = birthday); >+ } >+ } >+} >#P org.eclipse.core.databinding >Index: .classpath >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/.classpath,v >retrieving revision 1.3 >diff -u -r1.3 .classpath >--- .classpath 3 Apr 2008 17:15:42 -0000 1.3 >+++ .classpath 28 Feb 2010 23:33:36 -0000 >@@ -1,6 +1,6 @@ > <?xml version="1.0" encoding="UTF-8"?> > <classpath> >- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/CDC-1.1%Foundation-1.1"/> >+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> > <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> > <classpathentry kind="src" path="src"/> > <classpathentry kind="output" path="bin"/> >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.7 >diff -u -r1.7 StringToNumberParser.java >--- src/org/eclipse/core/internal/databinding/conversion/StringToNumberParser.java 22 Jan 2010 21:54:48 -0000 1.7 >+++ src/org/eclipse/core/internal/databinding/conversion/StringToNumberParser.java 28 Feb 2010 23:33:37 -0000 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Ovidio Mallo - bug 183055 > *******************************************************************************/ > > package org.eclipse.core.internal.databinding.conversion; >@@ -115,12 +116,12 @@ > .getErrorIndex() : position.getIndex(); > > if (errorIndex < value.length()) { >- return BindingMessages.formatString( >+ return BindingMessages.getFormattedString( > BindingMessages.VALIDATE_NUMBER_PARSE_ERROR, new Object[] { > value, new Integer(errorIndex + 1), > new Character(value.charAt(errorIndex)) }); > } >- return BindingMessages.formatString( >+ return BindingMessages.getFormattedString( > BindingMessages.VALIDATE_NUMBER_PARSE_ERROR_NO_CHARACTER, > new Object[] { value, new Integer(errorIndex + 1) }); > } >@@ -136,6 +137,23 @@ > */ > public static String createOutOfRangeMessage(Number minValue, > Number maxValue, NumberFormat numberFormat) { >+ return createOutOfRangeMessage(BindingMessages >+ .getString(BindingMessages.VALIDATE_NUMBER_OUT_OF_RANGE_ERROR), >+ minValue, maxValue, numberFormat); >+ } >+ >+ /** >+ * 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; > >@@ -144,8 +162,8 @@ > max = numberFormat.format(maxValue); > } > >- return BindingMessages.formatString( >- "Validate_NumberOutOfRangeError", new Object[] { min, max }); //$NON-NLS-1$ >+ return BindingMessages >+ .formatMessage(message, new Object[] { min, max }); > } > > /** >Index: src/org/eclipse/core/internal/databinding/conversion/StringToBooleanPrimitiveConverter.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/conversion/StringToBooleanPrimitiveConverter.java,v >retrieving revision 1.4 >diff -u -r1.4 StringToBooleanPrimitiveConverter.java >--- src/org/eclipse/core/internal/databinding/conversion/StringToBooleanPrimitiveConverter.java 25 May 2009 20:52:20 -0000 1.4 >+++ src/org/eclipse/core/internal/databinding/conversion/StringToBooleanPrimitiveConverter.java 28 Feb 2010 23:33:37 -0000 >@@ -9,6 +9,7 @@ > * Contributors: > * db4objects - Initial API and implementation > * Tom Schindl<tom.schindl@bestsolution.at> - bugfix for 217940 >+ * Ovidio Mallo - bug 183055 > */ > package org.eclipse.core.internal.databinding.conversion; > >@@ -24,19 +25,22 @@ > * StringToBooleanPrimitiveConverter. > */ > public class StringToBooleanPrimitiveConverter implements IConverter { >- private static final String[] trueValues; > >- private static final String[] falseValues; >+ private static final String[] DEFAULT_TRUE_VALUES; >+ private static final String[] DEFAULT_FALSE_VALUES; > > static { > String delimiter = BindingMessages.getString(BindingMessages.VALUE_DELIMITER); > String values = BindingMessages.getString(BindingMessages.TRUE_STRING_VALUES); >- trueValues = valuesToSortedArray(delimiter, values); >+ DEFAULT_TRUE_VALUES = valuesToSortedArray(delimiter, values); > > values = BindingMessages.getString(BindingMessages.FALSE_STRING_VALUES); >- falseValues = valuesToSortedArray(delimiter, values); >+ DEFAULT_FALSE_VALUES = valuesToSortedArray(delimiter, values); > } > >+ private String[] trueValues = DEFAULT_TRUE_VALUES; >+ private String[] falseValues = DEFAULT_FALSE_VALUES; >+ > /** > * Returns a sorted array with all values converted to upper case. > * >@@ -57,6 +61,33 @@ > return array; > } > >+ /** >+ * Sets the string values which are considered to represent a >+ * <code>true</code> and <code>false</code> value, respectively. >+ * >+ * <p> >+ * Note that the capitalization of the provided strings is ignored. >+ * </p> >+ * >+ * @param trueValues >+ * The set of strings representing a <code>true</code> value. >+ * @param falseValues >+ * The set of strings representing a <code>false</code> value. >+ */ >+ public final void setSourceStrings(String[] trueValues, String[] falseValues) { >+ this.trueValues = new String[trueValues.length]; >+ for (int i = 0; i < trueValues.length; i++) { >+ this.trueValues[i] = trueValues[i].toUpperCase(); >+ } >+ Arrays.sort(this.trueValues); // for binary search >+ >+ this.falseValues = new String[falseValues.length]; >+ for (int i = 0; i < falseValues.length; i++) { >+ this.falseValues[i] = falseValues[i].toUpperCase(); >+ } >+ Arrays.sort(this.falseValues); // for binary search >+ } >+ > /* > * (non-Javadoc) > * >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 28 Feb 2010 23:33:37 -0000 >@@ -10,6 +10,7 @@ > * db4objects - Initial API and implementation > * Tom Schindl<tom.schindl@bestsolution.at> - bugfix for 217940 > * Matthew Hall - bug 121110 >+ * Ovidio Mallo - bug 183055 > ******************************************************************************/ > package org.eclipse.core.internal.databinding.conversion; > >@@ -52,6 +53,20 @@ > }; > > /** >+ * Sets the {@link DateFormat}s to be used for parsing/formatting dates. Any >+ * of the supplied formats will be used for {@link #parse(String) parsing} a >+ * date from a string while the first format in the array will be used for >+ * {@link #format(Date) formatting} a date as a string. >+ * >+ * @param formatters >+ * The {@link DateFormat}s to be used for parsing/formatting >+ * dates. >+ */ >+ public final void setFormatters(DateFormat[] formatters) { >+ this.formatters = formatters; >+ } >+ >+ /** > * 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. >Index: src/org/eclipse/core/internal/databinding/validation/StringToCharacterValidator.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/validation/StringToCharacterValidator.java,v >retrieving revision 1.3 >diff -u -r1.3 StringToCharacterValidator.java >--- src/org/eclipse/core/internal/databinding/validation/StringToCharacterValidator.java 25 May 2009 20:52:19 -0000 1.3 >+++ src/org/eclipse/core/internal/databinding/validation/StringToCharacterValidator.java 28 Feb 2010 23:33:37 -0000 >@@ -8,6 +8,7 @@ > * Contributors: > * Matt Carter - initial API and implementation > * Tom Schindl<tom.schindl@bestsolution.at> - bugfix for 217940 >+ * Ovidio Mallo - bug 183055 > ******************************************************************************/ > > package org.eclipse.core.internal.databinding.validation; >@@ -26,6 +27,8 @@ > > private final StringToCharacterConverter converter; > >+ private String parseErrorMessage = BindingMessages.getString(BindingMessages.VALIDATE_CHARACTER_HELP); >+ > /** > * @param converter > */ >@@ -33,6 +36,18 @@ > this.converter = converter; > } > >+ /** >+ * Sets the validation message to be used in case the source string does not >+ * represent a valid character. >+ * >+ * @param message >+ * The validation message to be used in case the source string >+ * does not represent a valid character. >+ */ >+ public final void setParseErrorMessage(String message) { >+ this.parseErrorMessage = message; >+ } >+ > /* > * (non-Javadoc) > * >@@ -44,10 +59,8 @@ > } catch (IllegalArgumentException e) { > // The StringToCharacterConverter throws an IllegalArgumentException > // if it cannot convert. >- return ValidationStatus.error(BindingMessages >- .getString(BindingMessages.VALIDATE_CHARACTER_HELP)); >+ return ValidationStatus.error(parseErrorMessage); > } > return Status.OK_STATUS; > } >- > } >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 28 Feb 2010 23:33:37 -0000 >@@ -8,6 +8,7 @@ > * Contributors: > * IBM Corporation - initial API and implementation > * Tom Schindl<tom.schindl@bestsolution.at> - bugfix for 217940 >+ * Ovidio Mallo - bug 183055 > *******************************************************************************/ > > package org.eclipse.core.internal.databinding.validation; >@@ -28,6 +29,8 @@ > public class StringToDateValidator implements IValidator { > private final StringToDateConverter converter; > >+ private String parseErrorMessage = null; >+ > /** > * @param converter > */ >@@ -35,6 +38,18 @@ > this.converter = converter; > } > >+ /** >+ * Sets the validation message to be used in case the source string does not >+ * represent a valid date. >+ * >+ * @param message >+ * The validation message to be used in case the source string >+ * does not represent a valid date. >+ */ >+ public final void setParseErrorMessage(String message) { >+ this.parseErrorMessage = message; >+ } >+ > /* > * (non-Javadoc) > * >@@ -47,18 +62,17 @@ > Object convertedValue = converter.convert(value); > //The StringToDateConverter returns null if it can't parse the date. > if (convertedValue == null) { >- return ValidationStatus.error(getErrorMessage()); >+ return ValidationStatus.error(getParseErrorMessage()); > } > > return Status.OK_STATUS; > } > >- /* >- * (non-Javadoc) >- * >- * @see org.eclipse.core.internal.databinding.validation.WrappedConverterValidator#getErrorMessage() >- */ >- protected String getErrorMessage() { >+ private String getParseErrorMessage() { >+ if (parseErrorMessage != null) { >+ return parseErrorMessage; >+ } >+ > Date sampleDate = new Date(); > > // FIXME We need to use the information from the >@@ -73,7 +87,9 @@ > samples.append('\''); > samples.append(util.format(sampleDate, 0)); > samples.append('\''); >- return BindingMessages.getString(BindingMessages.EXAMPLES) + ": " + samples + ",..."; //$NON-NLS-1$//$NON-NLS-2$ >+ parseErrorMessage = BindingMessages.getString(BindingMessages.EXAMPLES) + ": " + samples + ",..."; //$NON-NLS-1$//$NON-NLS-2$ >+ >+ return parseErrorMessage; > } > > private static class FormatUtil extends DateConversionSupport { >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 28 Feb 2010 23:33:37 -0000 >@@ -7,12 +7,16 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Ovidio Mallo - bug 183055 > ******************************************************************************/ > > 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.BindingMessages; > import org.eclipse.core.internal.databinding.conversion.StringToNumberParser; > import org.eclipse.core.internal.databinding.conversion.StringToNumberParser.ParseResult; > import org.eclipse.core.runtime.IStatus; >@@ -31,7 +35,10 @@ > private final Number min; > private final Number max; > >- private String outOfRangeMessage; >+ private String parseErrorMessage; >+ >+ private String outOfRangeMessage = BindingMessages.getString(BindingMessages.VALIDATE_NUMBER_OUT_OF_RANGE_ERROR); >+ private String formattedOutOfRangeMessage; > > /** > * Constructs a new instance. >@@ -55,6 +62,34 @@ > } > > /** >+ * Sets the validation message pattern to be used in case the source string >+ * does not represent a valid number. >+ * >+ * @param message >+ * The validation message pattern to be used in case the source >+ * string does not represent a valid number. >+ */ >+ public final void setParseErrorMessage(String message) { >+ this.parseErrorMessage = message; >+ } >+ >+ /** >+ * Sets the validation message pattern to be used in case the parsed number >+ * lies outside the value range supported by the number type associated to >+ * this validator. >+ * >+ * @param message >+ * The validation message pattern to be used in case the parsed >+ * number lies outside the supported value range. Can be >+ * parameterized by the <code>Integer.MIN_VALUE</code> and >+ * <code>Integer.MAX_VALUE</code> values. >+ */ >+ public final void setOutOfRangeMessage(String message) { >+ this.outOfRangeMessage = message; >+ this.formattedOutOfRangeMessage = null; >+ } >+ >+ /** > * Validates the provided <code>value</code>. An error status is returned if: > * <ul> > * <li>The value cannot be parsed.</li> >@@ -69,16 +104,10 @@ > > if (result.getNumber() != null) { > if (!isInRange(result.getNumber())) { >- if (outOfRangeMessage == null) { >- outOfRangeMessage = StringToNumberParser >- .createOutOfRangeMessage(min, max, converter >- .getNumberFormat()); >- } >- >- return ValidationStatus.error(outOfRangeMessage); >+ return ValidationStatus.error(getFormattedOutOfRangeMessage()); > } > } else if (result.getPosition() != null) { >- String parseErrorMessage = StringToNumberParser.createParseErrorMessage( >+ String parseErrorMessage = createParseErrorMessage( > (String) value, result.getPosition()); > > return ValidationStatus.error(parseErrorMessage); >@@ -94,4 +123,22 @@ > * @return <code>true</code> 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 getFormattedOutOfRangeMessage() { >+ if (formattedOutOfRangeMessage == null) { >+ formattedOutOfRangeMessage = StringToNumberParser >+ .createOutOfRangeMessage(outOfRangeMessage, min, max, >+ converter.getNumberFormat()); >+ } >+ return formattedOutOfRangeMessage; >+ } > } >Index: META-INF/MANIFEST.MF >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/META-INF/MANIFEST.MF,v >retrieving revision 1.21 >diff -u -r1.21 MANIFEST.MF >--- META-INF/MANIFEST.MF 25 Aug 2009 04:57:27 -0000 1.21 >+++ META-INF/MANIFEST.MF 28 Feb 2010 23:33:36 -0000 >@@ -8,7 +8,9 @@ > 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.databinding.validation.constraint, > 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", > org.eclipse.core.internal.databinding.validation;x-friends:="org.eclipse.jface.tests.databinding" >@@ -22,6 +24,6 @@ > org.osgi.util.tracker;version="[1.3.3,2.0.0)";resolution:=optional, > org.eclipse.osgi.framework.log;version="[1.0.0,2.0.0)";resolution:=optional > Bundle-RequiredExecutionEnvironment: CDC-1.1/Foundation-1.1, >- J2SE-1.4 >+ J2SE-1.5 > Bundle-Activator: org.eclipse.core.internal.databinding.Activator > Bundle-ActivationPolicy: lazy >Index: .settings/org.eclipse.jdt.core.prefs >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/.settings/org.eclipse.jdt.core.prefs,v >retrieving revision 1.6 >diff -u -r1.6 org.eclipse.jdt.core.prefs >--- .settings/org.eclipse.jdt.core.prefs 5 Feb 2009 18:51:11 -0000 1.6 >+++ .settings/org.eclipse.jdt.core.prefs 28 Feb 2010 23:33:36 -0000 >@@ -1,4 +1,4 @@ >-#Thu Feb 05 11:35:38 MST 2009 >+#Sun Feb 28 19:30:40 CET 2010 > eclipse.preferences.version=1 > org.eclipse.jdt.core.builder.cleanOutputFolder=clean > org.eclipse.jdt.core.builder.duplicateResourceTask=warning >@@ -17,9 +17,9 @@ > org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= > org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= > org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled >-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2 >+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 > org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve >-org.eclipse.jdt.core.compiler.compliance=1.4 >+org.eclipse.jdt.core.compiler.compliance=1.5 > org.eclipse.jdt.core.compiler.debug.lineNumber=generate > org.eclipse.jdt.core.compiler.debug.localVariable=generate > org.eclipse.jdt.core.compiler.debug.sourceFile=generate >@@ -96,7 +96,7 @@ > org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error > org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning > org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning >-org.eclipse.jdt.core.compiler.source=1.3 >+org.eclipse.jdt.core.compiler.source=1.5 > org.eclipse.jdt.core.formatter.align_type_members_on_columns=false > org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 > org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 >Index: .settings/org.eclipse.jdt.ui.prefs >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/.settings/org.eclipse.jdt.ui.prefs,v >retrieving revision 1.3 >diff -u -r1.3 org.eclipse.jdt.ui.prefs >--- .settings/org.eclipse.jdt.ui.prefs 16 Feb 2009 23:03:21 -0000 1.3 >+++ .settings/org.eclipse.jdt.ui.prefs 28 Feb 2010 23:33:36 -0000 >@@ -1,4 +1,4 @@ >-#Tue Feb 10 16:05:48 MST 2009 >+#Thu Jan 07 19:10:54 CET 2010 > cleanup.add_default_serial_version_id=true > cleanup.add_generated_serial_version_id=false > cleanup.add_missing_annotations=true >@@ -51,7 +51,7 @@ > cleanup_profile=org.eclipse.jdt.ui.default.eclipse_clean_up_profile > cleanup_settings_version=2 > eclipse.preferences.version=1 >-editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true >+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=false > formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile > formatter_settings_version=11 > org.eclipse.jdt.ui.exception.name=e >@@ -78,7 +78,7 @@ > sp_cleanup.always_use_this_for_non_static_method_access=false > sp_cleanup.convert_to_enhanced_for_loop=false > sp_cleanup.correct_indentation=false >-sp_cleanup.format_source_code=true >+sp_cleanup.format_source_code=false > sp_cleanup.format_source_code_changes_only=false > sp_cleanup.make_local_variable_final=false > sp_cleanup.make_parameters_final=false >Index: src/org/eclipse/core/databinding/UpdateStrategy.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/src/org/eclipse/core/databinding/UpdateStrategy.java,v >retrieving revision 1.17 >diff -u -r1.17 UpdateStrategy.java >--- src/org/eclipse/core/databinding/UpdateStrategy.java 25 May 2009 20:52:19 -0000 1.17 >+++ src/org/eclipse/core/databinding/UpdateStrategy.java 28 Feb 2010 23:33:37 -0000 >@@ -9,6 +9,7 @@ > * IBM Corporation - initial API and implementation > * Matt Carter - bug 180392 > * - bug 197679 (Character support completed) >+ * Ovidio Mallo - bug 183055 > *******************************************************************************/ > > package org.eclipse.core.databinding; >@@ -24,6 +25,7 @@ > import org.eclipse.core.databinding.util.Policy; > import org.eclipse.core.internal.databinding.ClassLookupSupport; > import org.eclipse.core.internal.databinding.Pair; >+import org.eclipse.core.internal.databinding.conversion.BooleanToStringConverter; > import org.eclipse.core.internal.databinding.conversion.CharacterToStringConverter; > import org.eclipse.core.internal.databinding.conversion.IdentityConverter; > import org.eclipse.core.internal.databinding.conversion.IntegerToStringConverter; >@@ -35,7 +37,6 @@ > import org.eclipse.core.internal.databinding.conversion.NumberToIntegerConverter; > import org.eclipse.core.internal.databinding.conversion.NumberToLongConverter; > import org.eclipse.core.internal.databinding.conversion.NumberToShortConverter; >-import org.eclipse.core.internal.databinding.conversion.ObjectToStringConverter; > import org.eclipse.core.internal.databinding.conversion.StringToByteConverter; > import org.eclipse.core.internal.databinding.conversion.StringToCharacterConverter; > import org.eclipse.core.internal.databinding.conversion.StringToShortConverter; >@@ -307,7 +308,7 @@ > new Pair(BOOLEAN_CLASS, "java.lang.Boolean"), new IdentityConverter(Boolean.class, Boolean.class)); //$NON-NLS-1$ > converterMap > .put( >- new Pair(BOOLEAN_CLASS, "java.lang.String"), new ObjectToStringConverter(Boolean.class)); //$NON-NLS-1$ >+ new Pair(BOOLEAN_CLASS, "java.lang.String"), new BooleanToStringConverter(Boolean.class)); //$NON-NLS-1$ > converterMap > .put( > new Pair(BOOLEAN_CLASS, "java.lang.Object"), new IdentityConverter(Boolean.class, Object.class)); //$NON-NLS-1$ >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 28 Feb 2010 23:33:37 -0000 >@@ -8,6 +8,7 @@ > * Contributors: > * IBM Corporation - initial API and implementation > * Tom Schindl<tom.schindl@bestsolution.at> - bugfix for 217940 >+ * Ovidio Mallo - bug 183055 > *******************************************************************************/ > package org.eclipse.core.internal.databinding; > >@@ -69,6 +70,11 @@ > public static final String FALSE_STRING_VALUES = "FalseStringValues"; //$NON-NLS-1$ > > /** >+ * Key to be used for a "Validate_InvalidBooleanString" message >+ */ >+ public static final String VALIDATE_INVALID_BOOLEAN_STRING = "Validate_InvalidBooleanString"; //$NON-NLS-1$ >+ >+ /** > * Key to be used for a "Validate_NumberOutOfRangeError" message > */ > public static final String VALIDATE_NUMBER_OUT_OF_RANGE_ERROR = "Validate_NumberOutOfRangeError"; //$NON-NLS-1$ >@@ -99,6 +105,31 @@ > public static final String VALIDATE_CHARACTER_HELP = "Validate_CharacterHelp"; //$NON-NLS-1$ > > /** >+ * Key to be used for a "Validate_CharacterNoWhitespace" message >+ */ >+ public static final String VALIDATE_CHARACTER_NO_WHITESPACE = "Validate_CharacterNoWhitespace"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_CharacterNoSpace" message >+ */ >+ public static final String VALIDATE_CHARACTER_NO_SPACE = "Validate_CharacterNoSpace"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_CharacterLetter" message >+ */ >+ public static final String VALIDATE_CHARACTER_LETTER = "Validate_CharacterLetter"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_CharacterDigit" message >+ */ >+ public static final String VALIDATE_CHARACTER_DIGIT = "Validate_CharacterDigit"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_CharacterLetterOrDigit" message >+ */ >+ public static final String VALIDATE_CHARACTER_LETTER_OR_DIGIT = "Validate_CharacterLetterOrDigit"; //$NON-NLS-1$ >+ >+ /** > * Key to be used for a "Examples" message > */ > public static final String EXAMPLES = "Examples"; //$NON-NLS-1$ >@@ -109,10 +140,110 @@ > public static final String VALIDATE_NUMBER_PARSE_ERROR_NO_CHARACTER = "Validate_NumberParseErrorNoCharacter"; //$NON-NLS-1$ > > /** >+ * Key to be used for a "Validate_NonNull" message >+ */ >+ public static final String VALIDATE_NON_NULL = "Validate_NonNull"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_NonEmptyString" message >+ */ >+ public static final String VALIDATE_NON_EMPTY_STRING = "Validate_NonEmptyString"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_NonStringRegex" message >+ */ >+ public static final String VALIDATE_STRING_REGEX = "Validate_NonStringRegex"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_NumberRangeGreater" message >+ */ >+ public static final String VALIDATE_NUMBER_RANGE_GREATER = "Validate_NumberRangeGreater"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_NumberRangeGreaterEqual" message >+ */ >+ public static final String VALIDATE_NUMBER_RANGE_GREATER_EQUAL = "Validate_NumberRangeGreaterEqual"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_NumberRangeLess" message >+ */ >+ public static final String VALIDATE_NUMBER_RANGE_LESS = "Validate_NumberRangeLess"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_NumberRangeLessEqual" message >+ */ >+ public static final String VALIDATE_NUMBER_RANGE_LESS_EQUAL = "Validate_NumberRangeLessEqual"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_NumberRangeWithinRange" message >+ */ >+ public static final String VALIDATE_NUMBER_RANGE_WITHIN_RANGE = "Validate_NumberRangeWithinRange"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_NumberRangePositive" message >+ */ >+ public static final String VALIDATE_NUMBER_RANGE_POSITIVE = "Validate_NumberRangePositive"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_NumberRangeNonNegative" message >+ */ >+ public static final String VALIDATE_NUMBER_RANGE_NON_NEGATIVE = "Validate_NumberRangeNonNegative"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_DateRangeAfter" message >+ */ >+ public static final String VALIDATE_DATE_RANGE_AFTER = "Validate_DateRangeAfter"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_DateRangeAfterEqual" message >+ */ >+ public static final String VALIDATE_DATE_RANGE_AFTER_EQUAL = "Validate_DateRangeAfterEqual"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_DateRangeBefore" message >+ */ >+ public static final String VALIDATE_DATE_RANGE_BEFORE = "Validate_DateRangeBefore"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_DateRangeBeforeEqual" message >+ */ >+ public static final String VALIDATE_DATE_RANGE_BEFORE_EQUAL = "Validate_DateRangeBeforeEqual"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_DateRangeWithinRange" message >+ */ >+ public static final String VALIDATE_DATE_RANGE_WITHIN_RANGE = "Validate_DateRangeWithinRange"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_StringLengthMin" message >+ */ >+ public static final String VALIDATE_STRING_LENGTH_MIN = "Validate_StringLengthMin"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_StringLengthMax" message >+ */ >+ public static final String VALIDATE_STRING_LENGTH_MAX = "Validate_StringLengthMax"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_StringLengthRange" message >+ */ >+ public static final String VALIDATE_STRING_LENGTH_RANGE = "Validate_StringLengthRange"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_DecimalMaxScale" message >+ */ >+ public static final String VALIDATE_DECIMAL_MAX_SCALE = "Validate_DecimalMaxScale"; //$NON-NLS-1$ >+ >+ /** >+ * Key to be used for a "Validate_DecimalMaxPrecision" message >+ */ >+ public static final String VALIDATE_DECIMAL_MAX_PRECISION = "Validate_DecimalMaxPrecision"; //$NON-NLS-1$ >+ >+ /** > * 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 +259,27 @@ > /** > * 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) { >+ public static String getFormattedString(String key, Object[] arguments) { > try { >- return MessageFormat.format(bundle.getString(key), arguments); >+ return formatMessage(getString(key), arguments); > } catch (MissingResourceException e) { > return key; > } > } >+ >+ /** >+ * Formats the given message pattern with the provided arguments. >+ * >+ * @param pattern >+ * @param arguments >+ * @return formatted string >+ */ >+ public static String formatMessage(String pattern, Object[] arguments) { >+ return MessageFormat.format(pattern, arguments); >+ } > } >Index: src/org/eclipse/core/internal/databinding/messages.properties >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/messages.properties,v >retrieving revision 1.9 >diff -u -r1.9 messages.properties >--- src/org/eclipse/core/internal/databinding/messages.properties 16 Apr 2008 02:51:53 -0000 1.9 >+++ src/org/eclipse/core/internal/databinding/messages.properties 28 Feb 2010 23:33:37 -0000 >@@ -43,6 +43,8 @@ > TrueStringValues=yes,true > FalseStringValues=no,false > >+Validate_InvalidBooleanString=The boolean string is invalid. >+ > Validate_NumberOutOfRangeError=Please enter a value between [{0}] and [{1}] and with a similar format. > Validate_NumberParseError=Invalid character for value [{0}] at position [{1}] character [{2}]. > Validate_NumberParseErrorNoCharacter=Missing character for value [{0}] at position [{1}]. >@@ -53,4 +55,47 @@ > Validate_NoChangeAllowedHelp=Changes are not allowed in this field > Validate_CharacterHelp=Please type a character > >+#CharacterValidator >+Validate_CharacterNoWhitespace=The character must be no whitespace. >+Validate_CharacterNoSpace=The character must be no space. >+Validate_CharacterLetter=The character must be a letter. >+Validate_CharacterDigit=The character must be a digit. >+Validate_CharacterLetterOrDigit=The character must be a letter or digit. >+ >+#NonNullValidator >+Validate_NonNull=The value must not be empty. >+ >+#NonEmptyStringValidator >+Validate_NonEmptyString=The string must not be empty. >+ >+#StringRegexValidator >+Validate_NonStringRegex=The string must match the following pattern: {0}. >+ >+#NumberRangeValidator >+Validate_NumberRangeGreater=The value must be greater than {0}. >+Validate_NumberRangeGreaterEqual=The value must be greater than or equal to {0}. >+Validate_NumberRangeLess=The value must be less than {0}. >+Validate_NumberRangeLessEqual=The value must be less than or equal to {0}. >+Validate_NumberRangeWithinRange=The value must lie between {0} and {1}. >+Validate_NumberRangePositive=The value must be positive. >+Validate_NumberRangeNonNegative=The value must not be negative. >+ >+#DateRangeValidator >+Validate_DateRangeAfter=The date must be after {0}. >+Validate_DateRangeAfterEqual=The date must be after or on {0}. >+Validate_DateRangeBefore=The date must be before {0}. >+Validate_DateRangeBeforeEqual=The date must be before or on {0}. >+Validate_DateRangeWithinRange=The date must lie between {0} and {1}. >+ >+#StringLengthValidator >+Validate_StringLengthMin=The string must have at least {0} characters. >+Validate_StringLengthMax=The string must not have more than {0} characters. >+Validate_StringLengthRange=The string must have between {0} and {1} characters. >+ >+#DecimalScaleValidator >+Validate_DecimalMaxScale=The decimal must not have more than {0} fractional digits. >+ >+#DecimalPrecisionValidator >+Validate_DecimalMaxPrecision=The decimal must not have more than {0} significant digits. >+ > Examples=Examples >\ No newline at end of file >Index: src/org/eclipse/core/databinding/editing/StringEditing.java >=================================================================== >RCS file: src/org/eclipse/core/databinding/editing/StringEditing.java >diff -N src/org/eclipse/core/databinding/editing/StringEditing.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/databinding/editing/StringEditing.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,129 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.editing; >+ >+import org.eclipse.core.databinding.conversion.IConverter; >+import org.eclipse.core.databinding.validation.constraint.StringConstraints; >+import org.eclipse.core.internal.databinding.conversion.StringStripConverter; >+import org.eclipse.core.internal.databinding.conversion.StringTrimConverter; >+ >+/** >+ * @noextend This class is not intended to be subclassed by clients. >+ * @since 1.3 >+ */ >+public class StringEditing extends Editing<String, String> { >+ >+ /** >+ * Creates a new editing object for booleans. >+ * >+ * @param targetConverter >+ * The {@link #setTargetConverter(IConverter) target converter} >+ * to use for editing. >+ * >+ * @noreference This constructor is not intended to be referenced by >+ * clients. >+ */ >+ protected StringEditing(IConverter targetConverter) { >+ setTargetConverter(targetConverter); >+ } >+ >+ /** >+ * Creates a new editing object for strings which performs no validation or >+ * conversion. >+ * >+ * @return The new editing object which performs no validation or >+ * conversion. >+ */ >+ public static StringEditing withDefaults() { >+ return new StringEditing(null); >+ } >+ >+ /** >+ * Creates a new editing object which strips whitespace from both ends of >+ * the input string. >+ * >+ * @return The new editing object which strips whitespace from both ends of >+ * the input string. >+ * >+ * @see Character#isWhitespace(char) >+ */ >+ public static StringEditing stripped() { >+ return new StringEditing(new StringStripConverter(false)); >+ } >+ >+ /** >+ * Creates a new editing object which strips whitespace from both ends of >+ * the input string. In case stripping the input string results in an empty >+ * string, the input string will be converted to <code>null</code>. >+ * >+ * @return The new editing object which strips whitespace from both ends of >+ * the input string. Resulting empty strings are converted to >+ * <code>null</code>. >+ * >+ * @see Character#isWhitespace(char) >+ */ >+ public static StringEditing strippedToNull() { >+ return new StringEditing(new StringStripConverter(true)); >+ } >+ >+ /** >+ * Creates a new editing object which {@link String#trim()}s the input >+ * string. >+ * >+ * @return The new editing object which trims whitespace from both ends of >+ * the input string. >+ * >+ * @see String#trim() >+ */ >+ public static StringEditing trimmed() { >+ return new StringEditing(new StringTrimConverter(false)); >+ } >+ >+ /** >+ * Creates a new editing object which {@link String#trim()}s the input >+ * string. In case trimming the input string results in an empty string, the >+ * input string will be converted to <code>null</code>. >+ * >+ * @return The new editing object which trims whitespace from both ends of >+ * the input string. Resulting empty strings are converted to >+ * <code>null</code>. >+ * >+ * @see String#trim() >+ */ >+ public static StringEditing trimmedToNull() { >+ return new StringEditing(new StringTrimConverter(true)); >+ } >+ >+ public StringConstraints targetConstraints() { >+ return (StringConstraints) super.targetConstraints(); >+ } >+ >+ public StringConstraints modelConstraints() { >+ return (StringConstraints) super.modelConstraints(); >+ } >+ >+ public StringConstraints beforeSetModelConstraints() { >+ return (StringConstraints) super.beforeSetModelConstraints(); >+ } >+ >+ protected StringConstraints createTargetConstraints() { >+ return new StringConstraints(); >+ } >+ >+ protected StringConstraints createModelConstraints() { >+ return new StringConstraints(); >+ } >+ >+ protected StringConstraints createBeforeSetModelConstraints() { >+ return new StringConstraints(); >+ } >+} >Index: src/org/eclipse/core/internal/databinding/validation/NumberRangeValidator.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/validation/NumberRangeValidator.java >diff -N src/org/eclipse/core/internal/databinding/validation/NumberRangeValidator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/validation/NumberRangeValidator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,285 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.validation; >+ >+import java.text.MessageFormat; >+ >+import org.eclipse.core.databinding.validation.IValidator; >+import org.eclipse.core.databinding.validation.ValidationStatus; >+import org.eclipse.core.internal.databinding.BindingMessages; >+import org.eclipse.core.runtime.IStatus; >+ >+import com.ibm.icu.text.NumberFormat; >+ >+/** >+ * Provides validations for numbers which must lie within an open/closed range. >+ * >+ * @param <N> >+ * >+ * @since 1.3 >+ */ >+public class NumberRangeValidator<N extends Number & Comparable<N>> implements >+ IValidator { >+ >+ // The set of constraint types for the lower/upper bound of the date range. >+ protected static final int UNDEFINED = -1; >+ protected static final int GREATER = 0; >+ protected static final int GREATER_EQUAL = 1; >+ protected static final int LESS = 2; >+ protected static final int LESS_EQUAL = 3; >+ >+ // The default validation messages. >+ protected static final String GREATER_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_NUMBER_RANGE_GREATER); >+ protected static final String GREATER_EQUAL_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_NUMBER_RANGE_GREATER_EQUAL); >+ protected static final String LESS_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_NUMBER_RANGE_LESS); >+ protected static final String LESS_EQUAL_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_NUMBER_RANGE_LESS_EQUAL); >+ protected static final String WITHIN_RANGE_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_NUMBER_RANGE_WITHIN_RANGE); >+ protected static final String POSITIVE_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_NUMBER_RANGE_POSITIVE); >+ protected static final String NON_NEGATIVE_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_NUMBER_RANGE_NON_NEGATIVE); >+ >+ private final N min; >+ private final N max; >+ private final int minConstraint; >+ private final int maxConstraint; >+ private final String validationMessage; >+ private String formattedValidationMessage; >+ private final NumberFormat format; >+ >+ /** >+ * Single constructor which supports the individual number range types. >+ * >+ * @param min >+ * The min number of the range or <code>null</code> in case no >+ * lower bound is defined. >+ * @param max >+ * The max number of the range or <code>null</code> in case no >+ * upper bound is defined. >+ * @param minConstraint >+ * The type of constraint imposed by the lower bound of the >+ * range. >+ * @param maxConstraint >+ * The type of constraint imposed by the upper bound of the >+ * range. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized by >+ * the lower and upper bound of the range, if defined. >+ * @param format >+ * The integer format to use for formatting numbers in the >+ * validation message. >+ */ >+ protected NumberRangeValidator(N min, N max, int minConstraint, >+ int maxConstraint, String validationMessage, NumberFormat format) { >+ this.min = min; >+ this.max = max; >+ this.minConstraint = minConstraint; >+ this.maxConstraint = maxConstraint; >+ this.validationMessage = validationMessage; >+ this.format = format; >+ } >+ >+ /** >+ * Creates a validator which checks that an input integer is greater than >+ * the given number. >+ * >+ * @param <M> >+ * @param number >+ * The reference number of the greater constraint. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the given reference number. >+ * @param format >+ * The display format to use for formatting integers in the >+ * validation message. >+ * @return The validator instance. >+ */ >+ public static <M extends Number & Comparable<M>> NumberRangeValidator<M> greater( >+ M number, String validationMessage, NumberFormat format) { >+ return new NumberRangeValidator<M>(number, null, GREATER, UNDEFINED, >+ defaultIfNull(validationMessage, GREATER_MESSAGE), format); >+ } >+ >+ /** >+ * Creates a validator which checks that an input integer is greater than or >+ * equal to the given number. >+ * >+ * @param <M> >+ * @param number >+ * The reference number of the greater-equal constraint. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the given reference number. >+ * @param format >+ * The display format to use for formatting integers in the >+ * validation message. >+ * @return The validator instance. >+ */ >+ public static <M extends Number & Comparable<M>> NumberRangeValidator<M> greaterEqual( >+ M number, String validationMessage, NumberFormat format) { >+ return new NumberRangeValidator<M>(number, null, GREATER_EQUAL, >+ UNDEFINED, defaultIfNull(validationMessage, >+ GREATER_EQUAL_MESSAGE), format); >+ } >+ >+ /** >+ * Creates a validator which checks that an input integer is less than the >+ * given number. >+ * >+ * @param <M> >+ * @param number >+ * The reference number of the less constraint. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the given reference number. >+ * @param format >+ * The display format to use for formatting integers in the >+ * validation message. >+ * @return The validator instance. >+ */ >+ public static <M extends Number & Comparable<M>> NumberRangeValidator<M> less( >+ M number, String validationMessage, NumberFormat format) { >+ return new NumberRangeValidator<M>(null, number, UNDEFINED, LESS, >+ defaultIfNull(validationMessage, LESS_MESSAGE), format); >+ } >+ >+ /** >+ * Creates a validator which checks that an input integer is less than or >+ * equal to the given number. >+ * >+ * @param <M> >+ * @param number >+ * The reference number of the less-equal constraint. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the given reference number. >+ * @param format >+ * The display format to use for formatting integers in the >+ * validation message. >+ * @return The validator instance. >+ */ >+ public static <M extends Number & Comparable<M>> NumberRangeValidator<M> lessEqual( >+ M number, String validationMessage, NumberFormat format) { >+ return new NumberRangeValidator<M>(null, number, UNDEFINED, LESS_EQUAL, >+ defaultIfNull(validationMessage, LESS_EQUAL_MESSAGE), format); >+ } >+ >+ /** >+ * Creates a validator which checks that an input integer is within the >+ * given range. >+ * >+ * @param <M> >+ * @param min >+ * The lower bound of the range (inclusive). >+ * @param max >+ * The upper bound of the range (inclusive). >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the range's lower and upper bound. >+ * @param format >+ * The display format to use for formatting integers in the >+ * validation message. >+ * @return The validator instance. >+ */ >+ public static <M extends Number & Comparable<M>> NumberRangeValidator<M> range( >+ M min, M max, String validationMessage, NumberFormat format) { >+ return new NumberRangeValidator<M>(min, max, GREATER_EQUAL, LESS_EQUAL, >+ defaultIfNull(validationMessage, WITHIN_RANGE_MESSAGE), format); >+ } >+ >+ /** >+ * >+ * @param <M> >+ * @param one >+ * @param validationMessage >+ * @param format >+ * @return . >+ */ >+ public static <M extends Number & Comparable<M>> NumberRangeValidator<M> positive( >+ M one, String validationMessage, NumberFormat format) { >+ return new NumberRangeValidator<M>(one, null, GREATER_EQUAL, UNDEFINED, >+ defaultIfNull(validationMessage, POSITIVE_MESSAGE), format); >+ } >+ >+ /** >+ * >+ * @param <M> >+ * @param zero >+ * @param validationMessage >+ * @param format >+ * @return . >+ */ >+ public static <M extends Number & Comparable<M>> NumberRangeValidator<M> nonNegative( >+ M zero, String validationMessage, NumberFormat format) { >+ return new NumberRangeValidator<M>(zero, null, GREATER_EQUAL, >+ UNDEFINED, defaultIfNull(validationMessage, >+ NON_NEGATIVE_MESSAGE), format); >+ } >+ >+ public IStatus validate(Object value) { >+ if (value != null) { >+ N number = (N) value; >+ if ((min != null && !fulfillsConstraint(number, min, minConstraint)) >+ || (max != null && !fulfillsConstraint(number, max, >+ maxConstraint))) { >+ return ValidationStatus.error(getFormattedValidationMessage()); >+ } >+ } >+ return ValidationStatus.ok(); >+ } >+ >+ private boolean fulfillsConstraint(N number1, N number2, int constraint) { >+ int compareResult = number1.compareTo(number2); >+ switch (constraint) { >+ case GREATER: >+ return compareResult > 0; >+ case GREATER_EQUAL: >+ return compareResult >= 0; >+ case LESS: >+ return compareResult < 0; >+ case LESS_EQUAL: >+ return compareResult <= 0; >+ case UNDEFINED: >+ default: >+ throw new IllegalArgumentException( >+ "Unsupported constraint: " + constraint); //$NON-NLS-1$ >+ } >+ } >+ >+ private synchronized String getFormattedValidationMessage() { >+ if (formattedValidationMessage == null) { >+ formattedValidationMessage = MessageFormat.format( >+ validationMessage, getValidationMessageArguments()); >+ } >+ return formattedValidationMessage; >+ } >+ >+ private String[] getValidationMessageArguments() { >+ synchronized (format) { >+ if (min == null) { >+ return new String[] { format.format(max) }; >+ } else if (max == null) { >+ return new String[] { format.format(min) }; >+ } >+ return new String[] { format.format(min), format.format(max) }; >+ } >+ } >+ >+ private static String defaultIfNull(String string, String defaultString) { >+ return (string != null) ? string : defaultString; >+ } >+} >Index: src/org/eclipse/core/internal/databinding/validation/DateRangeValidator.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/validation/DateRangeValidator.java >diff -N src/org/eclipse/core/internal/databinding/validation/DateRangeValidator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/validation/DateRangeValidator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,243 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.validation; >+ >+import java.text.MessageFormat; >+import java.util.Date; >+ >+import org.eclipse.core.databinding.validation.IValidator; >+import org.eclipse.core.databinding.validation.ValidationStatus; >+import org.eclipse.core.internal.databinding.BindingMessages; >+import org.eclipse.core.runtime.IStatus; >+ >+import com.ibm.icu.text.DateFormat; >+ >+/** >+ * Provides validations for date which must lie within an open/closed range. >+ * >+ * @since 1.3 >+ */ >+public class DateRangeValidator implements IValidator { >+ >+ // The set of constraint types for the lower/upper bound of the date range. >+ private static final int UNDEFINED = -1; >+ private static final int AFTER = 0; >+ private static final int AFTER_EQUAL = 1; >+ private static final int BEFORE = 2; >+ private static final int BEFORE_EQUAL = 3; >+ >+ // The default validation messages. >+ private static final String AFTER_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_DATE_RANGE_AFTER); >+ private static final String AFTER_EQUAL_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_DATE_RANGE_AFTER_EQUAL); >+ private static final String BEFORE_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_DATE_RANGE_BEFORE); >+ private static final String BEFORE_EQUAL_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_DATE_RANGE_BEFORE_EQUAL); >+ private static final String WITHIN_RANGE_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_DATE_RANGE_WITHIN_RANGE); >+ >+ private final Date min; >+ private final Date max; >+ private final int minConstraint; >+ private final int maxConstraint; >+ private final String validationMessage; >+ private String formattedValidationMessage; >+ private final DateFormat format; >+ >+ /** >+ * Single constructor which supports the individual date range types. >+ * >+ * @param min >+ * The min date of the range or <code>null</code> in case no >+ * lower bound is defined. >+ * @param max >+ * The max date of the range or <code>null</code> in case no >+ * upper bound is defined. >+ * @param minConstraint >+ * The type of constraint imposed by the lower bound of the >+ * range. >+ * @param maxConstraint >+ * The type of constraint imposed by the upper bound of the >+ * range. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized by >+ * the lower and upper bound of the range, if defined. >+ * @param format >+ * The date format to use for formatting dates in the validation >+ * message. >+ */ >+ private DateRangeValidator(Date min, Date max, int minConstraint, >+ int maxConstraint, String validationMessage, DateFormat format) { >+ this.min = min; >+ this.max = max; >+ this.minConstraint = minConstraint; >+ this.maxConstraint = maxConstraint; >+ this.validationMessage = validationMessage; >+ this.format = format; >+ } >+ >+ /** >+ * Creates a validator which checks that an input date is after the given >+ * date. >+ * >+ * @param date >+ * The reference date of the after constraint. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the given reference date. >+ * @param format >+ * The display format to use for formatting dates in the >+ * validation message. >+ * @return The validator instance. >+ */ >+ public static DateRangeValidator after(Date date, String validationMessage, >+ DateFormat format) { >+ return new DateRangeValidator(date, null, AFTER, UNDEFINED, >+ defaultIfNull(validationMessage, AFTER_MESSAGE), format); >+ } >+ >+ /** >+ * Creates a validator which checks that an input date is after or on the >+ * given date. >+ * >+ * @param date >+ * The reference date of the after-equal constraint. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the given reference date. >+ * @param format >+ * The display format to use for formatting dates in the >+ * validation message. >+ * @return The validator instance. >+ */ >+ public static DateRangeValidator afterEqual(Date date, >+ String validationMessage, DateFormat format) { >+ return new DateRangeValidator(date, null, AFTER_EQUAL, UNDEFINED, >+ defaultIfNull(validationMessage, AFTER_EQUAL_MESSAGE), format); >+ } >+ >+ /** >+ * Creates a validator which checks that an input date is before the given >+ * date. >+ * >+ * @param date >+ * The reference date of the before constraint. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the given reference date. >+ * @param format >+ * The display format to use for formatting dates in the >+ * validation message. >+ * @return The validator instance. >+ */ >+ public static DateRangeValidator before(Date date, >+ String validationMessage, DateFormat format) { >+ return new DateRangeValidator(null, date, UNDEFINED, BEFORE, >+ defaultIfNull(validationMessage, BEFORE_MESSAGE), format); >+ } >+ >+ /** >+ * Creates a validator which checks that an input date is before or on the >+ * given date. >+ * >+ * @param date >+ * The reference date of the before-equal constraint. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the given reference date. >+ * @param format >+ * The display format to use for formatting dates in the >+ * validation message. >+ * @return The validator instance. >+ */ >+ public static DateRangeValidator beforeEqual(Date date, >+ String validationMessage, DateFormat format) { >+ return new DateRangeValidator(null, date, UNDEFINED, BEFORE_EQUAL, >+ defaultIfNull(validationMessage, BEFORE_EQUAL_MESSAGE), format); >+ } >+ >+ /** >+ * Creates a validator which checks that an input date is within the given >+ * range. >+ * >+ * @param min >+ * The lower bound of the range (inclusive). >+ * @param max >+ * The upper bound of the range (inclusive). >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the range's lower and upper bound. >+ * @param format >+ * The display format to use for formatting dates in the >+ * validation message. >+ * @return The validator instance. >+ */ >+ public static DateRangeValidator range(Date min, Date max, >+ String validationMessage, DateFormat format) { >+ return new DateRangeValidator(min, max, AFTER_EQUAL, BEFORE_EQUAL, >+ defaultIfNull(validationMessage, WITHIN_RANGE_MESSAGE), format); >+ } >+ >+ public IStatus validate(Object value) { >+ if (value != null) { >+ Date date = (Date) value; >+ if ((min != null && !fulfillsConstraint(date, min, minConstraint)) >+ || (max != null && !fulfillsConstraint(date, max, >+ maxConstraint))) { >+ return ValidationStatus.error(getFormattedValidationMessage()); >+ } >+ } >+ return ValidationStatus.ok(); >+ } >+ >+ private boolean fulfillsConstraint(Date date1, Date date2, int constraint) { >+ switch (constraint) { >+ case AFTER: >+ return date1.after(date2); >+ case AFTER_EQUAL: >+ return date1.after(date2) || date1.equals(date2); >+ case BEFORE: >+ return date1.before(date2); >+ case BEFORE_EQUAL: >+ return date1.before(date2) || date1.equals(date2); >+ case UNDEFINED: >+ default: >+ throw new IllegalArgumentException( >+ "Unsupported constraint: " + constraint); //$NON-NLS-1$ >+ } >+ } >+ >+ private synchronized String getFormattedValidationMessage() { >+ if (formattedValidationMessage == null) { >+ formattedValidationMessage = MessageFormat.format( >+ validationMessage, getValidationMessageArguments()); >+ } >+ return formattedValidationMessage; >+ } >+ >+ private String[] getValidationMessageArguments() { >+ synchronized (format) { >+ if (min == null) { >+ return new String[] { format.format(max) }; >+ } else if (max == null) { >+ return new String[] { format.format(min) }; >+ } >+ return new String[] { format.format(min), format.format(max) }; >+ } >+ } >+ >+ private static String defaultIfNull(String string, String defaultString) { >+ return (string != null) ? string : defaultString; >+ } >+} >Index: src/org/eclipse/core/internal/databinding/validation/StringLengthValidator.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/validation/StringLengthValidator.java >diff -N src/org/eclipse/core/internal/databinding/validation/StringLengthValidator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/validation/StringLengthValidator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,167 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.validation; >+ >+import java.text.MessageFormat; >+ >+import org.eclipse.core.databinding.validation.IValidator; >+import org.eclipse.core.databinding.validation.ValidationStatus; >+import org.eclipse.core.internal.databinding.BindingMessages; >+import org.eclipse.core.runtime.IStatus; >+ >+import com.ibm.icu.text.NumberFormat; >+ >+/** >+ * Provides validations for strings which must have a specified length. >+ * >+ * @since 1.3 >+ */ >+public class StringLengthValidator implements IValidator { >+ >+ // The default validation messages. >+ private static final String MIN_LENGTH_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_STRING_LENGTH_MIN); >+ private static final String MAX_LENGTH_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_STRING_LENGTH_MAX); >+ private static final String LENGTH_RANGE_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_STRING_LENGTH_RANGE); >+ >+ private final Integer minLength; >+ private final Integer maxLength; >+ private final String validationMessage; >+ private String formattedValidationMessage; >+ private final NumberFormat format; >+ >+ /** >+ * Creates a string length validator defining a minimum and/or maximum >+ * length for a string. >+ * >+ * @param minLength >+ * The minimum length of the string or <code>null</code> in case >+ * no minimum length is defined. >+ * @param maxLength >+ * The maximum length of the string or <code>null</code> in case >+ * no maximum length is defined. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized by >+ * the lower and upper bound of the range, if defined. >+ * @param format >+ * The number format to use for formatting integers (the length >+ * bounds) in the validation message. >+ */ >+ private StringLengthValidator(Integer minLength, Integer maxLength, >+ String validationMessage, NumberFormat format) { >+ this.minLength = minLength; >+ this.maxLength = maxLength; >+ this.validationMessage = validationMessage; >+ this.format = format; >+ } >+ >+ /** >+ * Creates a validator which checks that an input string has the given >+ * minimum length. >+ * >+ * @param minLength >+ * The minimum length which the input string must have. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the given minimum length. >+ * @param format >+ * The display format to use for formatting integers (the minimum >+ * length) in the validation message. >+ * @return The validator instance. >+ */ >+ public static StringLengthValidator min(int minLength, >+ String validationMessage, NumberFormat format) { >+ return new StringLengthValidator(new Integer(minLength), null, >+ defaultIfNull(validationMessage, MIN_LENGTH_MESSAGE), format); >+ } >+ >+ /** >+ * Creates a validator which checks that an input string has the given >+ * maximum length. >+ * >+ * @param maxLength >+ * The maximum length which the input string must have. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the given maximum length. >+ * @param format >+ * The display format to use for formatting integers (the maximum >+ * length) in the validation message. >+ * @return The validator instance. >+ */ >+ public static StringLengthValidator max(int maxLength, >+ String validationMessage, NumberFormat format) { >+ return new StringLengthValidator(null, new Integer(maxLength), >+ defaultIfNull(validationMessage, MAX_LENGTH_MESSAGE), format); >+ } >+ >+ /** >+ * Creates a validator which checks that the length of an input string lies >+ * in the given range. >+ * >+ * @param minLength >+ * The minimum length which the input string must have. >+ * @param maxLength >+ * The maximum length which the input string must have. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the given minimum and maximum lengths. >+ * @param format >+ * The display format to use for formatting integers (the >+ * minimum/maximum length) in the validation message. >+ * @return The validator instance. >+ */ >+ public static StringLengthValidator range(int minLength, int maxLength, >+ String validationMessage, NumberFormat format) { >+ return new StringLengthValidator(new Integer(minLength), new Integer( >+ maxLength), defaultIfNull(validationMessage, >+ LENGTH_RANGE_MESSAGE), format); >+ } >+ >+ public IStatus validate(Object value) { >+ String input = (String) value; >+ if (input != null) { >+ int inputLength = input.length(); >+ if ((minLength != null && inputLength < minLength.intValue()) >+ || maxLength != null && inputLength > maxLength.intValue()) { >+ return ValidationStatus.error(getFormattedValidationMessage()); >+ } >+ } >+ return ValidationStatus.ok(); >+ } >+ >+ private synchronized String getFormattedValidationMessage() { >+ if (formattedValidationMessage == null) { >+ formattedValidationMessage = MessageFormat.format( >+ validationMessage, getValidationMessageArguments()); >+ } >+ return formattedValidationMessage; >+ } >+ >+ private String[] getValidationMessageArguments() { >+ synchronized (format) { >+ if (minLength == null) { >+ return new String[] { format.format(maxLength) }; >+ } else if (maxLength == null) { >+ return new String[] { format.format(minLength) }; >+ } >+ return new String[] { format.format(minLength), >+ format.format(maxLength) }; >+ } >+ } >+ >+ private static String defaultIfNull(String string, String defaultString) { >+ return (string != null) ? string : defaultString; >+ } >+} >Index: src/org/eclipse/core/databinding/validation/constraint/CharacterConstraints.java >=================================================================== >RCS file: src/org/eclipse/core/databinding/validation/constraint/CharacterConstraints.java >diff -N src/org/eclipse/core/databinding/validation/constraint/CharacterConstraints.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/databinding/validation/constraint/CharacterConstraints.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,172 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.validation.constraint; >+ >+import org.eclipse.core.internal.databinding.validation.CharacterValidator; >+ >+/** >+ * Provides a set of constraints to apply to <code>Character</code>s. >+ * >+ * <p> >+ * Instances of this class can be used to define a set of constraints to apply >+ * to characters. In addition, the validation messages to be issued for the >+ * individual constraints can be configured. >+ * </p> >+ * >+ * @noextend This class is not intended to be subclassed by clients. >+ * @since 1.3 >+ */ >+public class CharacterConstraints extends >+ BaseObjectConstraints<Character, CharacterConstraints> { >+ >+ private String noWhitespaceMessage = null; >+ >+ private String noSpaceMessage = null; >+ >+ private String letterMessage = null; >+ >+ private String digitMessage = null; >+ >+ private String letterOrDigitMessage = null; >+ >+ /** >+ * Adds a validator ensuring that the character is no >+ * {@link Character#isWhitespace(char) whitespace}. Uses the current >+ * {@link #noWhitespaceMessage(String) validation message}. >+ * >+ * @return This constraints instance for method chaining. >+ */ >+ public CharacterConstraints noWhitespace() { >+ addValidator(CharacterValidator.noWhitespace(noWhitespaceMessage)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message for the {@link #noWhitespace()} constraint. >+ * >+ * @param message >+ * The validation message for the {@link #noWhitespace()} >+ * constraint. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #noWhitespace() >+ */ >+ public CharacterConstraints noWhitespaceMessage(String message) { >+ this.noWhitespaceMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the character is no >+ * {@link Character#isSpaceChar(char) space}. Uses the current >+ * {@link #noSpaceMessage(String) validation message}. >+ * >+ * @return This constraints instance for method chaining. >+ */ >+ public CharacterConstraints noSpace() { >+ addValidator(CharacterValidator.noSpace(noSpaceMessage)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message for the {@link #noSpace()} constraint. >+ * >+ * @param message >+ * The validation message for the {@link #noSpace()} constraint. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #noSpace() >+ */ >+ public CharacterConstraints noSpaceMessage(String message) { >+ this.noSpaceMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the character is a >+ * {@link Character#isLetter(char) letter}. Uses the current >+ * {@link #letterMessage(String) validation message}. >+ * >+ * @return This constraints instance for method chaining. >+ */ >+ public CharacterConstraints letter() { >+ addValidator(CharacterValidator.letter(letterMessage)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message for the {@link #letter()} constraint. >+ * >+ * @param message >+ * The validation message for the {@link #letter()} constraint. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #letter() >+ */ >+ public CharacterConstraints letterMessage(String message) { >+ this.letterMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the character is a >+ * {@link Character#isDigit(char) digit}. Uses the current >+ * {@link #digitMessage(String) validation message}. >+ * >+ * @return This constraints instance for method chaining. >+ */ >+ public CharacterConstraints digit() { >+ addValidator(CharacterValidator.digit(digitMessage)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message for the {@link #digit()} constraint. >+ * >+ * @param message >+ * The validation message for the {@link #digit()} constraint. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #digit() >+ */ >+ public CharacterConstraints digitMessage(String message) { >+ this.digitMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the character is a >+ * {@link Character#isLetterOrDigit(char) letter or digit}. Uses the current >+ * {@link #letterOrDigitMessage(String) validation message}. >+ * >+ * @return This constraints instance for method chaining. >+ */ >+ public CharacterConstraints letterOrDigit() { >+ addValidator(CharacterValidator.letterOrDigit(letterOrDigitMessage)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message for the {@link #letterOrDigit()} constraint. >+ * >+ * @param message >+ * The validation message for the {@link #letterOrDigit()} >+ * constraint. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #letterOrDigit() >+ */ >+ public CharacterConstraints letterOrDigitMessage(String message) { >+ this.letterOrDigitMessage = message; >+ return this; >+ } >+} >Index: src/org/eclipse/core/databinding/validation/constraint/DateConstraints.java >=================================================================== >RCS file: src/org/eclipse/core/databinding/validation/constraint/DateConstraints.java >diff -N src/org/eclipse/core/databinding/validation/constraint/DateConstraints.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/databinding/validation/constraint/DateConstraints.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,233 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.validation.constraint; >+ >+import java.util.Date; >+ >+import org.eclipse.core.internal.databinding.validation.DateRangeValidator; >+ >+import com.ibm.icu.text.DateFormat; >+ >+/** >+ * Provides a set of constraints to apply to <code>Date</code>s. >+ * >+ * <p> >+ * Instances of this class can be used to define a set of constraints to apply >+ * to dates. In addition, the validation messages to be issued for the >+ * individual constraints as well as the way in which model objects are >+ * formatted in the validation messages can be configured. >+ * </p> >+ * >+ * @see Date >+ * >+ * @noextend This class is not intended to be subclassed by clients. >+ * @since 1.3 >+ */ >+public class DateConstraints extends >+ BaseObjectConstraints<Date, DateConstraints> { >+ >+ private DateFormat dateFormat = DateFormat.getDateInstance(); >+ >+ private String afterMessage = null; >+ >+ private String afterEqualMessage = null; >+ >+ private String beforeMessage = null; >+ >+ private String beforeEqualMessage = null; >+ >+ private String rangeMessage = null; >+ >+ /** >+ * Sets the format to use when formatting a date to be included in any of >+ * the validation messages. >+ * >+ * @param format >+ * The format to use for displaying dates in validation messages. >+ * @return This constraints instance for method chaining. >+ */ >+ public DateConstraints dateFormat(DateFormat format) { >+ this.dateFormat = format; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input date is after the given date. >+ * Uses the current {@link #afterMessage(String) validation message} and >+ * {@link #dateFormat(DateFormat) date format}. >+ * >+ * @param date >+ * The date which the input date must be after. >+ * @return This constraints instance for method chaining. >+ * >+ * @see Date#after(Date) >+ */ >+ public DateConstraints after(Date date) { >+ addValidator(DateRangeValidator.after(date, afterMessage, dateFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the {@link #after(Date)} >+ * constraint. >+ * >+ * @param message >+ * The validation message pattern for the {@link #after(Date)} >+ * constraint. Can be parameterized with the date ({0}) which the >+ * input date must be after. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #after(Date) >+ */ >+ public DateConstraints afterMessage(String message) { >+ this.afterMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input date is after or on the given >+ * date. Uses the current {@link #afterEqualMessage(String) validation >+ * message} and {@link #dateFormat(DateFormat) date format}. >+ * >+ * @param date >+ * The date which the input date must be after or on. >+ * @return This constraints instance for method chaining. >+ * >+ * @see Date#after(Date) >+ * @see Date#equals(Object) >+ */ >+ public DateConstraints afterEqual(Date date) { >+ addValidator(DateRangeValidator.afterEqual(date, afterEqualMessage, >+ dateFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the {@link #afterEqual(Date)} >+ * constraint. >+ * >+ * @param message >+ * The validation message pattern for the >+ * {@link #afterEqual(Date)} constraint. Can be parameterized >+ * with the date ({0}) which the input date must be after or on. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #afterEqual(Date) >+ */ >+ public DateConstraints afterEqualMessage(String message) { >+ this.afterEqualMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input date is before the given date. >+ * Uses the current {@link #beforeMessage(String) validation message} and >+ * {@link #dateFormat(DateFormat) date format}. >+ * >+ * @param date >+ * The date which the input date must be before >+ * @return This constraints instance for method chaining. >+ * >+ * @see Date#before(Date) >+ */ >+ public DateConstraints before(Date date) { >+ addValidator(DateRangeValidator.before(date, beforeMessage, dateFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the {@link #before(Date)} >+ * constraint. >+ * >+ * @param message >+ * The validation message pattern for the {@link #before(Date)} >+ * constraint. Can be parameterized with the date ({0}) which the >+ * input date must be before. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #before(Date) >+ */ >+ public DateConstraints beforeMessage(String message) { >+ this.beforeMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input date is before or on the given >+ * date. Uses the current {@link #beforeEqualMessage(String) validation >+ * message} and {@link #dateFormat(DateFormat) date format}. >+ * >+ * @param date >+ * The date which the input date must be before or on. >+ * @return This constraints instance for method chaining. >+ * >+ * @see Date#before(Date) >+ * @see Date#equals(Object) >+ */ >+ public DateConstraints beforeEqual(Date date) { >+ addValidator(DateRangeValidator.beforeEqual(date, beforeEqualMessage, >+ dateFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the {@link #beforeEqual(Date)} >+ * constraint. >+ * >+ * @param message >+ * The validation message pattern for the >+ * {@link #beforeEqual(Date)} constraint. Can be parameterized >+ * ({0}) with the date which the input date must be before or on. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #beforeEqual(Date) >+ */ >+ public DateConstraints beforeEqualMessage(String message) { >+ this.beforeEqualMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input date is within the given range. >+ * Uses the current {@link #rangeMessage(String) validation message} and >+ * {@link #dateFormat(DateFormat) date format}. >+ * >+ * @param minDate >+ * The lower bound of the range (inclusive). >+ * @param maxDate >+ * The upper bound of the range (inclusive). >+ * @return This constraints instance for method chaining. >+ */ >+ public DateConstraints range(Date minDate, Date maxDate) { >+ addValidator(DateRangeValidator.range(minDate, maxDate, rangeMessage, >+ dateFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the {@link #range(Date, Date)} >+ * constraint. >+ * >+ * @param message >+ * The validation message pattern for the >+ * {@link #range(Date, Date)} constraint. Can be parameterized >+ * with the min ({0}) and max ({1}) dates of the range in which >+ * the input date must lie. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #range(Date, Date) >+ */ >+ public DateConstraints rangeMessage(String message) { >+ this.rangeMessage = message; >+ return this; >+ } >+} >Index: src/org/eclipse/core/internal/databinding/conversion/StringTrimConverter.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/conversion/StringTrimConverter.java >diff -N src/org/eclipse/core/internal/databinding/conversion/StringTrimConverter.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/conversion/StringTrimConverter.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,45 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.conversion; >+ >+import org.eclipse.core.databinding.conversion.Converter; >+ >+/** >+ * @since 1.3 >+ */ >+public class StringTrimConverter extends Converter { >+ >+ private final boolean trimToNull; >+ >+ /** >+ * >+ * @param trimToNull >+ */ >+ public StringTrimConverter(boolean trimToNull) { >+ super(String.class, String.class); >+ this.trimToNull = trimToNull; >+ } >+ >+ public Object convert(Object fromObject) { >+ String string = (String) fromObject; >+ >+ if (string != null) { >+ string = string.trim(); >+ >+ if (trimToNull && string.length() == 0) { >+ string = null; >+ } >+ } >+ >+ return string; >+ } >+} >Index: src/org/eclipse/core/databinding/editing/BooleanEditing.java >=================================================================== >RCS file: src/org/eclipse/core/databinding/editing/BooleanEditing.java >diff -N src/org/eclipse/core/databinding/editing/BooleanEditing.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/databinding/editing/BooleanEditing.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,161 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.editing; >+ >+import org.eclipse.core.databinding.validation.constraint.BooleanConstraints; >+import org.eclipse.core.databinding.validation.constraint.StringConstraints; >+import org.eclipse.core.internal.databinding.conversion.BooleanToStringConverter; >+import org.eclipse.core.internal.databinding.conversion.StringToBooleanConverter; >+import org.eclipse.core.internal.databinding.validation.StringToBooleanValidator; >+ >+/** >+ * @noextend This class is not intended to be subclassed by clients. >+ * @since 1.3 >+ */ >+public class BooleanEditing extends Editing<String, Boolean> { >+ >+ /** >+ * Creates a new editing object for booleans. >+ * >+ * @param trueValues >+ * The set of strings representing a <code>true</code> value. >+ * @param falseValues >+ * The set of strings representing a <code>false</code> value. >+ * @param parseErrorMessage >+ * The validation message issued in case the input string cannot >+ * be parsed to a boolean. >+ * >+ * @noreference This constructor is not intended to be referenced by >+ * clients. >+ */ >+ protected BooleanEditing(String[] trueValues, String[] falseValues, >+ String parseErrorMessage) { >+ StringToBooleanConverter targetConverter = new StringToBooleanConverter(); >+ BooleanToStringConverter modelConverter = new BooleanToStringConverter( >+ Boolean.class); >+ >+ StringToBooleanValidator targetValidator = new StringToBooleanValidator(); >+ if (parseErrorMessage != null) { >+ targetValidator.setParseErrorMessage(parseErrorMessage); >+ } >+ >+ if (trueValues != null && falseValues != null) { >+ targetValidator.setSourceStrings(trueValues, falseValues); >+ targetConverter.setSourceStrings(trueValues, falseValues); >+ modelConverter.setTargetStrings(trueValues[0], falseValues[0]); >+ } >+ >+ setTargetConverter(targetConverter); >+ setModelConverter(modelConverter); >+ targetConstraints().addValidator(targetValidator); >+ } >+ >+ /** >+ * Creates a new editing object which uses the default set of string >+ * representations for boolean values for parsing and displaying. >+ * >+ * @return The new editing object for the default set of string >+ * representations for boolean values. >+ */ >+ public static BooleanEditing withDefaults() { >+ return withDefaults(null); >+ } >+ >+ /** >+ * Creates a new editing object which uses the default set of string >+ * representations for boolean values for parsing and displaying. Uses the >+ * specified custom validation message. >+ * >+ * @param parseErrorMessage >+ * The validation message issued in case the input string cannot >+ * be parsed to a boolean. >+ * @return The new editing object for the default set of string >+ * representations for boolean values. >+ */ >+ public static BooleanEditing withDefaults(String parseErrorMessage) { >+ return new BooleanEditing(null, null, parseErrorMessage); >+ } >+ >+ /** >+ * Creates a new editing object which uses the given set of string >+ * representations for boolean values for parsing and displaying. >+ * >+ * <p> >+ * For parsing, the given string values will be considered valid >+ * representations of {@code true} and {@code false}, respectively. For >+ * displaying, the first element of the respective array will be used for >+ * representing the corresponding boolean value. >+ * </p> >+ * >+ * @param trueValues >+ * The set of strings representing a <code>true</code> value. >+ * @param falseValues >+ * The set of strings representing a <code>false</code> value. >+ * @return The new editing object for the given set of string >+ * representations for boolean values. >+ */ >+ public static BooleanEditing forStringValues(String[] trueValues, >+ String[] falseValues) { >+ return forStringValues(trueValues, falseValues, null); >+ } >+ >+ /** >+ * Creates a new editing object which uses the given set of string >+ * representations for boolean values for parsing and displaying. Uses the >+ * specified custom validation message. >+ * >+ * <p> >+ * For parsing, the given string values will be considered valid >+ * representations of {@code true} and {@code false}, respectively. For >+ * displaying, the first element of the respective array will be used for >+ * representing the corresponding boolean value. >+ * </p> >+ * >+ * @param trueValues >+ * The set of strings representing a <code>true</code> value. >+ * @param falseValues >+ * The set of strings representing a <code>false</code> value. >+ * @param parseErrorMessage >+ * The validation message issued in case the input string cannot >+ * be parsed to a boolean. >+ * @return The new editing object for the given set of string >+ * representations for boolean values. >+ */ >+ public static BooleanEditing forStringValues(String[] trueValues, >+ String[] falseValues, String parseErrorMessage) { >+ return new BooleanEditing(trueValues, falseValues, parseErrorMessage); >+ } >+ >+ public StringConstraints targetConstraints() { >+ return (StringConstraints) super.targetConstraints(); >+ } >+ >+ public BooleanConstraints modelConstraints() { >+ return (BooleanConstraints) super.modelConstraints(); >+ } >+ >+ public BooleanConstraints beforeSetModelConstraints() { >+ return (BooleanConstraints) super.beforeSetModelConstraints(); >+ } >+ >+ protected StringConstraints createTargetConstraints() { >+ return new StringConstraints(); >+ } >+ >+ protected BooleanConstraints createModelConstraints() { >+ return new BooleanConstraints(); >+ } >+ >+ protected BooleanConstraints createBeforeSetModelConstraints() { >+ return new BooleanConstraints(); >+ } >+} >Index: src/org/eclipse/core/databinding/validation/constraint/BooleanConstraints.java >=================================================================== >RCS file: src/org/eclipse/core/databinding/validation/constraint/BooleanConstraints.java >diff -N src/org/eclipse/core/databinding/validation/constraint/BooleanConstraints.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/databinding/validation/constraint/BooleanConstraints.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,30 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.validation.constraint; >+ >+/** >+ * Provides a set of constraints to apply to <code>Boolean</code>s. >+ * >+ * <p> >+ * Instances of this class can be used to define a set of constraints to apply >+ * to booleans. In addition, the validation messages to be issued for the >+ * individual constraints can be configured. >+ * </p> >+ * >+ * @noextend This class is not intended to be subclassed by clients. >+ * @since 1.3 >+ */ >+public class BooleanConstraints extends >+ BaseObjectConstraints<Boolean, BooleanConstraints> { >+ >+ // no additional constraints than those inherited from the subclass >+} >Index: src/org/eclipse/core/internal/databinding/validation/DecimalPrecisionValidator.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/validation/DecimalPrecisionValidator.java >diff -N src/org/eclipse/core/internal/databinding/validation/DecimalPrecisionValidator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/validation/DecimalPrecisionValidator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,108 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.validation; >+ >+import java.text.MessageFormat; >+ >+import org.eclipse.core.databinding.validation.IValidator; >+import org.eclipse.core.databinding.validation.ValidationStatus; >+import org.eclipse.core.internal.databinding.BindingMessages; >+import org.eclipse.core.runtime.IStatus; >+ >+import com.ibm.icu.math.BigDecimal; >+import com.ibm.icu.text.NumberFormat; >+ >+/** >+ * Provides validations for the precision of decimal numbers. >+ * >+ * @since 1.3 >+ */ >+public class DecimalPrecisionValidator implements IValidator { >+ >+ private static final String MAX_PRECISION_VALIDATION_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_DECIMAL_MAX_PRECISION); >+ >+ private final int maxPrecision; >+ >+ private final String validationMessage; >+ >+ private String formattedValidationMessage; >+ >+ private final NumberFormat precisionFormat; >+ >+ private DecimalPrecisionValidator(int maxPrecision, >+ String validationMessage, NumberFormat precisionFormat) { >+ this.maxPrecision = maxPrecision; >+ this.validationMessage = validationMessage != null ? validationMessage >+ : MAX_PRECISION_VALIDATION_MESSAGE; >+ this.precisionFormat = precisionFormat; >+ } >+ >+ /** >+ * Creates a validator which checks that an input decimal has a precision >+ * which is less or equal to the given precision. >+ * >+ * @param maxPrecision >+ * The maximum precision to enforce on the input decimal. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the maximum precision to be enforced. >+ * @param precisionFormat >+ * The display format to use for formatting the precision in the >+ * validation message. >+ * @return The validator instance. >+ */ >+ public static DecimalPrecisionValidator max(int maxPrecision, >+ String validationMessage, NumberFormat precisionFormat) { >+ return new DecimalPrecisionValidator(maxPrecision, validationMessage, >+ precisionFormat); >+ } >+ >+ public IStatus validate(Object value) { >+ if (value != null) { >+ Number number = (Number) value; >+ final int precision; >+ if (number instanceof BigDecimal) { >+ precision = computePrecision(((BigDecimal) number)); >+ } else { >+ precision = computePrecision(new BigDecimal(number >+ .doubleValue())); >+ } >+ if (precision > maxPrecision) { >+ return ValidationStatus.error(getFormattedValidationMessage()); >+ } >+ } >+ return ValidationStatus.ok(); >+ } >+ >+ private static int computePrecision(BigDecimal bigDecimal) { >+ // In Java 1.4, there is no direct API for retrieving the precision of >+ // a BigDecimal so we use the length of the string representation of the >+ // unscaled BigInteger value of the BigDecimal to actually compute it. >+ return bigDecimal.unscaledValue().abs().toString().length(); >+ } >+ >+ private synchronized String getFormattedValidationMessage() { >+ if (formattedValidationMessage == null) { >+ formattedValidationMessage = MessageFormat.format( >+ validationMessage, getValidationMessageArguments()); >+ } >+ return formattedValidationMessage; >+ } >+ >+ private String[] getValidationMessageArguments() { >+ synchronized (precisionFormat) { >+ return new String[] { precisionFormat.format(new Integer( >+ maxPrecision)) }; >+ } >+ } >+} >Index: src/org/eclipse/core/internal/databinding/validation/StringToBigDecimalValidator.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/validation/StringToBigDecimalValidator.java >diff -N src/org/eclipse/core/internal/databinding/validation/StringToBigDecimalValidator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/validation/StringToBigDecimalValidator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,32 @@ >+/******************************************************************************* >+ * Copyright (c) 2007 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.validation; >+ >+/** >+ * Validates that a string is of the appropriate format for a BigDecimal. >+ * >+ * @since 1.3 >+ */ >+public class StringToBigDecimalValidator extends >+ AbstractStringToNumberValidator { >+ >+ /** >+ * @param converter >+ */ >+ public StringToBigDecimalValidator(NumberFormatConverter converter) { >+ super(converter, null, null); >+ } >+ >+ protected boolean isInRange(Number number) { >+ return true; >+ } >+} >Index: src/org/eclipse/core/internal/databinding/validation/StringToBooleanValidator.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/validation/StringToBooleanValidator.java >diff -N src/org/eclipse/core/internal/databinding/validation/StringToBooleanValidator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/validation/StringToBooleanValidator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,117 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.validation; >+ >+import java.util.Arrays; >+import java.util.LinkedList; >+import java.util.List; >+import java.util.StringTokenizer; >+ >+import org.eclipse.core.databinding.validation.IValidator; >+import org.eclipse.core.databinding.validation.ValidationStatus; >+import org.eclipse.core.internal.databinding.BindingMessages; >+import org.eclipse.core.runtime.IStatus; >+ >+/** >+ * @since 1.3 >+ */ >+public class StringToBooleanValidator implements IValidator { >+ >+ // TODO: Some of this code is duplicated from StringToBooleanPrimitiveConverter! >+ private static final String[] DEFAULT_TRUE_VALUES; >+ private static final String[] DEFAULT_FALSE_VALUES; >+ >+ static { >+ String delimiter = BindingMessages.getString(BindingMessages.VALUE_DELIMITER); >+ String values = BindingMessages.getString(BindingMessages.TRUE_STRING_VALUES); >+ DEFAULT_TRUE_VALUES = valuesToSortedArray(delimiter, values); >+ >+ values = BindingMessages.getString(BindingMessages.FALSE_STRING_VALUES); >+ DEFAULT_FALSE_VALUES = valuesToSortedArray(delimiter, values); >+ } >+ >+ private String[] trueValues = DEFAULT_TRUE_VALUES; >+ private String[] falseValues = DEFAULT_FALSE_VALUES; >+ >+ private String parseErrorMessage = BindingMessages.getString(BindingMessages.VALIDATE_INVALID_BOOLEAN_STRING); >+ >+ /** >+ * Returns a sorted array with all values converted to upper case. >+ * >+ * @param delimiter >+ * @param values >+ * @return sorted array of values >+ */ >+ private static String[] valuesToSortedArray(String delimiter, String values) { >+ List list = new LinkedList(); >+ StringTokenizer tokenizer = new StringTokenizer(values, delimiter); >+ while (tokenizer.hasMoreTokens()) { >+ list.add(tokenizer.nextToken().toUpperCase()); >+ } >+ >+ String[] array = (String[]) list.toArray(new String[list.size()]); >+ Arrays.sort(array); >+ >+ return array; >+ } >+ >+ /** >+ * Sets the validation message to be used in case the source string does not >+ * represent a valid boolean value. >+ * >+ * @param message >+ * The validation message to be used in case the source string >+ * does not represent a valid boolean value. >+ */ >+ public final void setParseErrorMessage(String message) { >+ this.parseErrorMessage = message; >+ } >+ >+ /** >+ * Sets the string values which are considered to represent a >+ * <code>true</code> and <code>false</code> value, respectively. >+ * >+ * <p> >+ * Note that the capitalization of the provided strings is ignored. >+ * </p> >+ * >+ * @param trueValues >+ * The set of strings representing a <code>true</code> value. >+ * @param falseValues >+ * The set of strings representing a <code>false</code> value. >+ */ >+ public final void setSourceStrings(String[] trueValues, String[] falseValues) { >+ this.trueValues = new String[trueValues.length]; >+ for (int i = 0; i < trueValues.length; i++) { >+ this.trueValues[i] = trueValues[i].toUpperCase(); >+ } >+ Arrays.sort(this.trueValues); // for binary search >+ >+ this.falseValues = new String[falseValues.length]; >+ for (int i = 0; i < falseValues.length; i++) { >+ this.falseValues[i] = falseValues[i].toUpperCase(); >+ } >+ Arrays.sort(this.falseValues); // for binary search >+ } >+ >+ public IStatus validate(Object value) { >+ String source = (String) value; >+ if (source != null && source.length() != 0) { >+ source = source.toUpperCase(); >+ if (Arrays.binarySearch(trueValues, source) < 0 >+ && Arrays.binarySearch(falseValues, source) < 0) { >+ return ValidationStatus.error(parseErrorMessage); >+ } >+ } >+ return ValidationStatus.ok(); >+ } >+} >Index: src/org/eclipse/core/databinding/validation/constraint/Constraints.java >=================================================================== >RCS file: src/org/eclipse/core/databinding/validation/constraint/Constraints.java >diff -N src/org/eclipse/core/databinding/validation/constraint/Constraints.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/databinding/validation/constraint/Constraints.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,228 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.validation.constraint; >+ >+import java.util.ArrayList; >+import java.util.List; >+ >+import org.eclipse.core.databinding.util.Policy; >+import org.eclipse.core.databinding.validation.IValidator; >+import org.eclipse.core.internal.databinding.BindingMessages; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.core.runtime.MultiStatus; >+import org.eclipse.core.runtime.Status; >+ >+/** >+ * This class allows to aggregate a set of {@link IValidator validators} and to >+ * combine their individual validation statuses in different ways. >+ * >+ * <p> >+ * The set of validators to be applied can be {@link #addValidator(IValidator) >+ * added} to a constraints object from which an aggregate validator can then be >+ * {@link #createValidator() created} which combines the statuses of all the >+ * accumulated validators as dictated by the specified >+ * {@link #aggregationPolicy(Aggregation) aggregation policy}. >+ * </p> >+ * >+ * @param <T> >+ * >+ * @see IValidator >+ * >+ * @since 1.3 >+ */ >+public class Constraints<T> { >+ >+ /** >+ * The supported aggregation policies to apply to the individual validations >+ * which constitute the set of constraints. >+ */ >+ public static enum Aggregation { >+ >+ /** >+ * Constant denoting an aggregation strategy that merges multiple non-OK >+ * status objects in a {@link MultiStatus}. Returns an OK status result >+ * if all statuses from the set of validators to apply are an OK status. >+ * Returns a single status if there is only one non-OK status. >+ * >+ * @see #aggregationPolicy(Aggregation) >+ */ >+ MERGED, >+ >+ /** >+ * Constant denoting an aggregation strategy that always returns the >+ * <i>most</i> severe status from the set of validators to apply. If >+ * there is more than one status at the same severity level, it picks >+ * the first one it encounters. >+ * >+ * @see #aggregationPolicy(Aggregation) >+ */ >+ MAX_SEVERITY, >+ >+ /** >+ * Constant denoting an aggregation strategy that always returns the >+ * <i>least</i> severe status from the set of validators to apply. If >+ * there is more than one status at the same severity level, it picks >+ * the first one it encounters. >+ * >+ * @see #aggregationPolicy(Aggregation) >+ */ >+ MIN_SEVERITY; >+ } >+ >+ // Will be initialized lazily. >+ private List<IValidator> validators = null; >+ >+ private IValidator cachedValidator = null; >+ >+ private Aggregation aggregationPolicy = Aggregation.MAX_SEVERITY; >+ >+ /** >+ * Adds a custom validator to the set of constraints to apply. >+ * >+ * @param validator >+ * The custom validator to add to the set of constraints. >+ * @return This constraints instance for method chaining. >+ */ >+ public Constraints<T> addValidator(IValidator validator) { >+ if (validators == null) { >+ validators = new ArrayList<IValidator>(2); >+ } >+ validators.add(validator); >+ cachedValidator = null; >+ return this; >+ } >+ >+ /** >+ * Sets the aggregation policy to apply to the individual validations which >+ * constitute this set of constraints. >+ * >+ * @param policy >+ * The validation aggregation policy to set. Must be one of >+ * {@link Aggregation#MERGED}, {@link Aggregation#MAX_SEVERITY} >+ * or {@link Aggregation#MIN_SEVERITY}. >+ * @return This constraints instance for method chaining. >+ * >+ * @see Aggregation#MERGED >+ * @see Aggregation#MAX_SEVERITY >+ * @see Aggregation#MIN_SEVERITY >+ */ >+ public Constraints<T> aggregationPolicy(Aggregation policy) { >+ this.aggregationPolicy = policy; >+ cachedValidator = null; >+ return this; >+ } >+ >+ /** >+ * Creates a validator which enforces the current set of constraints. >+ * >+ * <p> >+ * Note that this method will return <code>null</code> in case the set of >+ * constraints to apply is empty. >+ * </p> >+ * >+ * @return A validator which enforces the current set of constraints. May be >+ * <code>null</code>. >+ */ >+ public final IValidator createValidator() { >+ if (validators != null && !validators.isEmpty()) { >+ if (cachedValidator == null) { >+ if (validators.size() == 1) { >+ cachedValidator = validators.get(0); >+ } else { >+ IValidator[] currentValidators = validators >+ .toArray(new IValidator[validators.size()]); >+ cachedValidator = new ConstraintsValidator( >+ currentValidators, aggregationPolicy); >+ } >+ } >+ return cachedValidator; >+ } >+ return null; >+ } >+ >+ private static final class ConstraintsValidator implements IValidator { >+ >+ private final IValidator[] validators; >+ >+ private final Aggregation aggregationPolicy; >+ >+ public ConstraintsValidator(IValidator[] validators, >+ Aggregation aggregationPolicy) { >+ this.validators = validators; >+ this.aggregationPolicy = aggregationPolicy; >+ } >+ >+ public IStatus validate(Object value) { >+ switch (aggregationPolicy) { >+ case MERGED: >+ return validateMerged(value); >+ case MAX_SEVERITY: >+ return validateMaxSeverity(value); >+ case MIN_SEVERITY: >+ return validateMinSeverity(value); >+ default: >+ throw new IllegalArgumentException( >+ "Unsupported aggregationPolicy: " + aggregationPolicy); //$NON-NLS-1$ >+ } >+ } >+ >+ private IStatus validateMerged(Object value) { >+ List<IStatus> statuses = new ArrayList<IStatus>(); >+ for (IValidator validator : validators) { >+ IStatus status = validator.validate(value); >+ if (!status.isOK()) { >+ statuses.add(status); >+ } >+ } >+ >+ if (statuses.size() == 1) { >+ return statuses.get(0); >+ } >+ >+ if (!statuses.isEmpty()) { >+ MultiStatus result = new MultiStatus(Policy.JFACE_DATABINDING, >+ 0, BindingMessages >+ .getString(BindingMessages.MULTIPLE_PROBLEMS), >+ null); >+ for (IStatus status : statuses) { >+ result.merge(status); >+ } >+ return result; >+ } >+ >+ return Status.OK_STATUS; >+ } >+ >+ private IStatus validateMaxSeverity(Object value) { >+ IStatus maxStatus = Status.OK_STATUS; >+ for (IValidator validator : validators) { >+ IStatus status = validator.validate(value); >+ if (status.getSeverity() > maxStatus.getSeverity()) { >+ maxStatus = status; >+ } >+ } >+ return maxStatus; >+ } >+ >+ private IStatus validateMinSeverity(Object value) { >+ IStatus minStatus = null; >+ for (IValidator validator : validators) { >+ IStatus status = validator.validate(value); >+ if (minStatus == null >+ || status.getSeverity() < minStatus.getSeverity()) { >+ minStatus = status; >+ } >+ } >+ return minStatus != null ? minStatus : Status.OK_STATUS; >+ } >+ } >+} >Index: src/org/eclipse/core/databinding/validation/constraint/StringConstraints.java >=================================================================== >RCS file: src/org/eclipse/core/databinding/validation/constraint/StringConstraints.java >diff -N src/org/eclipse/core/databinding/validation/constraint/StringConstraints.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/databinding/validation/constraint/StringConstraints.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,245 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.validation.constraint; >+ >+import java.util.regex.Pattern; >+ >+import org.eclipse.core.internal.databinding.validation.NonEmptyStringValidator; >+import org.eclipse.core.internal.databinding.validation.StringLengthValidator; >+import org.eclipse.core.internal.databinding.validation.StringRegexValidator; >+ >+import com.ibm.icu.text.NumberFormat; >+ >+/** >+ * Provides a set of constraints to apply to <code>String</code>s. >+ * >+ * <p> >+ * Instances of this class can be used to define a set of constraints to apply >+ * to strings. In addition, the validation messages to be issued for the >+ * individual constraints as well as the way in which model objects are >+ * formatted in the validation messages can be configured. >+ * </p> >+ * >+ * @noextend This class is not intended to be subclassed by clients. >+ * @since 1.3 >+ */ >+public class StringConstraints extends >+ BaseObjectConstraints<String, StringConstraints> { >+ >+ private NumberFormat lengthFormat = NumberFormat.getIntegerInstance(); >+ >+ private String nonEmptyMessage = null; >+ >+ private String minLengthMessage = null; >+ >+ private String maxLengthMessage = null; >+ >+ private String lengthRangeMessage = null; >+ >+ private String matchesMessage = null; >+ >+ /** >+ * Adds a validator ensuring that the input integer is not empty. Uses the >+ * current {@link #nonEmptyMessage(String) validation message}. >+ * >+ * @return This constraints instance for method chaining. >+ */ >+ public StringConstraints nonEmpty() { >+ addValidator(new NonEmptyStringValidator(nonEmptyMessage)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message for the {@link #nonEmpty()} constraint. >+ * >+ * @param message >+ * The validation message for the {@link #nonEmpty()} constraint. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #nonEmpty() >+ */ >+ public StringConstraints nonEmptyMessage(String message) { >+ this.nonEmptyMessage = message; >+ return this; >+ } >+ >+ /** >+ * Sets the format to use when formatting the string length in any of the >+ * validation messages stemming from a length constraint. >+ * >+ * @param format >+ * The format to use for displaying the string length in >+ * validation messages stemming from a length constraint. >+ * messages. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #minLength(int) >+ * @see #maxLength(int) >+ * @see #lengthRange(int, int) >+ */ >+ public StringConstraints lengthFormat(NumberFormat format) { >+ this.lengthFormat = format; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input string has at least the >+ * specified amount of characters. Uses the current >+ * {@link #minLengthMessage(String) validation message} and >+ * {@link #lengthFormat(NumberFormat) length format}. >+ * >+ * @param minLength >+ * The minimal length to be enforced on the input string. >+ * @return This constraints instance for method chaining. >+ */ >+ public StringConstraints minLength(int minLength) { >+ addValidator(StringLengthValidator.min(minLength, minLengthMessage, >+ lengthFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the {@link #minLength(int)} >+ * constraint. >+ * >+ * @param message >+ * The validation message pattern for the {@link #minLength(int)} >+ * constraint. Can be parameterized with the minimum string >+ * length ({0}). >+ * @return This constraints instance for method chaining. >+ * >+ * @see #minLength(int) >+ */ >+ public StringConstraints minLengthMessage(String message) { >+ this.minLengthMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input string has not more than the >+ * specified amount of characters. Uses the current >+ * {@link #maxLengthMessage(String) validation message} and >+ * {@link #lengthFormat(NumberFormat) length format}. >+ * >+ * @param maxLength >+ * The maximum length to be enforced on the input string. >+ * @return This constraints instance for method chaining. >+ */ >+ public StringConstraints maxLength(int maxLength) { >+ addValidator(StringLengthValidator.max(maxLength, maxLengthMessage, >+ lengthFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the {@link #maxLength(int)} >+ * constraint. >+ * >+ * @param message >+ * The validation message pattern for the {@link #maxLength(int)} >+ * constraint. Can be parameterized with the maximum string >+ * length ({0}). >+ * @return This constraints instance for method chaining. >+ * >+ * @see #maxLength(int) >+ */ >+ public StringConstraints maxLengthMessage(String message) { >+ this.maxLengthMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the length of the input string is between >+ * the given bounds. Uses the current {@link #lengthRangeMessage(String) >+ * validation message} and {@link #lengthFormat(NumberFormat) length format} >+ * . >+ * >+ * @param minLength >+ * The minimal length to be enforced on the input string. >+ * @param maxLength >+ * The maximum length to be enforced on the input string. >+ * @return This constraints instance for method chaining. >+ */ >+ public StringConstraints lengthRange(int minLength, int maxLength) { >+ addValidator(StringLengthValidator.range(minLength, maxLength, >+ lengthRangeMessage, lengthFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the >+ * {@link #lengthRange(int, int)} constraint. >+ * >+ * @param message >+ * The validation message pattern for the >+ * {@link #lengthRange(int, int)} constraint. Can be >+ * parameterized with the minimum ({0}) and maximum ({1}) string >+ * lengths. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #lengthRange(int, int) >+ */ >+ public StringConstraints lengthRangeMessage(String message) { >+ this.lengthRangeMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input string >+ * {@link Pattern#matches(String, CharSequence) matches} the given regular >+ * expression. Uses the current {@link #matchesMessage(String) validation >+ * message}. >+ * >+ * @param regex >+ * The regular expression which the input string must match. >+ * @return This constraints instance for method chaining. >+ * >+ * @see Pattern#matches(String, CharSequence) >+ */ >+ public StringConstraints matches(String regex) { >+ addValidator(new StringRegexValidator(regex, matchesMessage)); >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input string >+ * {@link Pattern#matches(String, CharSequence) matches} the given pattern. >+ * Uses the current {@link #matchesMessage(String) validation message}. >+ * >+ * @param pattern >+ * The pattern which the input string must match. >+ * @return This constraints instance for method chaining. >+ * >+ * @see Pattern#matches(String, CharSequence) >+ */ >+ public StringConstraints matches(Pattern pattern) { >+ addValidator(new StringRegexValidator(pattern, matchesMessage)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the {@link #matches(String)} >+ * constraint. >+ * >+ * @param message >+ * The validation message pattern for the >+ * {@link #matches(String)} constraint. Can be parameterized with >+ * the pattern string ({0}) which the input integer must match. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #matches(String) >+ */ >+ public StringConstraints matchesMessage(String message) { >+ this.matchesMessage = message; >+ 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,970 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.editing; >+ >+import org.eclipse.core.databinding.Binding; >+import org.eclipse.core.databinding.DataBindingContext; >+import org.eclipse.core.databinding.UpdateListStrategy; >+import org.eclipse.core.databinding.UpdateSetStrategy; >+import org.eclipse.core.databinding.UpdateValueStrategy; >+import org.eclipse.core.databinding.conversion.IConverter; >+import org.eclipse.core.databinding.observable.list.IObservableList; >+import org.eclipse.core.databinding.observable.set.IObservableSet; >+import org.eclipse.core.databinding.observable.value.IObservableValue; >+import org.eclipse.core.databinding.validation.IValidator; >+import org.eclipse.core.databinding.validation.constraint.Constraints; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.core.runtime.MultiStatus; >+ >+/** >+ * @param <T> >+ * @param <M> >+ * >+ * @since 1.3 >+ */ >+public class Editing<T, M> { >+ >+ private Constraints<T> targetConstraints; >+ >+ private Constraints<M> modelConstraints; >+ >+ private Constraints<M> beforeSetModelConstraints; >+ >+ private IConverter targetConverter; >+ >+ private IConverter modelConverter; >+ >+ /** >+ * Default constructor which creates an unconfigured editing instance. >+ */ >+ protected Editing() { >+ // empty editing instance >+ } >+ >+ /** >+ * Creates an unconfigured editing instance. >+ * >+ * @return A new, unconfigured editing instance. >+ * >+ * @param <MT> >+ * @param <MM> >+ */ >+ public static <MT, MM> Editing<MT, MM> create() { >+ return new Editing<MT, MM>(); >+ } >+ >+ /** >+ * Creates an editing instance with the given target-to-model and >+ * model-to-target converters. >+ * >+ * @param t2mConverter >+ * The target-to-model converter to set. May be <code>null</code> >+ * . >+ * @param m2tConverter >+ * The model-to-target converter to set. May be <code>null</code> >+ * . >+ * @return A new editing instance with the given target-to-model and >+ * model-to-target converters. >+ * >+ * @param <MM> >+ * @param <MT> >+ */ >+ public static <MT, MM> Editing<MT, MM> withConverters( >+ IConverter t2mConverter, IConverter m2tConverter) { >+ Editing<MT, MM> editing = new Editing<MT, MM>(); >+ editing.setTargetConverter(t2mConverter); >+ editing.setModelConverter(m2tConverter); >+ return editing; >+ } >+ >+ /** >+ * Returns the target constraints to apply. >+ * >+ * @return The target constraints to apply. >+ * >+ * @see #createTargetConstraints() >+ */ >+ public Constraints<T> targetConstraints() { >+ if (targetConstraints == null) { >+ targetConstraints = createTargetConstraints(); >+ } >+ return targetConstraints; >+ } >+ >+ /** >+ * Returns the model constraints to apply. >+ * >+ * @return The model constraints to apply. >+ * >+ * @see #createModelConstraints() >+ */ >+ public Constraints<M> modelConstraints() { >+ if (modelConstraints == null) { >+ modelConstraints = createModelConstraints(); >+ } >+ return modelConstraints; >+ } >+ >+ /** >+ * Returns the before-set model constraints to apply. >+ * >+ * @return The before-set model constraints to apply. >+ * >+ * @see #createBeforeSetModelConstraints() >+ */ >+ public Constraints<M> beforeSetModelConstraints() { >+ if (beforeSetModelConstraints == null) { >+ beforeSetModelConstraints = createBeforeSetModelConstraints(); >+ } >+ return beforeSetModelConstraints; >+ } >+ >+ /** >+ * Creates the target constraints to apply. >+ * >+ * <p> >+ * The constraints object created by this method will be exposed as the >+ * {@link #targetConstraints()} of this editing object. By default, this >+ * method returns a plain {@link Constraints} object. >+ * </p> >+ * >+ * <p> >+ * This method will be called lazily the first time the target constraints >+ * are accessed. Subclasses may overwrite this method in order to create a >+ * custom constraints object which will then be typically exposed in the >+ * subclass as API in order to allow for a typesafe access. >+ * </p> >+ * >+ * @return The target constraints to apply. >+ * >+ * @see #targetConstraints() >+ */ >+ protected Constraints<T> createTargetConstraints() { >+ return new Constraints<T>(); >+ } >+ >+ /** >+ * Creates the model constraints to apply. >+ * >+ * <p> >+ * The constraints object created by this method will be exposed as the >+ * {@link #modelConstraints()} of this editing object. By default, this >+ * method returns a plain {@link Constraints} object. >+ * </p> >+ * >+ * <p> >+ * This method will be called lazily the first time the model constraints >+ * are accessed. Subclasses may overwrite this method in order to create a >+ * custom constraints object which will then be typically exposed in the >+ * subclass as API in order to allow for a typesafe access. >+ * </p> >+ * >+ * @return The model constraints to apply. >+ * >+ * @see #modelConstraints() >+ */ >+ protected Constraints<M> createModelConstraints() { >+ return new Constraints<M>(); >+ } >+ >+ /** >+ * Creates the before-set model constraints to apply. >+ * >+ * <p> >+ * The constraints object created by this method will be exposed as the >+ * {@link #beforeSetModelConstraints()} of this editing object. By default, >+ * this method returns a plain {@link Constraints} object. >+ * </p> >+ * >+ * <p> >+ * This method will be called lazily the first time the before-set model >+ * constraints are accessed. Subclasses may overwrite this method in order >+ * to create a custom constraints object which will then be typically >+ * exposed in the subclass as API in order to allow for a typesafe access. >+ * </p> >+ * >+ * @return The before-set model constraints to apply. >+ * >+ * @see #beforeSetModelConstraints() >+ */ >+ protected Constraints<M> createBeforeSetModelConstraints() { >+ return new Constraints<M>(); >+ } >+ >+ /** >+ * Sets the target-to-model converter for this editing instance. >+ * >+ * @param converter >+ * The target-to-model converter to set. >+ */ >+ protected final void setTargetConverter(IConverter converter) { >+ this.targetConverter = converter; >+ } >+ >+ /** >+ * Sets the model-to-target converter for this editing instance. >+ * >+ * @param converter >+ * The model-to-target converter to set. >+ */ >+ protected final void setModelConverter(IConverter converter) { >+ this.modelConverter = converter; >+ } >+ >+ /** >+ * 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() >+ * @see #adaptT2MValueStrategy(UpdateValueStrategy) >+ */ >+ public final UpdateValueStrategy createT2MValueStrategy() { >+ return adaptT2MValueStrategy(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) >+ * @see #adaptT2MValueStrategy(UpdateValueStrategy) >+ */ >+ public final UpdateValueStrategy createT2MValueStrategy(int updatePolicy) { >+ return adaptT2MValueStrategy(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() >+ * @see #adaptM2TValueStrategy(UpdateValueStrategy) >+ */ >+ public final UpdateValueStrategy createM2TValueStrategy() { >+ return adaptM2TValueStrategy(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) >+ * @see #adaptM2TValueStrategy(UpdateValueStrategy) >+ */ >+ public final UpdateValueStrategy createM2TValueStrategy(int updatePolicy) { >+ return adaptM2TValueStrategy(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() >+ * @see #adaptT2MListStrategy(UpdateListStrategy) >+ */ >+ public final UpdateListStrategy createT2MListStrategy() { >+ return adaptT2MListStrategy(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) >+ * @see #adaptT2MListStrategy(UpdateListStrategy) >+ */ >+ public final UpdateListStrategy createT2MListStrategy(int updatePolicy) { >+ return adaptT2MListStrategy(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() >+ * @see #adaptM2TListStrategy(UpdateListStrategy) >+ */ >+ public final UpdateListStrategy createM2TListStrategy() { >+ return adaptM2TListStrategy(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) >+ * @see #adaptM2TListStrategy(UpdateListStrategy) >+ */ >+ public final UpdateListStrategy createM2TListStrategy(int updatePolicy) { >+ return adaptM2TListStrategy(new UpdateListStrategy(updatePolicy)); >+ } >+ >+ /** >+ * Creates a new target-to-model {@link UpdateSetStrategy} with a default >+ * update policy configured by the current state of this editing object. >+ * >+ * @return A new target-to-model {@link UpdateSetStrategy} configured by the >+ * current state of this editing object. >+ * >+ * @see UpdateListStrategy#UpdateListStrategy() >+ * @see #adaptT2MSetStrategy(UpdateSetStrategy) >+ */ >+ public final UpdateSetStrategy createT2MSetStrategy() { >+ return adaptT2MSetStrategy(new UpdateSetStrategy()); >+ } >+ >+ /** >+ * 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 UpdateSetStrategy#UpdateSetStrategy(int) >+ * @see #adaptT2MSetStrategy(UpdateSetStrategy) >+ */ >+ public final UpdateSetStrategy createT2MSetStrategy(int updatePolicy) { >+ return adaptT2MSetStrategy(new UpdateSetStrategy(updatePolicy)); >+ } >+ >+ /** >+ * Creates a new model-to-target {@link UpdateSetStrategy} with a default >+ * update policy configured by the current state of this editing object. >+ * >+ * @return A new model-to-target {@link UpdateSetStrategy} configured by the >+ * current state of this editing object. >+ * >+ * @see UpdateSetStrategy#UpdateSetStrategy() >+ * @see #adaptM2TSetStrategy(UpdateSetStrategy) >+ */ >+ public final UpdateSetStrategy createM2TSetStrategy() { >+ return adaptM2TSetStrategy(new UpdateSetStrategy()); >+ } >+ >+ /** >+ * Creates a new model-to-target {@link UpdateSetStrategy} 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 UpdateSetStrategy} configured by the >+ * current state of this editing object. >+ * >+ * @see UpdateSetStrategy#UpdateSetStrategy(int) >+ * @see #adaptM2TSetStrategy(UpdateSetStrategy) >+ */ >+ public final UpdateSetStrategy createM2TSetStrategy(int updatePolicy) { >+ return adaptM2TSetStrategy(new UpdateSetStrategy(updatePolicy)); >+ } >+ >+ /** >+ * Configures an existing target-to-model {@link UpdateValueStrategy} with >+ * the current state of this editing object. >+ * >+ * <p> >+ * The configuration is done as follows: >+ * <ul> >+ * <li> >+ * The {@link Constraints#createValidator() validator} of the >+ * {@link #targetConstraints() target constraints} is set as the >+ * {@link UpdateValueStrategy#setAfterGetValidator(IValidator) after-get >+ * validator} of the update strategy.</li> >+ * <li>The {@link #setTargetConverter(IConverter) target converter} is set >+ * as the {@link UpdateValueStrategy#setConverter(IConverter) converter} of >+ * the update strategy.</li> >+ * <li> >+ * The {@link Constraints#createValidator() validator} of the >+ * {@link #modelConstraints() model constraints} is set as the >+ * {@link UpdateValueStrategy#setAfterConvertValidator(IValidator) >+ * after-convert validator} of the update strategy.</li> >+ * <li>The {@link Constraints#createValidator() validator} of the >+ * {@link #beforeSetModelConstraints() before-set model constraints} is set >+ * as the {@link UpdateValueStrategy#setBeforeSetValidator(IValidator) >+ * before-set validator} of the update strategy.</li> >+ * </ul> >+ * </p> >+ * >+ * @param updateStrategy >+ * The {@link UpdateValueStrategy} to configure. >+ * @return The passed-in, configured target-to-model >+ * {@link UpdateValueStrategy}. >+ * >+ * @see UpdateValueStrategy#setAfterGetValidator(IValidator) >+ * @see UpdateValueStrategy#setConverter(IConverter) >+ * @see UpdateValueStrategy#setAfterConvertValidator(IValidator) >+ * @see UpdateValueStrategy#setBeforeSetValidator(IValidator) >+ */ >+ public final UpdateValueStrategy adaptT2MValueStrategy( >+ UpdateValueStrategy updateStrategy) { >+ updateStrategy.setAfterGetValidator(createValidator(targetConstraints)); >+ updateStrategy.setConverter(targetConverter); >+ updateStrategy >+ .setAfterConvertValidator(createValidator(modelConstraints)); >+ updateStrategy >+ .setBeforeSetValidator(createValidator(beforeSetModelConstraints)); >+ return updateStrategy; >+ } >+ >+ /** >+ * Configures an existing model-to-target {@link UpdateValueStrategy} with >+ * the current state of this editing object by setting the >+ * {@link #setModelConverter(IConverter) model converter} as the >+ * {@link UpdateValueStrategy#setConverter(IConverter) converter} of the >+ * update strategy. >+ * >+ * @param updateStrategy >+ * The {@link UpdateValueStrategy} to configure. >+ * @return The passed-in, configured model-to-target >+ * {@link UpdateValueStrategy}. >+ * >+ * @see UpdateValueStrategy#setConverter(IConverter) >+ */ >+ public final UpdateValueStrategy adaptM2TValueStrategy( >+ UpdateValueStrategy updateStrategy) { >+ updateStrategy.setConverter(modelConverter); >+ return updateStrategy; >+ } >+ >+ /** >+ * Configures an existing target-to-model {@link UpdateListStrategy} with >+ * the current state of this editing object by setting the >+ * {@link #setTargetConverter(IConverter) target converter} as the >+ * {@link UpdateListStrategy#setConverter(IConverter) converter} of the >+ * update strategy. >+ * >+ * @param updateStrategy >+ * The {@link UpdateListStrategy} to configure. >+ * @return The passed-in, configured target-to-model >+ * {@link UpdateListStrategy}. >+ * >+ * @see UpdateListStrategy#setConverter(IConverter) >+ */ >+ public final UpdateListStrategy adaptT2MListStrategy( >+ UpdateListStrategy updateStrategy) { >+ updateStrategy.setConverter(targetConverter); >+ return updateStrategy; >+ } >+ >+ /** >+ * Configures an existing model-to-target {@link UpdateListStrategy} with >+ * the current state of this editing object by setting the >+ * {@link #setModelConverter(IConverter) model converter} as the >+ * {@link UpdateListStrategy#setConverter(IConverter) converter} of the >+ * update strategy. >+ * >+ * @param updateStrategy >+ * The {@link UpdateListStrategy} to configure. >+ * @return The passed-in, configured model-to-target >+ * {@link UpdateListStrategy}. >+ * >+ * @see UpdateListStrategy#setConverter(IConverter) >+ */ >+ public final UpdateListStrategy adaptM2TListStrategy( >+ UpdateListStrategy updateStrategy) { >+ updateStrategy.setConverter(modelConverter); >+ return updateStrategy; >+ } >+ >+ /** >+ * Configures an existing target-to-model {@link UpdateListStrategy} with >+ * the current state of this editing object by setting the >+ * {@link #setTargetConverter(IConverter) target converter} as the >+ * {@link UpdateSetStrategy#setConverter(IConverter) converter} of the >+ * update strategy. >+ * >+ * @param updateStrategy >+ * The {@link UpdateSetStrategy} to configure. >+ * @return The passed-in, configured target-to-model >+ * {@link UpdateSetStrategy}. >+ * >+ * @see UpdateSetStrategy#setConverter(IConverter) >+ */ >+ public final UpdateSetStrategy adaptT2MSetStrategy( >+ UpdateSetStrategy updateStrategy) { >+ updateStrategy.setConverter(targetConverter); >+ return updateStrategy; >+ } >+ >+ /** >+ * Configures an existing model-to-target {@link UpdateSetStrategy} with the >+ * current state of this editing object by setting the >+ * {@link #setModelConverter(IConverter) model converter} as the >+ * {@link UpdateSetStrategy#setConverter(IConverter) converter} of the >+ * update strategy. >+ * >+ * @param updateStrategy >+ * The {@link UpdateSetStrategy} to configure. >+ * @return The passed-in, configured model-to-target >+ * {@link UpdateSetStrategy}. >+ * >+ * @see UpdateSetStrategy#setConverter(IConverter) >+ */ >+ public final UpdateSetStrategy adaptM2TSetStrategy( >+ UpdateSetStrategy updateStrategy) { >+ updateStrategy.setConverter(modelConverter); >+ return updateStrategy; >+ } >+ >+ /** >+ * Converts a target value to a model value by performing the following >+ * steps: >+ * <ul> >+ * <li> >+ * Applying all the {@link #targetConstraints() target constraints} to the >+ * given target value.</li> >+ * <li> >+ * {@link #setTargetConverter(IConverter) Converting} the target value to >+ * the model value.</li> >+ * <li> >+ * Applying all the {@link #modelConstraints() model constraints} to the >+ * converted model value.</li> >+ * <li> >+ * Applying all the {@link #beforeSetModelConstraints() before-set model >+ * constraints} to the converted model value.</li> >+ * </ul> >+ * >+ * <p> >+ * The conversion process will be aborted by returning <code>null</code> >+ * whenever any of the applied validators produces a {@link IStatus >+ * validation status} having {@link IStatus#getSeverity() severity} >+ * <code>IStatus.ERROR</code> or <code>IStatus.CANCEL</code>. During the >+ * conversion process, any validation status whose severity is different >+ * from <code>IStatus.OK</code> will be {@link MultiStatus#merge(IStatus) >+ * aggregated} on the given <code>validationStatus</code>. >+ * </p> >+ * >+ * @param targetValue >+ * The target value to be converted to a model value. >+ * @param validationStatus >+ * Aggregate validation status to which to add the validations >+ * produced during the conversion process. May be >+ * <code>null</code>. >+ * @return The converted model value or <code>null</code> in case the >+ * conversion has been aborted due to a validation error. >+ */ >+ public final M convertToModel(T targetValue, MultiStatus validationStatus) { >+ if (!applyConstraints(targetConstraints, targetValue, validationStatus)) { >+ return null; >+ } >+ >+ M modelValue = (M) applyConverter(targetConverter, targetValue); >+ >+ if (!applyConstraints(modelConstraints, modelValue, validationStatus)) { >+ return null; >+ } >+ >+ if (!applyConstraints(beforeSetModelConstraints, modelValue, >+ validationStatus)) { >+ return null; >+ } >+ >+ return modelValue; >+ } >+ >+ /** >+ * {@link #setModelConverter(IConverter) Converts} a model value to a target >+ * value. >+ * >+ * @param modelValue >+ * The model value to be converted to a target value. >+ * @return The converted target value. >+ */ >+ public final T convertToTarget(M modelValue) { >+ return (T) applyConverter(modelConverter, modelValue); >+ } >+ >+ /** >+ * Creates a binding between a target and model observable value on the >+ * given binding context by creating new update strategies which will be >+ * both configured with the state of this editing object before passing them >+ * to the binding. >+ * >+ * <p> >+ * The target-to-model and model-to-target update strategies for the binding >+ * will be created by the methods {@link #createT2MValueStrategy()} and >+ * {@link #createM2TValueStrategy()}, respectively. >+ * </p> >+ * >+ * @param dbc >+ * The binding context on which to create the value binding. >+ * @param targetObservableValue >+ * The target observable value of the binding. >+ * @param modelObservableValue >+ * The model observable value of the binding. >+ * @return The new value binding. >+ * >+ * @see #createT2MValueStrategy() >+ * @see #createM2TValueStrategy() >+ * @see DataBindingContext#bindValue(IObservableValue, IObservableValue, >+ * UpdateValueStrategy, UpdateValueStrategy) >+ */ >+ public final Binding bindValue(DataBindingContext dbc, >+ IObservableValue targetObservableValue, >+ IObservableValue modelObservableValue) { >+ return dbc.bindValue(targetObservableValue, modelObservableValue, >+ createT2MValueStrategy(), createM2TValueStrategy()); >+ } >+ >+ /** >+ * Creates a binding between a target and model observable value on the >+ * given binding context by creating new update strategies with the provided >+ * update policies which will be both configured with the state of this >+ * editing object before passing them to the binding. >+ * >+ * @param dbc >+ * The binding context on which to create the value binding. >+ * @param targetObservableValue >+ * The target observable value of the binding. >+ * @param modelObservableValue >+ * The model observable value of the binding. >+ * @param t2mUpdatePolicy >+ * The update policy for the target-to-model >+ * {@link UpdateValueStrategy} which is >+ * {@link #createT2MValueStrategy(int) created} and passed to the >+ * new binding. >+ * @param m2tUpdatePolicy >+ * The update policy for the model-to-target >+ * {@link UpdateValueStrategy} which is >+ * {@link #createM2TValueStrategy(int) created} and passed to the >+ * new binding. >+ * @return The new value binding. >+ * >+ * @see #createT2MValueStrategy(int) >+ * @see #createM2TValueStrategy(int) >+ * @see DataBindingContext#bindValue(IObservableValue, IObservableValue, >+ * UpdateValueStrategy, UpdateValueStrategy) >+ */ >+ public final Binding bindValue(DataBindingContext dbc, >+ IObservableValue targetObservableValue, >+ IObservableValue modelObservableValue, int t2mUpdatePolicy, >+ int m2tUpdatePolicy) { >+ return dbc.bindValue(targetObservableValue, modelObservableValue, >+ createT2MValueStrategy(t2mUpdatePolicy), >+ createM2TValueStrategy(m2tUpdatePolicy)); >+ } >+ >+ /** >+ * Creates a binding between a target and model observable value on the >+ * given binding context by using the provided update strategies which will >+ * be both configured with the state of this editing object before passing >+ * them to the binding. >+ * >+ * @param dbc >+ * The binding context on which to create the value binding. >+ * @param targetObservableValue >+ * The target observable value of the binding. >+ * @param modelObservableValue >+ * The model observable value of the binding. >+ * @param t2mUpdateStrategy >+ * The target-to-model {@link UpdateValueStrategy} of the binding >+ * to be {@link #adaptT2MValueStrategy(UpdateValueStrategy) >+ * configured} with the state of this editing object before >+ * passing it to the binding. >+ * @param m2tUpdateStrategy >+ * The model-to-target {@link UpdateValueStrategy} of the binding >+ * to be {@link #adaptM2TValueStrategy(UpdateValueStrategy) >+ * configured} with the state of this editing object before >+ * passing it to the binding. >+ * @return The new value binding. >+ * >+ * @see #adaptT2MValueStrategy(UpdateValueStrategy) >+ * @see #adaptM2TValueStrategy(UpdateValueStrategy) >+ * @see DataBindingContext#bindValue(IObservableValue, IObservableValue, >+ * UpdateValueStrategy, UpdateValueStrategy) >+ */ >+ public final Binding bindValue(DataBindingContext dbc, >+ IObservableValue targetObservableValue, >+ IObservableValue modelObservableValue, >+ UpdateValueStrategy t2mUpdateStrategy, >+ UpdateValueStrategy m2tUpdateStrategy) { >+ return dbc.bindValue(targetObservableValue, modelObservableValue, >+ adaptT2MValueStrategy(t2mUpdateStrategy), >+ adaptM2TValueStrategy(m2tUpdateStrategy)); >+ } >+ >+ /** >+ * Creates a binding between a target and model observable list on the given >+ * binding context by creating new update strategies which will be both >+ * configured with the state of this editing object before passing them to >+ * the binding. >+ * >+ * <p> >+ * The target-to-model and model-to-target update strategies for the binding >+ * will be created by the methods {@link #createT2MListStrategy()} and >+ * {@link #createM2TListStrategy()}, respectively. >+ * </p> >+ * >+ * @param dbc >+ * The binding context on which to create the list binding. >+ * @param targetObservableList >+ * The target observable list of the binding. >+ * @param modelObservableList >+ * The model observable list of the binding. >+ * @return The new list binding. >+ * >+ * @see #createT2MListStrategy() >+ * @see #createM2TListStrategy() >+ * @see DataBindingContext#bindList(IObservableList, IObservableList, >+ * UpdateListStrategy, UpdateListStrategy) >+ */ >+ public final Binding bindList(DataBindingContext dbc, >+ IObservableList targetObservableList, >+ IObservableList modelObservableList) { >+ return dbc.bindList(targetObservableList, modelObservableList, >+ createT2MListStrategy(), createM2TListStrategy()); >+ } >+ >+ /** >+ * Creates a binding between a target and model observable list on the given >+ * binding context by creating new update strategies with the provided >+ * update policies which will be both configured with the state of this >+ * editing object before passing them to the binding. >+ * >+ * @param dbc >+ * The binding context on which to create the list binding. >+ * @param targetObservableList >+ * The target observable list of the binding. >+ * @param modelObservableList >+ * The model observable list of the binding. >+ * @param t2mUpdatePolicy >+ * The update policy for the target-to-model >+ * {@link UpdateListStrategy} which is >+ * {@link #createT2MListStrategy(int) created} and passed to the >+ * new binding. >+ * @param m2tUpdatePolicy >+ * The update policy for the model-to-target >+ * {@link UpdateListStrategy} which is >+ * {@link #createM2TListStrategy(int) created} and passed to the >+ * new binding. >+ * @return The new list binding. >+ * >+ * @see #createT2MListStrategy(int) >+ * @see #createM2TListStrategy(int) >+ * @see DataBindingContext#bindList(IObservableList, IObservableList, >+ * UpdateListStrategy, UpdateListStrategy) >+ */ >+ public final Binding bindList(DataBindingContext dbc, >+ IObservableList targetObservableList, >+ IObservableList modelObservableList, int t2mUpdatePolicy, >+ int m2tUpdatePolicy) { >+ return dbc.bindList(targetObservableList, modelObservableList, >+ createT2MListStrategy(t2mUpdatePolicy), >+ createM2TListStrategy(m2tUpdatePolicy)); >+ } >+ >+ /** >+ * Creates a binding between a target and model observable list on the given >+ * binding context by using the provided update strategies which will be >+ * both configured with the state of this editing object before passing them >+ * to the binding. >+ * >+ * @param dbc >+ * The binding context on which to create the list binding. >+ * @param targetObservableList >+ * The target observable list of the binding. >+ * @param modelObservableList >+ * The model observable list of the binding. >+ * @param t2mUpdateStrategy >+ * The target-to-model {@link UpdateListStrategy} of the binding >+ * to be {@link #adaptT2MListStrategy(UpdateListStrategy) >+ * configured} with the state of this editing object before >+ * passing it to the binding. >+ * @param m2tUpdateStrategy >+ * The model-to-target {@link UpdateListStrategy} of the binding >+ * to be {@link #adaptM2TListStrategy(UpdateListStrategy) >+ * configured} with the state of this editing object before >+ * passing it to the binding. >+ * @return The new list binding. >+ * >+ * @see #adaptT2MListStrategy(UpdateListStrategy) >+ * @see #adaptM2TListStrategy(UpdateListStrategy) >+ * @see DataBindingContext#bindList(IObservableList, IObservableList, >+ * UpdateListStrategy, UpdateListStrategy) >+ */ >+ public final Binding bindList(DataBindingContext dbc, >+ IObservableList targetObservableList, >+ IObservableList modelObservableList, >+ UpdateListStrategy t2mUpdateStrategy, >+ UpdateListStrategy m2tUpdateStrategy) { >+ return dbc.bindList(targetObservableList, modelObservableList, >+ adaptT2MListStrategy(t2mUpdateStrategy), >+ adaptM2TListStrategy(m2tUpdateStrategy)); >+ } >+ >+ /** >+ * Creates a binding between a target and model observable set on the given >+ * binding context by creating new update strategies which will be both >+ * configured with the state of this editing object before passing them to >+ * the binding. >+ * >+ * <p> >+ * The target-to-model and model-to-target update strategies for the binding >+ * will be created by the methods {@link #createT2MSetStrategy()} and >+ * {@link #createM2TSetStrategy()}, respectively. >+ * </p> >+ * >+ * @param dbc >+ * The binding context on which to create the set binding. >+ * @param targetObservableSet >+ * The target observable set of the binding. >+ * @param modelObservableSet >+ * The model observable set of the binding. >+ * @return The new set binding. >+ * >+ * @see #createT2MSetStrategy() >+ * @see #createM2TSetStrategy() >+ * @see DataBindingContext#bindSet(IObservableSet, IObservableSet, >+ * UpdateSetStrategy, UpdateSetStrategy) >+ */ >+ public final Binding bindSet(DataBindingContext dbc, >+ IObservableSet targetObservableSet, >+ IObservableSet modelObservableSet) { >+ return dbc.bindSet(targetObservableSet, modelObservableSet, >+ createT2MSetStrategy(), createM2TSetStrategy()); >+ } >+ >+ /** >+ * Creates a binding between a target and model observable set on the given >+ * binding context by creating new update strategies with the provided >+ * update policies which will be both configured with the state of this >+ * editing object before passing them to the binding. >+ * >+ * @param dbc >+ * The binding context on which to create the set binding. >+ * @param targetObservableSet >+ * The target observable set of the binding. >+ * @param modelObservableSet >+ * The model observable set of the binding. >+ * @param t2mUpdatePolicy >+ * The update policy for the target-to-model >+ * {@link UpdateSetStrategy} which is >+ * {@link #createT2MSetStrategy(int) created} and passed to the >+ * new binding. >+ * @param m2tUpdatePolicy >+ * The update policy for the model-to-target >+ * {@link UpdateSetStrategy} which is >+ * {@link #createM2TSetStrategy(int) created} and passed to the >+ * new binding. >+ * @return The new set binding. >+ * >+ * @see #createT2MSetStrategy(int) >+ * @see #createM2TSetStrategy(int) >+ * @see DataBindingContext#bindSet(IObservableSet, IObservableSet, >+ * UpdateSetStrategy, UpdateSetStrategy) >+ */ >+ public final Binding bindSet(DataBindingContext dbc, >+ IObservableSet targetObservableSet, >+ IObservableSet modelObservableSet, int t2mUpdatePolicy, >+ int m2tUpdatePolicy) { >+ return dbc.bindSet(targetObservableSet, modelObservableSet, >+ createT2MSetStrategy(t2mUpdatePolicy), >+ createM2TSetStrategy(m2tUpdatePolicy)); >+ } >+ >+ /** >+ * Creates a binding between a target and model observable set on the given >+ * binding context by using the provided update strategies which will be >+ * both configured with the state of this editing object before passing them >+ * to the binding. >+ * >+ * @param dbc >+ * The binding context on which to create the set binding. >+ * @param targetObservableSet >+ * The target observable set of the binding. >+ * @param modelObservableSet >+ * The model observable set of the binding. >+ * @param t2mUpdateStrategy >+ * The target-to-model {@link UpdateSetStrategy} of the binding >+ * to be {@link #adaptT2MSetStrategy(UpdateSetStrategy) >+ * configured} with the state of this editing object before >+ * passing it to the binding. >+ * @param m2tUpdateStrategy >+ * The model-to-target {@link UpdateSetStrategy} of the binding >+ * to be {@link #adaptM2TSetStrategy(UpdateSetStrategy) >+ * configured} with the state of this editing object before >+ * passing it to the binding. >+ * @return The new set binding. >+ * >+ * @see #adaptT2MSetStrategy(UpdateSetStrategy) >+ * @see #adaptM2TSetStrategy(UpdateSetStrategy) >+ * @see DataBindingContext#bindSet(IObservableSet, IObservableSet, >+ * UpdateSetStrategy, UpdateSetStrategy) >+ */ >+ public final Binding bindSet(DataBindingContext dbc, >+ IObservableSet targetObservableSet, >+ IObservableSet modelObservableSet, >+ UpdateSetStrategy t2mUpdateStrategy, >+ UpdateSetStrategy m2tUpdateStrategy) { >+ return dbc.bindSet(targetObservableSet, modelObservableSet, >+ adaptT2MSetStrategy(t2mUpdateStrategy), >+ adaptM2TSetStrategy(m2tUpdateStrategy)); >+ } >+ >+ private static IValidator createValidator(Constraints<?> constraints) { >+ return constraints != null ? constraints.createValidator() : null; >+ } >+ >+ private static boolean applyConstraints(Constraints<?> constraints, >+ Object value, MultiStatus aggregateStatus) { >+ IValidator validator = createValidator(constraints); >+ if (validator != null) { >+ IStatus validationStatus = validator.validate(value); >+ if (aggregateStatus != null && !validationStatus.isOK()) { >+ aggregateStatus.merge(validationStatus); >+ } >+ return isValid(validationStatus); >+ } >+ return true; >+ } >+ >+ private static Object applyConverter(IConverter converter, Object value) { >+ return converter != null ? converter.convert(value) : value; >+ } >+ >+ private static boolean isValid(IStatus status) { >+ return status.isOK() || status.matches(IStatus.INFO | IStatus.WARNING); >+ } >+} >Index: src/org/eclipse/core/databinding/validation/constraint/NumberConstraints.java >=================================================================== >RCS file: src/org/eclipse/core/databinding/validation/constraint/NumberConstraints.java >diff -N src/org/eclipse/core/databinding/validation/constraint/NumberConstraints.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/databinding/validation/constraint/NumberConstraints.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,396 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.validation.constraint; >+ >+import org.eclipse.core.internal.databinding.validation.DecimalPrecisionValidator; >+import org.eclipse.core.internal.databinding.validation.DecimalScaleValidator; >+import org.eclipse.core.internal.databinding.validation.NumberRangeValidator; >+ >+import com.ibm.icu.text.NumberFormat; >+ >+/** >+ * Provides a set of constraints to apply to number numbers. >+ * >+ * <p> >+ * Instances of this class can be used to define a set of constraints to apply >+ * to number numbers. In addition, the validation messages to be issued for the >+ * individual constraints as well as the way in which model objects are >+ * formatted in the validation messages can be configured. >+ * </p> >+ * >+ * @param <N> >+ * >+ * @noextend This class is not intended to be subclassed by clients. >+ * @since 1.3 >+ */ >+public class NumberConstraints<N extends Number & Comparable<N>> extends >+ BaseObjectConstraints<N, NumberConstraints<N>> { >+ >+ private NumberFormat numberFormat = NumberFormat.getNumberInstance(); >+ >+ private NumberFormat scaleFormat = NumberFormat.getIntegerInstance(); >+ >+ private NumberFormat precisionFormat = NumberFormat.getIntegerInstance(); >+ >+ private String greaterMessage = null; >+ >+ private String greaterEqualMessage = null; >+ >+ private String lessMessage = null; >+ >+ private String lessEqualMessage = null; >+ >+ private String rangeMessage = null; >+ >+ private String positiveMessage = null; >+ >+ private String nonNegativeMessage = null; >+ >+ private String maxScaleMessage = null; >+ >+ private String maxPrecisionMessage = null; >+ >+ /** >+ * Sets the format to use when formatting a number to be included in any of >+ * the validation messages. >+ * >+ * @param format >+ * The format to use for displaying numbers in validation >+ * messages. >+ * @return This constraints instance for method chaining. >+ */ >+ public NumberConstraints<N> numberFormat(NumberFormat format) { >+ this.numberFormat = format; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input number is greater than the given >+ * number. Uses the current {@link #greaterMessage(String) validation >+ * message} and {@link #numberFormat(NumberFormat) number format}. >+ * >+ * @param number >+ * The number which the input number must be greater than. >+ * @return This constraints instance for method chaining. >+ */ >+ public NumberConstraints<N> greater(N number) { >+ addValidator(NumberRangeValidator.greater(number, greaterMessage, >+ numberFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the {@link #greater(Number)} >+ * constraint. >+ * >+ * @param message >+ * The validation message pattern for the >+ * {@link #greater(Number)} constraint. Can be parameterized with >+ * the number ({0}) which the input number must be greater than. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #greater(Number) >+ */ >+ public NumberConstraints<N> greaterMessage(String message) { >+ this.greaterMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input number is greater than or equal >+ * to the given number. Uses the current >+ * {@link #greaterEqualMessage(String) validation message} and >+ * {@link #numberFormat(NumberFormat) number format}. >+ * >+ * @param number >+ * The number which the input number must be greater than or >+ * equal to. >+ * @return This constraints instance for method chaining. >+ */ >+ public NumberConstraints<N> greaterEqual(N number) { >+ addValidator(NumberRangeValidator.greaterEqual(number, >+ greaterEqualMessage, numberFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the {@link #greaterEqual(Number)} >+ * constraint. >+ * >+ * @param message >+ * The validation message pattern for the >+ * {@link #greaterEqual(Number)} constraint. Can be parameterized >+ * with the number ({0}) which the input number must be greater >+ * than or equal to. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #greaterEqual(Number) >+ */ >+ public NumberConstraints<N> greaterEqualMessage(String message) { >+ this.greaterEqualMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input number is less than the given >+ * number. Uses the current {@link #lessMessage(String) validation message} >+ * and {@link #numberFormat(NumberFormat) number format}. >+ * >+ * @param number >+ * The number which the input number must be less than. >+ * @return This constraints instance for method chaining. >+ */ >+ public NumberConstraints<N> less(N number) { >+ addValidator(NumberRangeValidator.less(number, lessMessage, >+ numberFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the {@link #less(Number)} >+ * constraint. >+ * >+ * @param message >+ * The validation message pattern for the {@link #less(Number)} >+ * constraint. Can be parameterized with the number ({0}) which >+ * the input number must be less than. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #less(Number) >+ */ >+ public NumberConstraints<N> lessMessage(String message) { >+ this.lessMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input number is less than or equal to >+ * the given number. Uses the current {@link #lessEqualMessage(String) >+ * validation message} and {@link #numberFormat(NumberFormat) number format} >+ * . >+ * >+ * @param number >+ * The number which the input number must be less than or equal >+ * to. >+ * @return This constraints instance for method chaining. >+ */ >+ public NumberConstraints<N> lessEqual(N number) { >+ addValidator(NumberRangeValidator.greaterEqual(number, >+ lessEqualMessage, numberFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the {@link #lessEqual(Number)} >+ * constraint. >+ * >+ * @param message >+ * The validation message pattern for the >+ * {@link #lessEqual(Number)} constraint. Can be parameterized >+ * with the number ({0}) which the input number must be less than >+ * or equal to. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #lessEqual(Number) >+ */ >+ public NumberConstraints<N> lessEqualMessage(String message) { >+ this.lessEqualMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input number is within the given >+ * range. Uses the current {@link #rangeMessage(String) validation message} >+ * and {@link #numberFormat(NumberFormat) number format}. >+ * >+ * @param min >+ * The lower bound of the range (inclusive). >+ * @param max >+ * The upper bound of the range (inclusive). >+ * @return This constraints instance for method chaining. >+ */ >+ public NumberConstraints<N> range(N min, N max) { >+ addValidator(NumberRangeValidator.range(min, max, rangeMessage, >+ numberFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the >+ * {@link #range(Number, Number)} constraint. >+ * >+ * @param message >+ * The validation message pattern for the >+ * {@link #range(Number, Number)} constraint. Can be >+ * parameterized with the min ({0}) and max ({1}) values of the >+ * range in which the input number must lie. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #range(Number, Number) >+ */ >+ public NumberConstraints<N> rangeMessage(String message) { >+ this.rangeMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input number is positive. Uses the >+ * current {@link #positiveMessage(String) validation message}. >+ * >+ * @return This constraints instance for method chaining. >+ */ >+ public NumberConstraints<N> positive() { >+ // FIXME omallo: Need the number 1 with the correct number type. >+ addValidator(NumberRangeValidator.positive(new Long(1), >+ positiveMessage, numberFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message for the {@link #positive()} constraint. >+ * >+ * @param message >+ * The validation message for the {@link #positive()} constraint. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #positive() >+ */ >+ public NumberConstraints<N> positiveMessage(String message) { >+ this.positiveMessage = message; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input number is non-negative. Uses the >+ * current {@link #nonNegativeMessage(String) validation message}. >+ * >+ * @return This constraints instance for method chaining. >+ */ >+ public NumberConstraints<N> nonNegative() { >+ // FIXME omallo: Need the number 0 with the correct number type. >+ addValidator(NumberRangeValidator.nonNegative(new Long(0), >+ nonNegativeMessage, numberFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message for the {@link #nonNegative()} constraint. >+ * >+ * @param message >+ * The validation message for the {@link #nonNegative()} >+ * constraint. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #nonNegative() >+ */ >+ public NumberConstraints<N> nonNegativeMessage(String message) { >+ this.nonNegativeMessage = message; >+ return this; >+ } >+ >+ /** >+ * Sets the format to use when formatting the scale in any of the validation >+ * messages stemming from a scale constraint. >+ * >+ * @param format >+ * The format to use for displaying the scale in validation >+ * messages stemming from a scale constraint. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #maxScale(int) >+ */ >+ public NumberConstraints<N> scaleFormat(NumberFormat format) { >+ this.scaleFormat = format; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input number's scale is not greater >+ * than the given one. Uses the current {@link #maxScaleMessage(String) >+ * validation message} and {@link #scaleFormat(NumberFormat) scale format}. >+ * >+ * @param scale >+ * The maximum scale to enforce on the input number. >+ * @return This constraints instance for method chaining. >+ */ >+ public NumberConstraints<N> maxScale(int scale) { >+ addValidator(DecimalScaleValidator.max(scale, maxScaleMessage, >+ scaleFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the {@link #maxScale(int)} >+ * constraint. >+ * >+ * @param message >+ * The validation message pattern for the {@link #maxScale(int)} >+ * constraint. Can be parameterized with the maximum scale ({0}) >+ * of the number. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #maxScale(int) >+ */ >+ public NumberConstraints<N> maxScaleMessage(String message) { >+ this.maxScaleMessage = message; >+ return this; >+ } >+ >+ /** >+ * Sets the format to use when formatting the precision in any of the >+ * validation messages stemming from a precision constraint. >+ * >+ * @param format >+ * The format to use for displaying the precision in validation >+ * messages stemming from a precision constraint. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #maxPrecision(int) >+ */ >+ public NumberConstraints<N> precisionFormat(NumberFormat format) { >+ this.precisionFormat = format; >+ return this; >+ } >+ >+ /** >+ * Adds a validator ensuring that the input number's precision is not >+ * greater than the given one. Uses the current >+ * {@link #maxPrecisionMessage(String) validation message} and >+ * {@link #precisionFormat(NumberFormat) precision format}. >+ * >+ * @param precision >+ * The maximum precision to enforce on the input number. >+ * @return This constraints instance for method chaining. >+ */ >+ public NumberConstraints<N> maxPrecision(int precision) { >+ addValidator(DecimalPrecisionValidator.max(precision, >+ maxPrecisionMessage, precisionFormat)); >+ return this; >+ } >+ >+ /** >+ * Sets the validation message pattern for the {@link #maxPrecision(int)} >+ * constraint. >+ * >+ * @param message >+ * The validation message pattern for the >+ * {@link #maxPrecision(int)} constraint. Can be parameterized >+ * with the maximum precision ({0}) of the number. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #maxPrecision(int) >+ */ >+ public NumberConstraints<N> maxPrecisionMessage(String message) { >+ this.maxPrecisionMessage = message; >+ return this; >+ } >+} >Index: src/org/eclipse/core/databinding/validation/constraint/BaseObjectConstraints.java >=================================================================== >RCS file: src/org/eclipse/core/databinding/validation/constraint/BaseObjectConstraints.java >diff -N src/org/eclipse/core/databinding/validation/constraint/BaseObjectConstraints.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/databinding/validation/constraint/BaseObjectConstraints.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,67 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.validation.constraint; >+ >+import org.eclipse.core.databinding.validation.IValidator; >+import org.eclipse.core.internal.databinding.validation.NonNullValidator; >+ >+/** >+ * @param <T> >+ * @param <C> >+ * >+ * @since 1.3 >+ */ >+public class BaseObjectConstraints<T, C extends BaseObjectConstraints<T, C>> >+ extends Constraints<T> { >+ >+ private String requiredMessage = null; >+ >+ public C addValidator(IValidator validator) { >+ super.addValidator(validator); >+ return getThis(); >+ } >+ >+ public C aggregationPolicy(Aggregation aggregation) { >+ super.aggregationPolicy(aggregation); >+ return getThis(); >+ } >+ >+ /** >+ * Adds a validator ensuring that the input number is not <code>null</code> >+ * . Uses the current {@link #requiredMessage(String) validation message}. >+ * >+ * @return This constraints instance for method chaining. >+ */ >+ public C required() { >+ addValidator(new NonNullValidator(requiredMessage)); >+ return getThis(); >+ } >+ >+ /** >+ * Sets the validation message for the {@link #required()} constraint. >+ * >+ * @param message >+ * The validation message for the {@link #required()} constraint. >+ * @return This constraints instance for method chaining. >+ * >+ * @see #required() >+ */ >+ public C requiredMessage(String message) { >+ this.requiredMessage = message; >+ return getThis(); >+ } >+ >+ @SuppressWarnings("unchecked") >+ private C getThis() { >+ return (C) this; >+ } >+} >Index: src/org/eclipse/core/internal/databinding/validation/DecimalScaleValidator.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/validation/DecimalScaleValidator.java >diff -N src/org/eclipse/core/internal/databinding/validation/DecimalScaleValidator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/validation/DecimalScaleValidator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,99 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.validation; >+ >+import java.text.MessageFormat; >+ >+import org.eclipse.core.databinding.validation.IValidator; >+import org.eclipse.core.databinding.validation.ValidationStatus; >+import org.eclipse.core.internal.databinding.BindingMessages; >+import org.eclipse.core.runtime.IStatus; >+ >+import com.ibm.icu.math.BigDecimal; >+import com.ibm.icu.text.NumberFormat; >+ >+/** >+ * Provides validations for the scale of decimal numbers. >+ * >+ * @since 1.3 >+ */ >+public class DecimalScaleValidator implements IValidator { >+ >+ private static final String MAX_SCALE_VALIDATION_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_DECIMAL_MAX_SCALE); >+ >+ private final int maxScale; >+ >+ private final String validationMessage; >+ >+ private String formattedValidationMessage; >+ >+ private final NumberFormat scaleFormat; >+ >+ private DecimalScaleValidator(int maxScale, String validationMessage, >+ NumberFormat scaleFormat) { >+ this.maxScale = maxScale; >+ this.validationMessage = validationMessage != null ? validationMessage >+ : MAX_SCALE_VALIDATION_MESSAGE; >+ this.scaleFormat = scaleFormat; >+ } >+ >+ /** >+ * Creates a validator which checks that an input decimal has a scale which >+ * is less or equal to the given scale. >+ * >+ * @param maxScale >+ * The maximum scale to enforce on the input decimal. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the maximum scale to be enforced. >+ * @param scaleFormat >+ * The display format to use for formatting the scale in the >+ * validation message. >+ * @return The validator instance. >+ */ >+ public static DecimalScaleValidator max(int maxScale, >+ String validationMessage, NumberFormat scaleFormat) { >+ return new DecimalScaleValidator(maxScale, validationMessage, >+ scaleFormat); >+ } >+ >+ public IStatus validate(Object value) { >+ if (value != null) { >+ Number number = (Number) value; >+ final int scale; >+ if (number instanceof BigDecimal) { >+ scale = ((BigDecimal) number).scale(); >+ } else { >+ scale = new BigDecimal(number.doubleValue()).scale(); >+ } >+ if (scale > maxScale) { >+ return ValidationStatus.error(getFormattedValidationMessage()); >+ } >+ } >+ return ValidationStatus.ok(); >+ } >+ >+ private synchronized String getFormattedValidationMessage() { >+ if (formattedValidationMessage == null) { >+ formattedValidationMessage = MessageFormat.format( >+ validationMessage, getValidationMessageArguments()); >+ } >+ return formattedValidationMessage; >+ } >+ >+ private String[] getValidationMessageArguments() { >+ synchronized (scaleFormat) { >+ return new String[] { scaleFormat.format(new Integer(maxScale)) }; >+ } >+ } >+} >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,155 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.editing; >+ >+import java.util.Date; >+ >+import org.eclipse.core.databinding.validation.constraint.DateConstraints; >+import org.eclipse.core.databinding.validation.constraint.StringConstraints; >+import org.eclipse.core.internal.databinding.conversion.DateToStringConverter; >+import org.eclipse.core.internal.databinding.conversion.StringToDateConverter; >+import org.eclipse.core.internal.databinding.validation.StringToDateValidator; >+ >+import com.ibm.icu.text.DateFormat; >+ >+/** >+ * @noextend This class is not intended to be subclassed by clients. >+ * @since 1.3 >+ */ >+public class DateEditing extends Editing<String, Date> { >+ >+ private final DateFormat displayFormat; >+ >+ /** >+ * Creates a new editing object for <code>Date</code>s. >+ * >+ * @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. >+ * >+ * @noreference This constructor is not intended to be referenced by >+ * clients. >+ */ >+ protected DateEditing(DateFormat[] inputFormats, String parseErrorMessage, >+ DateFormat displayFormat) { >+ this.displayFormat = displayFormat; >+ >+ StringToDateConverter targetConverter = new StringToDateConverter(); >+ if (inputFormats != null) { >+ targetConverter.setFormatters(inputFormats); >+ } >+ >+ DateToStringConverter modelConverter = new DateToStringConverter(); >+ if (displayFormat != null) { >+ modelConverter.setFormatters(new DateFormat[] { displayFormat }); >+ } >+ >+ StringToDateValidator targetValidator = new StringToDateValidator( >+ targetConverter); >+ if (parseErrorMessage != null) { >+ targetValidator.setParseErrorMessage(parseErrorMessage); >+ } >+ >+ setTargetConverter(targetConverter); >+ setModelConverter(modelConverter); >+ targetConstraints().addValidator(targetValidator); >+ } >+ >+ /** >+ * 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 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); >+ } >+ >+ public StringConstraints targetConstraints() { >+ return (StringConstraints) super.targetConstraints(); >+ } >+ >+ public DateConstraints modelConstraints() { >+ return (DateConstraints) super.modelConstraints(); >+ } >+ >+ public DateConstraints beforeSetModelConstraints() { >+ return (DateConstraints) super.beforeSetModelConstraints(); >+ } >+ >+ protected StringConstraints createTargetConstraints() { >+ return new StringConstraints(); >+ } >+ >+ protected DateConstraints createModelConstraints() { >+ return new DateConstraints().dateFormat(displayFormat); >+ } >+ >+ protected DateConstraints createBeforeSetModelConstraints() { >+ return new DateConstraints().dateFormat(displayFormat); >+ } >+} >Index: src/org/eclipse/core/internal/databinding/validation/StringRegexValidator.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/validation/StringRegexValidator.java >diff -N src/org/eclipse/core/internal/databinding/validation/StringRegexValidator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/validation/StringRegexValidator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,83 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.validation; >+ >+import java.text.MessageFormat; >+import java.util.regex.Matcher; >+import java.util.regex.Pattern; >+ >+import org.eclipse.core.databinding.validation.IValidator; >+import org.eclipse.core.databinding.validation.ValidationStatus; >+import org.eclipse.core.internal.databinding.BindingMessages; >+import org.eclipse.core.runtime.IStatus; >+ >+/** >+ * Provides validations for strings which must match a given regular expression. >+ * >+ * @since 1.3 >+ */ >+public class StringRegexValidator implements IValidator { >+ >+ private static final String REGEX_VALIDATION_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_STRING_REGEX); >+ >+ private final Pattern pattern; >+ private final String validationMessage; >+ private String formattedValidationMessage; >+ >+ /** >+ * Creates a new regex validator. >+ * >+ * @param regex >+ * The regular expression which the input string must match. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the given regular expression string. >+ */ >+ public StringRegexValidator(String regex, String validationMessage) { >+ this(Pattern.compile(regex), validationMessage); >+ } >+ >+ /** >+ * Creates a new regex validator. >+ * >+ * @param pattern >+ * The pattern which the input string must match. >+ * @param validationMessage >+ * The validation message pattern to use. Can be parameterized >+ * with the given regular expression string. >+ */ >+ public StringRegexValidator(Pattern pattern, String validationMessage) { >+ this.pattern = pattern; >+ this.validationMessage = validationMessage != null ? validationMessage >+ : REGEX_VALIDATION_MESSAGE; >+ } >+ >+ public IStatus validate(Object value) { >+ String input = (String) value; >+ if (input != null) { >+ Matcher matcher = pattern.matcher(input); >+ if (!matcher.matches()) { >+ return ValidationStatus.error(getFormattedValidationMessage()); >+ } >+ } >+ return ValidationStatus.ok(); >+ } >+ >+ private synchronized String getFormattedValidationMessage() { >+ if (formattedValidationMessage == null) { >+ formattedValidationMessage = MessageFormat.format( >+ validationMessage, new String[] { pattern.pattern() }); >+ } >+ return formattedValidationMessage; >+ } >+} >Index: src/org/eclipse/core/internal/databinding/validation/CharacterValidator.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/validation/CharacterValidator.java >diff -N src/org/eclipse/core/internal/databinding/validation/CharacterValidator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/validation/CharacterValidator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,145 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+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.internal.databinding.BindingMessages; >+import org.eclipse.core.runtime.IStatus; >+ >+/** >+ * @since 1.3 >+ */ >+public class CharacterValidator implements IValidator { >+ >+ private static final int VALIDATE_NO_WHITESPACE = 0; >+ private static final int VALIDATE_NO_SPACE = 1; >+ private static final int VALIDATE_LETTER = 2; >+ private static final int VALIDATE_DIGIT = 3; >+ private static final int VALIDATE_LETTER_OR_DIGIT = 4; >+ >+ private static final String NO_WHITESPACE_VALIDATION_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_CHARACTER_NO_WHITESPACE); >+ private static final String NO_SPACE_VALIDATION_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_CHARACTER_NO_SPACE); >+ private static final String LETTER_VALIDATION_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_CHARACTER_LETTER); >+ private static final String DIGIT_VALIDATION_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_CHARACTER_DIGIT); >+ private static final String LETTER_OR_DIGIT_VALIDATION_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_CHARACTER_LETTER_OR_DIGIT); >+ >+ private final int validation; >+ private final String validationMessage; >+ >+ private CharacterValidator(int validation, String validationMessage) { >+ this.validation = validation; >+ this.validationMessage = validationMessage; >+ } >+ >+ /** >+ * Creates a validator which checks that an input character is no >+ * {@link Character#isWhitespace(char) whitespace}. >+ * >+ * @param validationMessage >+ * The validation message to use. >+ * @return The validator instance. >+ */ >+ public static CharacterValidator noWhitespace(String validationMessage) { >+ return new CharacterValidator(VALIDATE_NO_WHITESPACE, defaultIfNull( >+ NO_WHITESPACE_VALIDATION_MESSAGE, validationMessage)); >+ } >+ >+ /** >+ * Creates a validator which checks that an input character is no >+ * {@link Character#isSpaceChar(char) space}. >+ * >+ * @param validationMessage >+ * The validation message to use. >+ * @return The validator instance. >+ */ >+ public static CharacterValidator noSpace(String validationMessage) { >+ return new CharacterValidator(VALIDATE_NO_SPACE, defaultIfNull( >+ NO_SPACE_VALIDATION_MESSAGE, validationMessage)); >+ } >+ >+ /** >+ * Creates a validator which checks that an input character is a >+ * {@link Character#isLetter(char) letter}. >+ * >+ * @param validationMessage >+ * The validation message to use. >+ * @return The validator instance. >+ */ >+ public static CharacterValidator letter(String validationMessage) { >+ return new CharacterValidator(VALIDATE_LETTER, defaultIfNull( >+ LETTER_VALIDATION_MESSAGE, validationMessage)); >+ } >+ >+ /** >+ * Creates a validator which checks that an input character is a >+ * {@link Character#isDigit(char) digit}. >+ * >+ * @param validationMessage >+ * The validation message to use. >+ * @return The validator instance. >+ */ >+ public static CharacterValidator digit(String validationMessage) { >+ return new CharacterValidator(VALIDATE_DIGIT, defaultIfNull( >+ DIGIT_VALIDATION_MESSAGE, validationMessage)); >+ } >+ >+ /** >+ * Creates a validator which checks that an input character is a >+ * {@link Character#isLetterOrDigit(char) letter or ditig}. >+ * >+ * @param validationMessage >+ * The validation message to use. >+ * @return The validator instance. >+ */ >+ public static CharacterValidator letterOrDigit(String validationMessage) { >+ return new CharacterValidator(VALIDATE_LETTER_OR_DIGIT, defaultIfNull( >+ LETTER_OR_DIGIT_VALIDATION_MESSAGE, validationMessage)); >+ } >+ >+ public IStatus validate(Object value) { >+ if (value != null) { >+ char character = ((Character) value).charValue(); >+ if (!isValid(character)) { >+ return ValidationStatus.error(validationMessage); >+ } >+ } >+ return ValidationStatus.ok(); >+ } >+ >+ private boolean isValid(char character) { >+ switch (validation) { >+ case VALIDATE_NO_WHITESPACE: >+ return !Character.isWhitespace(character); >+ case VALIDATE_NO_SPACE: >+ return !Character.isSpaceChar(character); >+ case VALIDATE_LETTER: >+ return Character.isLetter(character); >+ case VALIDATE_DIGIT: >+ return Character.isDigit(character); >+ case VALIDATE_LETTER_OR_DIGIT: >+ return Character.isLetterOrDigit(character); >+ default: >+ throw new IllegalArgumentException( >+ "Unsupported validation: " + validation); //$NON-NLS-1$ >+ } >+ } >+ >+ private static String defaultIfNull(String string, String defaultString) { >+ return (string != null) ? string : defaultString; >+ } >+} >Index: src/org/eclipse/core/databinding/editing/CharacterEditing.java >=================================================================== >RCS file: src/org/eclipse/core/databinding/editing/CharacterEditing.java >diff -N src/org/eclipse/core/databinding/editing/CharacterEditing.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/databinding/editing/CharacterEditing.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,100 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.editing; >+ >+import org.eclipse.core.databinding.validation.constraint.CharacterConstraints; >+import org.eclipse.core.databinding.validation.constraint.StringConstraints; >+import org.eclipse.core.internal.databinding.conversion.CharacterToStringConverter; >+import org.eclipse.core.internal.databinding.conversion.StringToCharacterConverter; >+import org.eclipse.core.internal.databinding.validation.StringToCharacterValidator; >+ >+/** >+ * @noextend This class is not intended to be subclassed by clients. >+ * @since 1.3 >+ */ >+public class CharacterEditing extends Editing<String, Character> { >+ >+ /** >+ * Creates a new editing object for booleans. >+ * >+ * @param parseErrorMessage >+ * The validation message issued in case the input string is not >+ * a valid character. >+ * >+ * @noreference This constructor is not intended to be referenced by >+ * clients. >+ */ >+ protected CharacterEditing(String parseErrorMessage) { >+ StringToCharacterConverter targetConverter = new StringToCharacterConverter( >+ false); >+ CharacterToStringConverter modelConverter = CharacterToStringConverter >+ .fromCharacter(false); >+ >+ StringToCharacterValidator targetValidator = new StringToCharacterValidator( >+ targetConverter); >+ if (parseErrorMessage != null) { >+ targetValidator.setParseErrorMessage(parseErrorMessage); >+ } >+ >+ setTargetConverter(targetConverter); >+ setModelConverter(modelConverter); >+ targetConstraints().addValidator(targetValidator); >+ } >+ >+ /** >+ * Creates a new editing object which uses the default validations and >+ * conversions for the editing of characters. >+ * >+ * @return The new editing object for the default editing of characters. >+ */ >+ public static CharacterEditing withDefaults() { >+ return withDefaults(null); >+ } >+ >+ /** >+ * Creates a new editing object which uses the default validations and >+ * conversions for the editing of characters. Uses the specified custom >+ * validation message. >+ * >+ * @param parseErrorMessage >+ * The validation message issued in case the input string is not >+ * a valid character. >+ * @return The new editing object for the default editing of characters. >+ */ >+ public static CharacterEditing withDefaults(String parseErrorMessage) { >+ return new CharacterEditing(parseErrorMessage); >+ } >+ >+ public StringConstraints targetConstraints() { >+ return (StringConstraints) super.targetConstraints(); >+ } >+ >+ public CharacterConstraints modelConstraints() { >+ return (CharacterConstraints) super.modelConstraints(); >+ } >+ >+ public CharacterConstraints beforeSetModelConstraints() { >+ return (CharacterConstraints) super.beforeSetModelConstraints(); >+ } >+ >+ protected StringConstraints createTargetConstraints() { >+ return new StringConstraints(); >+ } >+ >+ protected CharacterConstraints createModelConstraints() { >+ return new CharacterConstraints(); >+ } >+ >+ protected CharacterConstraints createBeforeSetModelConstraints() { >+ return new CharacterConstraints(); >+ } >+} >Index: src/org/eclipse/core/internal/databinding/validation/StringToBigIntegerValidator.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/validation/StringToBigIntegerValidator.java >diff -N src/org/eclipse/core/internal/databinding/validation/StringToBigIntegerValidator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/validation/StringToBigIntegerValidator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,32 @@ >+/******************************************************************************* >+ * Copyright (c) 2007 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.validation; >+ >+/** >+ * Validates that a string is of the appropriate format for a BigInteger. >+ * >+ * @since 1.3 >+ */ >+public class StringToBigIntegerValidator extends >+ AbstractStringToNumberValidator { >+ >+ /** >+ * @param converter >+ */ >+ public StringToBigIntegerValidator(NumberFormatConverter converter) { >+ super(converter, null, null); >+ } >+ >+ protected boolean isInRange(Number number) { >+ return true; >+ } >+} >Index: src/org/eclipse/core/databinding/editing/NumberEditing.java >=================================================================== >RCS file: src/org/eclipse/core/databinding/editing/NumberEditing.java >diff -N src/org/eclipse/core/databinding/editing/NumberEditing.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/databinding/editing/NumberEditing.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,732 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.databinding.editing; >+ >+import java.math.BigDecimal; >+import java.math.BigInteger; >+ >+import org.eclipse.core.databinding.conversion.NumberToStringConverter; >+import org.eclipse.core.databinding.conversion.StringToNumberConverter; >+import org.eclipse.core.databinding.validation.constraint.NumberConstraints; >+import org.eclipse.core.databinding.validation.constraint.StringConstraints; >+import org.eclipse.core.internal.databinding.validation.AbstractStringToNumberValidator; >+import org.eclipse.core.internal.databinding.validation.StringToBigDecimalValidator; >+import org.eclipse.core.internal.databinding.validation.StringToBigIntegerValidator; >+import org.eclipse.core.internal.databinding.validation.StringToByteValidator; >+import org.eclipse.core.internal.databinding.validation.StringToDoubleValidator; >+import org.eclipse.core.internal.databinding.validation.StringToFloatValidator; >+import org.eclipse.core.internal.databinding.validation.StringToIntegerValidator; >+import org.eclipse.core.internal.databinding.validation.StringToLongValidator; >+import org.eclipse.core.internal.databinding.validation.StringToShortValidator; >+ >+import com.ibm.icu.text.NumberFormat; >+ >+/** >+ * @param <N> >+ * >+ * @noextend This class is not intended to be subclassed by clients. >+ * @since 1.3 >+ */ >+public class NumberEditing<N extends Number & Comparable<N>> extends >+ Editing<String, N> { >+ >+ private final NumberFormat displayFormat; >+ >+ /** >+ * Creates a new editing object for integer numbers. >+ * >+ * @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. >+ * @param numberType >+ * The specific integer type for which to set up an editing >+ * instance. >+ * >+ * @noreference This constructor is not intended to be referenced by >+ * clients. >+ */ >+ protected NumberEditing(NumberFormat format, String parseErrorMessage, >+ String outOfRangeMessage, Class<N> numberType) { >+ this.displayFormat = format; >+ >+ final StringToNumberConverter targetConverter; >+ final NumberToStringConverter modelConverter; >+ final AbstractStringToNumberValidator targetValidator; >+ if (Long.class.equals(numberType)) { >+ targetConverter = StringToNumberConverter.toLong(format, false); >+ modelConverter = NumberToStringConverter.fromLong(format, false); >+ targetValidator = new StringToLongValidator(targetConverter); >+ } else if (Integer.class.equals(numberType)) { >+ targetConverter = StringToNumberConverter.toInteger(format, false); >+ modelConverter = NumberToStringConverter.fromInteger(format, false); >+ targetValidator = new StringToIntegerValidator(targetConverter); >+ } else if (Short.class.equals(numberType)) { >+ targetConverter = StringToNumberConverter.toShort(format, false); >+ modelConverter = NumberToStringConverter.fromShort(format, false); >+ targetValidator = new StringToShortValidator(targetConverter); >+ } else if (Byte.class.equals(numberType)) { >+ targetConverter = StringToNumberConverter.toByte(format, false); >+ modelConverter = NumberToStringConverter.fromByte(format, false); >+ targetValidator = new StringToByteValidator(targetConverter); >+ } else if (Double.class.equals(numberType)) { >+ targetConverter = StringToNumberConverter.toDouble(format, false); >+ modelConverter = NumberToStringConverter.fromDouble(format, false); >+ targetValidator = new StringToDoubleValidator(targetConverter); >+ } else if (Float.class.equals(numberType)) { >+ targetConverter = StringToNumberConverter.toFloat(format, false); >+ modelConverter = NumberToStringConverter.fromFloat(format, false); >+ targetValidator = new StringToFloatValidator(targetConverter); >+ } else if (BigInteger.class.equals(numberType)) { >+ targetConverter = StringToNumberConverter.toBigInteger(format); >+ modelConverter = NumberToStringConverter.fromBigInteger(format); >+ targetValidator = new StringToBigIntegerValidator(targetConverter); >+ } else if (BigDecimal.class.equals(numberType)) { >+ targetConverter = StringToNumberConverter.toBigDecimal(format); >+ modelConverter = NumberToStringConverter.fromBigDecimal(format); >+ targetValidator = new StringToBigDecimalValidator(targetConverter); >+ } else { >+ throw new IllegalArgumentException( >+ "Unsupported number type: " + numberType); //$NON-NLS-1$ >+ } >+ >+ if (parseErrorMessage != null) { >+ targetValidator.setParseErrorMessage(parseErrorMessage); >+ } >+ if (outOfRangeMessage != null) { >+ targetValidator.setOutOfRangeMessage(outOfRangeMessage); >+ } >+ >+ setTargetConverter(targetConverter); >+ setModelConverter(modelConverter); >+ targetConstraints().addValidator(targetValidator); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Long}s 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 NumberEditing<Long> withLongDefaults() { >+ return withLongDefaults(null, null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Long}s 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 <code>Long.MIN_VALUE</code> ({0}) and >+ * <code>Long.MAX_VALUE</code> ({1}) values. >+ * @return The new editing object using the default validations and >+ * conversions for editing. >+ * >+ * @see NumberFormat#getIntegerInstance() >+ */ >+ public static NumberEditing<Long> withLongDefaults( >+ String parseErrorMessage, String outOfRangeMessage) { >+ return new NumberEditing<Long>(NumberFormat.getIntegerInstance(), >+ parseErrorMessage, outOfRangeMessage, Long.class); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Long}s 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 NumberEditing<Long> forLongFormat(NumberFormat format) { >+ return forLongFormat(format, null, null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Long}s 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 <code>Long.MIN_VALUE</code> ({0}) and >+ * <code>Long.MAX_VALUE</code> ({1}) values. >+ * @return The new editing object configured by the given integer format. >+ */ >+ public static NumberEditing<Long> forLongFormat(NumberFormat format, >+ String parseErrorMessage, String outOfRangeMessage) { >+ return new NumberEditing<Long>(format, parseErrorMessage, >+ outOfRangeMessage, Long.class); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Integer}s 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 NumberEditing<Integer> withIntegerDefaults() { >+ return withIntegerDefaults(null, null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Integer}s 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 <code>Integer.MIN_VALUE</code> ({0}) and >+ * <code>Integer.MAX_VALUE</code> ({1}) values. >+ * @return The new editing object using the default validations and >+ * conversions for editing. >+ * >+ * @see NumberFormat#getIntegerInstance() >+ */ >+ public static NumberEditing<Integer> withIntegerDefaults( >+ String parseErrorMessage, String outOfRangeMessage) { >+ return new NumberEditing<Integer>(NumberFormat.getIntegerInstance(), >+ parseErrorMessage, outOfRangeMessage, Integer.class); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Integer}s 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 NumberEditing<Integer> forIntegerFormat(NumberFormat format) { >+ return forIntegerFormat(format, null, null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Integer}s 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 <code>Integer.MIN_VALUE</code> ({0}) and >+ * <code>Integer.MAX_VALUE</code> ({1}) values. >+ * @return The new editing object configured by the given integer format. >+ */ >+ public static NumberEditing<Integer> forIntegerFormat(NumberFormat format, >+ String parseErrorMessage, String outOfRangeMessage) { >+ return new NumberEditing<Integer>(format, parseErrorMessage, >+ outOfRangeMessage, Integer.class); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Short}s 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 NumberEditing<Short> withShortDefaults() { >+ return withShortDefaults(null, null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Short}s 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 <code>Short.MIN_VALUE</code> ({0}) and >+ * <code>Short.MAX_VALUE</code> ({1}) values. >+ * @return The new editing object using the default validations and >+ * conversions for editing. >+ * >+ * @see NumberFormat#getIntegerInstance() >+ */ >+ public static NumberEditing<Short> withShortDefaults( >+ String parseErrorMessage, String outOfRangeMessage) { >+ return new NumberEditing<Short>(NumberFormat.getIntegerInstance(), >+ parseErrorMessage, outOfRangeMessage, Short.class); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Short}s 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 NumberEditing<Short> forShortFormat(NumberFormat format) { >+ return forShortFormat(format, null, null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Short}s 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 <code>Short.MIN_VALUE</code> ({0}) and >+ * <code>Short.MAX_VALUE</code> ({1}) values. >+ * @return The new editing object configured by the given integer format. >+ */ >+ public static NumberEditing<Short> forShortFormat(NumberFormat format, >+ String parseErrorMessage, String outOfRangeMessage) { >+ return new NumberEditing<Short>(format, parseErrorMessage, >+ outOfRangeMessage, Short.class); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Byte}s 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 NumberEditing<Byte> withByteDefaults() { >+ return withByteDefaults(null, null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Byte}s 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 <code>Byte.MIN_VALUE</code> ({0}) and >+ * <code>Byte.MAX_VALUE</code> ({1}) values. >+ * @return The new editing object using the default validations and >+ * conversions for editing. >+ * >+ * @see NumberFormat#getIntegerInstance() >+ */ >+ public static NumberEditing<Byte> withByteDefaults( >+ String parseErrorMessage, String outOfRangeMessage) { >+ return new NumberEditing<Byte>(NumberFormat.getIntegerInstance(), >+ parseErrorMessage, outOfRangeMessage, Byte.class); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Byte}s 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 NumberEditing<Byte> forByteFormat(NumberFormat format) { >+ return forByteFormat(format, null, null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Byte}s 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 <code>Byte.MIN_VALUE</code> ({0}) and >+ * <code>Byte.MAX_VALUE</code> ({1}) values. >+ * @return The new editing object configured by the given integer format. >+ */ >+ public static NumberEditing<Byte> forByteFormat(NumberFormat format, >+ String parseErrorMessage, String outOfRangeMessage) { >+ return new NumberEditing<Byte>(format, parseErrorMessage, >+ outOfRangeMessage, Byte.class); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Double}s 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#getNumberInstance() >+ */ >+ public static NumberEditing<Double> withDoubleDefaults() { >+ return withDoubleDefaults(null, null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Double}s 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 a double. >+ * @param outOfRangeMessage >+ * The validation message issued in case the input string >+ * represents a double whose value is out of range. Can be >+ * parameterized by the <code>-Double.MAX_VALUE</code> ({0}) and >+ * <code>+Double.MAX_VALUE</code> ({1}) values. >+ * @return The new editing object using the default validations and >+ * conversions for editing. >+ * >+ * @see NumberFormat#getNumberInstance() >+ */ >+ public static NumberEditing<Double> withDoubleDefaults( >+ String parseErrorMessage, String outOfRangeMessage) { >+ return new NumberEditing<Double>(NumberFormat.getNumberInstance(), >+ parseErrorMessage, outOfRangeMessage, Double.class); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Double}s whose validations and >+ * conversions used for editing are based on the given number format. Uses >+ * the default validation messages. >+ * >+ * @param format >+ * The number format defining the validations and conversions >+ * used for editing. >+ * @return The new editing object configured by the given number format. >+ */ >+ public static NumberEditing<Double> forDoubleFormat(NumberFormat format) { >+ return forDoubleFormat(format, null, null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Double}s whose validations and >+ * conversions used for editing are based on the given number format. Uses >+ * the specified custom validation messages. >+ * >+ * @param format >+ * The number format defining the validations and conversions >+ * used for editing. >+ * @param parseErrorMessage >+ * The validation message issued in case the input string cannot >+ * be parsed to a double. >+ * @param outOfRangeMessage >+ * The validation message issued in case the input string >+ * represents a double whose value is out of range. Can be >+ * parameterized by the <code>-Double.MAX_VALUE</code> ({0}) and >+ * <code>+Double.MAX_VALUE</code> ({1}) values. >+ * @return The new editing object configured by the given number format. >+ */ >+ public static NumberEditing<Double> forDoubleFormat(NumberFormat format, >+ String parseErrorMessage, String outOfRangeMessage) { >+ return new NumberEditing<Double>(format, parseErrorMessage, >+ outOfRangeMessage, Double.class); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Float}s 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#getNumberInstance() >+ */ >+ public static NumberEditing<Float> withFloatDefaults() { >+ return withFloatDefaults(null, null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Float}s 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 a double. >+ * @param outOfRangeMessage >+ * The validation message issued in case the input string >+ * represents a float whose value is out of range. Can be >+ * parameterized by the <code>-Float.MAX_VALUE</code> ({0}) and >+ * <code>+Float.MAX_VALUE</code> ({1}) values. >+ * @return The new editing object using the default validations and >+ * conversions for editing. >+ * >+ * @see NumberFormat#getNumberInstance() >+ */ >+ public static NumberEditing<Float> withFloatDefaults( >+ String parseErrorMessage, String outOfRangeMessage) { >+ return new NumberEditing<Float>(NumberFormat.getNumberInstance(), >+ parseErrorMessage, outOfRangeMessage, Float.class); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Float}s whose validations and >+ * conversions used for editing are based on the given number format. Uses >+ * the default validation messages. >+ * >+ * @param format >+ * The number format defining the validations and conversions >+ * used for editing. >+ * @return The new editing object configured by the given number format. >+ */ >+ public static NumberEditing<Float> forFloatFormat(NumberFormat format) { >+ return forFloatFormat(format, null, null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link Float}s whose validations and >+ * conversions used for editing are based on the given number format. Uses >+ * the specified custom validation messages. >+ * >+ * @param format >+ * The number format defining the validations and conversions >+ * used for editing. >+ * @param parseErrorMessage >+ * The validation message issued in case the input string cannot >+ * be parsed to a float. >+ * @param outOfRangeMessage >+ * The validation message issued in case the input string >+ * represents a float whose value is out of range. Can be >+ * parameterized by the <code>-Float.MAX_VALUE</code> ({0}) and >+ * <code>+Float.MAX_VALUE</code> ({1}) values. >+ * @return The new editing object configured by the given number format. >+ */ >+ public static NumberEditing<Float> forFloatFormat(NumberFormat format, >+ String parseErrorMessage, String outOfRangeMessage) { >+ return new NumberEditing<Float>(format, parseErrorMessage, >+ outOfRangeMessage, Float.class); >+ } >+ >+ /** >+ * Creates a new editing object for {@link BigInteger}s 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 NumberEditing<BigInteger> withBigIntegerDefaults() { >+ return withBigIntegerDefaults(null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link BigInteger}s which defaults the >+ * validations and conversions used for editing based on the platform's >+ * locale. Uses the specified custom validation message. >+ * >+ * @param parseErrorMessage >+ * The validation message issued in case the input string cannot >+ * be parsed to a BigInteger. >+ * @return The new editing object using the default validations and >+ * conversions for editing. >+ * >+ * @see NumberFormat#getIntegerInstance() >+ */ >+ public static NumberEditing<BigInteger> withBigIntegerDefaults( >+ String parseErrorMessage) { >+ return new NumberEditing<BigInteger>(NumberFormat.getIntegerInstance(), >+ parseErrorMessage, null, BigInteger.class); >+ } >+ >+ /** >+ * Creates a new editing object for {@link BigInteger}s whose validations >+ * and conversions used for editing are based on the given BigInteger >+ * format. Uses the default validation messages. >+ * >+ * @param format >+ * The BigInteger format defining the validations and conversions >+ * used for editing. >+ * @return The new editing object configured by the given BigInteger format. >+ */ >+ public static NumberEditing<BigInteger> forBigIntegerFormat( >+ NumberFormat format) { >+ return forBigIntegerFormat(format, null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link BigInteger}s whose validations >+ * and conversions used for editing are based on the given BigInteger >+ * format. Uses the specified custom validation message. >+ * >+ * @param format >+ * The BigInteger format defining the validations and conversions >+ * used for editing. >+ * @param parseErrorMessage >+ * The validation message issued in case the input string cannot >+ * be parsed to a BigInteger. >+ * @return The new editing object configured by the given BigInteger format. >+ */ >+ public static NumberEditing<BigInteger> forBigIntegerFormat( >+ NumberFormat format, String parseErrorMessage) { >+ return new NumberEditing<BigInteger>(format, parseErrorMessage, null, >+ BigInteger.class); >+ } >+ >+ /** >+ * Creates a new editing object for {@link BigDecimal}s 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#getNumberInstance() >+ */ >+ public static NumberEditing<BigDecimal> withBigDecimalDefaults() { >+ return withBigDecimalDefaults(null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link BigDecimal}s which defaults the >+ * validations and conversions used for editing based on the platform's >+ * locale. Uses the specified custom validation message. >+ * >+ * @param parseErrorMessage >+ * The validation message issued in case the input string cannot >+ * be parsed to a BigDecimal. >+ * @return The new editing object using the default validations and >+ * conversions for editing. >+ * >+ * @see NumberFormat#getNumberInstance() >+ */ >+ public static NumberEditing<BigDecimal> withBigDecimalDefaults( >+ String parseErrorMessage) { >+ return new NumberEditing<BigDecimal>(NumberFormat.getNumberInstance(), >+ parseErrorMessage, null, BigDecimal.class); >+ } >+ >+ /** >+ * Creates a new editing object for {@link BigDecimal}s whose validations >+ * and conversions used for editing are based on the given BigDecimal >+ * format. Uses the default validation messages. >+ * >+ * @param format >+ * The BigDecimal format defining the validations and conversions >+ * used for editing. >+ * @return The new editing object configured by the given BigDecimal format. >+ */ >+ public static NumberEditing<BigDecimal> forBigDecimalFormat( >+ NumberFormat format) { >+ return forBigDecimalFormat(format, null); >+ } >+ >+ /** >+ * Creates a new editing object for {@link BigDecimal}s whose validations >+ * and conversions used for editing are based on the given BigDecimal >+ * format. Uses the specified custom validation message. >+ * >+ * @param format >+ * The BigDecimal format defining the validations and conversions >+ * used for editing. >+ * @param parseErrorMessage >+ * The validation message issued in case the input string cannot >+ * be parsed to a BigDecimal. >+ * @return The new editing object configured by the given BigDecimal format. >+ */ >+ public static NumberEditing<BigDecimal> forBigDecimalFormat( >+ NumberFormat format, String parseErrorMessage) { >+ return new NumberEditing<BigDecimal>(format, parseErrorMessage, null, >+ BigDecimal.class); >+ } >+ >+ public StringConstraints targetConstraints() { >+ return (StringConstraints) super.targetConstraints(); >+ } >+ >+ public NumberConstraints<N> modelConstraints() { >+ return (NumberConstraints<N>) super.modelConstraints(); >+ } >+ >+ public NumberConstraints<N> beforeSetModelConstraints() { >+ return (NumberConstraints<N>) super.beforeSetModelConstraints(); >+ } >+ >+ protected StringConstraints createTargetConstraints() { >+ return new StringConstraints(); >+ } >+ >+ protected NumberConstraints<N> createModelConstraints() { >+ return new NumberConstraints<N>().numberFormat(displayFormat); >+ } >+ >+ protected NumberConstraints<N> createBeforeSetModelConstraints() { >+ return new NumberConstraints<N>().numberFormat(displayFormat); >+ } >+} >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,43 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+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.internal.databinding.BindingMessages; >+import org.eclipse.core.runtime.IStatus; >+ >+/** >+ * @since 1.3 >+ */ >+public class NonNullValidator implements IValidator { >+ >+ private static final String NON_NULL_VALIDATION_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_NON_NULL); >+ >+ private final String validationMessage; >+ >+ /** >+ * @param validationMessage >+ */ >+ public NonNullValidator(String validationMessage) { >+ this.validationMessage = validationMessage != null ? validationMessage >+ : NON_NULL_VALIDATION_MESSAGE; >+ } >+ >+ public IStatus validate(Object value) { >+ if (value == null) { >+ return ValidationStatus.error(validationMessage); >+ } >+ return ValidationStatus.ok(); >+ } >+} >Index: src/org/eclipse/core/internal/databinding/conversion/BooleanToStringConverter.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/conversion/BooleanToStringConverter.java >diff -N src/org/eclipse/core/internal/databinding/conversion/BooleanToStringConverter.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/conversion/BooleanToStringConverter.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,60 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.conversion; >+ >+import org.eclipse.core.databinding.conversion.Converter; >+ >+/** >+ * @since 1.3 >+ */ >+public class BooleanToStringConverter extends Converter { >+ >+ // Those are the defaults used up to now in UpdateStrategy where a simple >+ // ObjectToStringConverter was used for converting booleans to strings. >+ // FIXME: Should/may we change this to convert to a localized string? >+ private String trueValue = Boolean.TRUE.toString(); >+ private String falseValue = Boolean.FALSE.toString(); >+ >+ /** >+ * Creates a new converter which converts a boolean to its default string >+ * representation. >+ * >+ * @param booleanType >+ * The boolean type. Must be one of {@code Boolean.TYPE} or >+ * {@code Boolean.class}. >+ */ >+ public BooleanToStringConverter(Class booleanType) { >+ super(booleanType, String.class); >+ } >+ >+ /** >+ * Sets the string values to which a <code>true</code> and >+ * <code>false</code> value should be converted. >+ * >+ * @param trueValue >+ * The string to which to convert a <code>true</code> value. >+ * @param falseValue >+ * The string to which to convert a <code>false</code> value. >+ */ >+ public final void setTargetStrings(String trueValue, String falseValue) { >+ this.trueValue = trueValue; >+ this.falseValue = falseValue; >+ } >+ >+ public Object convert(Object source) { >+ Boolean value = (Boolean) source; >+ if (value != null) { >+ return value.booleanValue() ? trueValue : falseValue; >+ } >+ return ""; //$NON-NLS-1$ >+ } >+} >Index: src/org/eclipse/core/internal/databinding/validation/NonEmptyStringValidator.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/validation/NonEmptyStringValidator.java >diff -N src/org/eclipse/core/internal/databinding/validation/NonEmptyStringValidator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/validation/NonEmptyStringValidator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,51 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+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.internal.databinding.BindingMessages; >+import org.eclipse.core.runtime.IStatus; >+ >+/** >+ * @since 1.3 >+ */ >+public class NonEmptyStringValidator implements IValidator { >+ >+ private static final String NON_EMPTY_STRING_VALIDATION_MESSAGE = BindingMessages >+ .getString(BindingMessages.VALIDATE_NON_EMPTY_STRING); >+ >+ private final String validationMessage; >+ >+ /** >+ * >+ */ >+ public NonEmptyStringValidator() { >+ this(null); >+ } >+ >+ /** >+ * @param validationMessage >+ */ >+ public NonEmptyStringValidator(String validationMessage) { >+ this.validationMessage = validationMessage != null ? validationMessage >+ : NON_EMPTY_STRING_VALIDATION_MESSAGE; >+ } >+ >+ public IStatus validate(Object value) { >+ String input = (String) value; >+ if (input == null || input.length() == 0) { >+ return ValidationStatus.error(validationMessage); >+ } >+ return ValidationStatus.ok(); >+ } >+} >Index: src/org/eclipse/core/internal/databinding/conversion/StringStripConverter.java >=================================================================== >RCS file: src/org/eclipse/core/internal/databinding/conversion/StringStripConverter.java >diff -N src/org/eclipse/core/internal/databinding/conversion/StringStripConverter.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/databinding/conversion/StringStripConverter.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,61 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Ovidio Mallo 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: >+ * Ovidio Mallo - initial API and implementation (bug 183055) >+ ******************************************************************************/ >+ >+package org.eclipse.core.internal.databinding.conversion; >+ >+import org.eclipse.core.databinding.conversion.Converter; >+ >+/** >+ * @since 1.3 >+ */ >+public class StringStripConverter extends Converter { >+ >+ private final boolean stripToNull; >+ >+ /** >+ * >+ * @param stripToNull >+ */ >+ public StringStripConverter(boolean stripToNull) { >+ super(String.class, String.class); >+ this.stripToNull = stripToNull; >+ } >+ >+ public Object convert(Object fromObject) { >+ String string = (String) fromObject; >+ >+ if (string != null && string.length() != 0) { >+ int stripStart = 0; >+ while (stripStart < string.length() >+ && Character.isWhitespace(string.charAt(stripStart))) { >+ stripStart++; >+ } >+ >+ int stripEnd = string.length() - 1; >+ while (stripEnd >= stripStart >+ && Character.isWhitespace(string.charAt(stripEnd))) { >+ stripEnd--; >+ } >+ >+ if (stripStart <= stripEnd) { >+ string = string.substring(stripStart, stripEnd + 1); >+ } else { >+ string = ""; //$NON-NLS-1$ >+ } >+ } >+ >+ if (stripToNull && string != null && string.length() == 0) { >+ string = null; >+ } >+ >+ return string; >+ } >+} >#P org.eclipse.jface.tests.databinding >Index: src/org/eclipse/core/tests/internal/databinding/BindingMessagesTest.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/BindingMessagesTest.java,v >retrieving revision 1.1 >diff -u -r1.1 BindingMessagesTest.java >--- src/org/eclipse/core/tests/internal/databinding/BindingMessagesTest.java 1 Apr 2007 20:58:10 -0000 1.1 >+++ src/org/eclipse/core/tests/internal/databinding/BindingMessagesTest.java 28 Feb 2010 23:33:40 -0000 >@@ -12,6 +12,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Ovidio Mallo - bug 183055 > ******************************************************************************/ > > /** >@@ -21,13 +22,13 @@ > public class BindingMessagesTest extends TestCase { > public void testFormatString() throws Exception { > String key = "Validate_NumberOutOfRangeError"; >- String result = BindingMessages.formatString(key, new Object[] {"1", "2"}); >+ String result = BindingMessages.getFormattedString(key, new Object[] {"1", "2"}); > assertFalse("key should not be returned", key.equals(result)); > } > > public void testFormatStringForKeyNotFound() throws Exception { > String key = "key_that_does_not_exist"; >- String result = BindingMessages.formatString(key, null); >+ String result = BindingMessages.getFormattedString(key, null); > assertTrue(key.equals(result)); > } > } >Index: .settings/org.eclipse.jdt.ui.prefs >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface.tests.databinding/.settings/org.eclipse.jdt.ui.prefs,v >retrieving revision 1.6 >diff -u -r1.6 org.eclipse.jdt.ui.prefs >--- .settings/org.eclipse.jdt.ui.prefs 16 Feb 2009 23:03:22 -0000 1.6 >+++ .settings/org.eclipse.jdt.ui.prefs 28 Feb 2010 23:33:39 -0000 >@@ -1,4 +1,4 @@ >-#Tue Feb 10 16:06:05 MST 2009 >+#Thu Jan 07 19:11:15 CET 2010 > cleanup.add_default_serial_version_id=true > cleanup.add_generated_serial_version_id=false > cleanup.add_missing_annotations=true >@@ -51,7 +51,7 @@ > cleanup_profile=org.eclipse.jdt.ui.default.eclipse_clean_up_profile > cleanup_settings_version=2 > eclipse.preferences.version=1 >-editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true >+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=false > formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile > formatter_settings_version=11 > org.eclipse.jdt.ui.exception.name=e
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 183055
:
139097
|
142074
|
145997
|
146005
|
146551
|
147262
|
149314
|
149326
|
151361
|
152082
|
153890
|
156294
|
156446
|
157017
|
157180
|
157378
|
157469
|
160440
|
160542
|
179211
|
179212