FIXED - bug 306611: [DataBinding] Converted value property
https://bugs.eclipse.org/bugs/show_bug.cgi?id=306611
diff --git a/bundles/org.eclipse.core.databinding/META-INF/MANIFEST.MF b/bundles/org.eclipse.core.databinding/META-INF/MANIFEST.MF
index 703e8b7..7eb6a40 100644
--- a/bundles/org.eclipse.core.databinding/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.core.databinding/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.core.databinding
-Bundle-Version: 1.3.100.qualifier
+Bundle-Version: 1.4.0.qualifier
 Bundle-ClassPath: .
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/databinding/BindingProperties.java b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/databinding/BindingProperties.java
index aae4869..0977bf9 100644
--- a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/databinding/BindingProperties.java
+++ b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/databinding/BindingProperties.java
@@ -8,16 +8,19 @@
  * Contributors:
  *     Matthew Hall - initial API and implementation (bug 263709)
  *     Matthew Hall - bug 264954
+ *     Ovidio Mallo - bug 306611
  ******************************************************************************/
 
 package org.eclipse.core.databinding;
 
+import org.eclipse.core.databinding.conversion.IConverter;
 import org.eclipse.core.databinding.observable.IObservable;
 import org.eclipse.core.databinding.property.Properties;
 import org.eclipse.core.databinding.property.list.IListProperty;
 import org.eclipse.core.databinding.property.value.IValueProperty;
 import org.eclipse.core.internal.databinding.BindingModelProperty;
 import org.eclipse.core.internal.databinding.BindingTargetProperty;
+import org.eclipse.core.internal.databinding.ConverterValueProperty;
 import org.eclipse.core.internal.databinding.DataBindingContextBindingsProperty;
 import org.eclipse.core.internal.databinding.DataBindingContextValidationStatusProvidersProperty;
 import org.eclipse.core.internal.databinding.ValidationStatusProviderModelsProperty;
@@ -111,4 +114,24 @@
 	public static IListProperty validationStatusProviders() {
 		return new DataBindingContextValidationStatusProvidersProperty();
 	}
+
+	/**
+	 * Returns an {@link IValueProperty} whose value results from applying the
+	 * given {@link IConverter} on the source object of the value property.
+	 * Consequently, the {@link IValueProperty#getValueType() value type} of the
+	 * returned property is the same as the {@link IConverter#getToType() target
+	 * type} of the converter. Setting a value on the property is not supported.
+	 * 
+	 * @param converter
+	 *            The converter to apply to the source object of the value
+	 *            property.
+	 * @return A new instance of a value property whose value is the result of
+	 *         applying the given converter to the source object passed to the
+	 *         value property.
+	 * 
+	 * @since 1.4
+	 */
+	public static IValueProperty convertedValue(IConverter converter) {
+		return new ConverterValueProperty(converter);
+	}
 }
diff --git a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ConverterValueProperty.java b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ConverterValueProperty.java
new file mode 100644
index 0000000..32ca3a7
--- /dev/null
+++ b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ConverterValueProperty.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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 306611)
+ ******************************************************************************/
+
+package org.eclipse.core.internal.databinding;
+
+import org.eclipse.core.databinding.conversion.IConverter;
+import org.eclipse.core.databinding.property.INativePropertyListener;
+import org.eclipse.core.databinding.property.ISimplePropertyListener;
+import org.eclipse.core.databinding.property.value.SimpleValueProperty;
+
+/**
+ * Simple value property which applies a given converter on a source object in
+ * order to produce the property's value.
+ */
+public class ConverterValueProperty extends SimpleValueProperty {
+
+	private final IConverter converter;
+
+	/**
+	 * Creates a new value property which applies the given converter on the
+	 * source object in order to produce the property's value.
+	 * 
+	 * @param converter
+	 *            The converter to apply to the source object.
+	 */
+	public ConverterValueProperty(IConverter converter) {
+		this.converter = converter;
+	}
+
+	public Object getValueType() {
+		// the property type is the converter's target type
+		return converter.getToType();
+	}
+
+	public Object getValue(Object source) {
+		// We do also pass null values to the converter.
+		return doGetValue(source);
+	}
+
+	protected Object doGetValue(Object source) {
+		// delegate to the IConverter
+		return converter.convert(source);
+	}
+
+	protected void doSetValue(Object source, Object value) {
+		// setting a value is not supported
+		throw new UnsupportedOperationException(toString()
+				+ ": Setter not supported on a converted value!"); //$NON-NLS-1$
+	}
+
+	public INativePropertyListener adaptListener(
+			ISimplePropertyListener listener) {
+		// no listener API
+		return null;
+	}
+
+	public String toString() {
+		return "IConverter#convert(source) <IConverter#getToType()>"; //$NON-NLS-1$
+	}
+}
diff --git a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/ConverterValuePropertyTest.java b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/ConverterValuePropertyTest.java
new file mode 100644
index 0000000..a99170f
--- /dev/null
+++ b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/ConverterValuePropertyTest.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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 306611)
+ ******************************************************************************/
+
+package org.eclipse.core.tests.internal.databinding;
+
+import org.eclipse.core.databinding.BindingProperties;
+import org.eclipse.core.databinding.conversion.IConverter;
+import org.eclipse.core.databinding.property.value.IValueProperty;
+import org.eclipse.core.internal.databinding.ConverterValueProperty;
+import org.eclipse.core.internal.databinding.conversion.ObjectToStringConverter;
+import org.eclipse.jface.tests.databinding.AbstractDefaultRealmTestCase;
+
+/**
+ * Tests for the {@link ConverterValueProperty} class.
+ */
+public class ConverterValuePropertyTest extends AbstractDefaultRealmTestCase {
+
+	private IConverter converter;
+
+	protected void setUp() throws Exception {
+		super.setUp();
+
+		converter = new ObjectToStringConverter(Integer.class);
+	}
+
+	public void testGetValue() {
+		IValueProperty property = BindingProperties.convertedValue(converter);
+
+		assertEquals("123", property.getValue(new Integer(123)));
+	}
+
+	public void testGetValueForNullSource() {
+		// The converter converts null to "".
+		IValueProperty property = BindingProperties.convertedValue(converter);
+
+		// null should also be converted rather than simply returning null.
+		assertEquals("", property.getValue(null));
+	}
+
+	public void testSetValue() {
+		IValueProperty property = BindingProperties.convertedValue(converter);
+
+		try {
+			property.setValue(new Integer(123), "123");
+			fail("setting a value should trigger an exception!");
+		} catch (UnsupportedOperationException e) {
+			// expected exception
+		}
+	}
+
+	public void testGetValueType() {
+		IValueProperty property = BindingProperties.convertedValue(converter);
+
+		assertEquals(converter.getToType(), property.getValueType());
+	}
+}
diff --git a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/jface/tests/databinding/BindingTestSuite.java b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/jface/tests/databinding/BindingTestSuite.java
index ac2417d..3c26247 100644
--- a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/jface/tests/databinding/BindingTestSuite.java
+++ b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/jface/tests/databinding/BindingTestSuite.java
@@ -17,7 +17,7 @@
  *                    246103, 249992, 256150, 256543, 262269, 175735, 262946,
  *                    255734, 263693, 169876, 266038, 268336, 270461, 271720,
  *                    283204, 281723, 283428
- *     Ovidio Mallo - bugs 237163, 235195, 299619
+ *     Ovidio Mallo - bugs 237163, 235195, 299619, 306611
  *******************************************************************************/
 package org.eclipse.jface.tests.databinding;
 
@@ -84,6 +84,7 @@
 import org.eclipse.core.tests.databinding.validation.ValidationStatusTest;
 import org.eclipse.core.tests.internal.databinding.BindingMessagesTest;
 import org.eclipse.core.tests.internal.databinding.BindingStatusTest;
+import org.eclipse.core.tests.internal.databinding.ConverterValuePropertyTest;
 import org.eclipse.core.tests.internal.databinding.IdentityMapTest;
 import org.eclipse.core.tests.internal.databinding.IdentitySetTest;
 import org.eclipse.core.tests.internal.databinding.QueueTest;
@@ -316,6 +317,7 @@
 		// org.eclipse.core.tests.internal.databinding
 		addTestSuite(BindingMessagesTest.class);
 		addTestSuite(BindingStatusTest.class);
+		addTestSuite(ConverterValuePropertyTest.class);
 		addTestSuite(IdentityMapTest.class);
 		addTestSuite(IdentitySetTest.class);
 		addTestSuite(QueueTest.class);