Bug 311907 - Support conversion of @Preference types
diff --git a/bundles/org.eclipse.e4.core.di.extensions/src/org/eclipse/e4/core/di/internal/extensions/PreferencesObjectSupplier.java b/bundles/org.eclipse.e4.core.di.extensions/src/org/eclipse/e4/core/di/internal/extensions/PreferencesObjectSupplier.java index 68f8615..caa1e07 100644 --- a/bundles/org.eclipse.e4.core.di.extensions/src/org/eclipse/e4/core/di/internal/extensions/PreferencesObjectSupplier.java +++ b/bundles/org.eclipse.e4.core.di.extensions/src/org/eclipse/e4/core/di/internal/extensions/PreferencesObjectSupplier.java
@@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.e4.core.di.internal.extensions; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -26,6 +28,9 @@ import org.eclipse.e4.core.di.suppliers.IRequestor; import org.osgi.framework.FrameworkUtil; +/** + * Note: we do not support byte arrays in preferences at this time. + */ public class PreferencesObjectSupplier extends ExtendedObjectSupplier { private Map<String, List<IRequestor>> listenerCache = new HashMap<String, List<IRequestor>>(); @@ -45,9 +50,48 @@ if (track) addListener(nodePath, requestor); - // TBD add auto-conversion depending on the descriptor's desired type - Object result = getPreferencesService().getString(nodePath, key, null, null); - return result; + + Class<?> descriptorsClass = getDesiredClass(descriptor.getDesiredType()); + if (descriptorsClass.isPrimitive()) { + if (descriptorsClass.equals(boolean.class)) + return getPreferencesService().getBoolean(nodePath, key, false, null); + else if (descriptorsClass.equals(int.class)) + return getPreferencesService().getInt(nodePath, key, 0, null); + else if (descriptorsClass.equals(double.class)) + return getPreferencesService().getDouble(nodePath, key, 0.0d, null); + else if (descriptorsClass.equals(float.class)) + return getPreferencesService().getFloat(nodePath, key, 0.0f, null); + else if (descriptorsClass.equals(long.class)) + return getPreferencesService().getLong(nodePath, key, 0L, null); + } + + if (String.class.equals(descriptorsClass)) + return getPreferencesService().getString(nodePath, key, null, null); + else if (Boolean.class.equals(descriptorsClass)) + return getPreferencesService().getBoolean(nodePath, key, false, null); + else if (Boolean.class.equals(descriptorsClass)) + return getPreferencesService().getBoolean(nodePath, key, false, null); + else if (Integer.class.equals(descriptorsClass)) + return getPreferencesService().getInt(nodePath, key, 0, null); + else if (Double.class.equals(descriptorsClass)) + return getPreferencesService().getDouble(nodePath, key, 0.0d, null); + else if (Float.class.equals(descriptorsClass)) + return getPreferencesService().getFloat(nodePath, key, 0.0f, null); + else if (Long.class.equals(descriptorsClass)) + return getPreferencesService().getLong(nodePath, key, 0L, null); + + return getPreferencesService().getString(nodePath, key, null, null); + } + + private Class<?> getDesiredClass(Type desiredType) { + if (desiredType instanceof Class<?>) + return (Class<?>) desiredType; + if (desiredType instanceof ParameterizedType) { + Type rawType = ((ParameterizedType) desiredType).getRawType(); + if (rawType instanceof Class<?>) + return (Class<?>) rawType; + } + return null; } private String getKey(IObjectDescriptor descriptor) {
diff --git a/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/di/extensions/InjectionPreferencesTest.java b/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/di/extensions/InjectionPreferencesTest.java index 8184bea..6695355 100644 --- a/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/di/extensions/InjectionPreferencesTest.java +++ b/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/di/extensions/InjectionPreferencesTest.java
@@ -10,8 +10,6 @@ ******************************************************************************/ package org.eclipse.e4.core.internal.tests.di.extensions; -import java.lang.reflect.InvocationTargetException; - import javax.inject.Inject; import junit.framework.TestCase; @@ -26,12 +24,21 @@ import org.eclipse.e4.core.internal.tests.CoreTestsActivator; import org.osgi.service.prefs.BackingStoreException; -// TBD add auto-conversion? +/** + * Note: we do not support byte arrays at this time. + */ public class InjectionPreferencesTest extends TestCase { static final private String TEST_PREFS_KEY = "testPreferencesQualifier"; static final private String TEST_PREFS_NODE = "org.eclipse.e4.core.tests.ext"; + static final private String KEY_INT = "testPreferencesInt"; + static final private String KEY_BOOL = "testPreferencesBoolean"; + static final private String KEY_DOUBLE = "testPreferencesDouble"; + static final private String KEY_FLOAT = "testPreferencesFloat"; + static final private String KEY_LONG = "testPreferencesLong"; +// static final private String KEY_BYTE_ARRAY = "testPreferencesByteArray"; + static class InjectTarget { public int counter = 0; public int counterNode = 0; @@ -62,11 +69,66 @@ } } - public void testPreferencesQualifier() throws BackingStoreException, InvocationTargetException, InstantiationException { + static class InjectTargetPrimitive { + @Inject @Preference(KEY_INT) + public int intField; + + @Inject @Preference(KEY_BOOL) + public boolean booleanField; + + @Inject @Preference(KEY_DOUBLE) + public double doubleField; + + @Inject @Preference(KEY_FLOAT) + public float floatField; + + @Inject @Preference(KEY_LONG) + public long longField; + +// @Inject @Preference(KEY_BYTE_ARRAY) +// public byte[] byteArrayField; + + public int intArg; + public boolean booleanArg; + + @Inject + public void set(@Preference(KEY_INT) int intArg, @Preference(KEY_BOOL) boolean booleanArg) { + this.intArg = intArg; + this.booleanArg = booleanArg; + } + } + + static class InjectTargetConversion { + @Inject @Preference(KEY_INT) + public Integer intField; + + @Inject @Preference(KEY_BOOL) + public Boolean booleanField; + + @Inject @Preference(KEY_DOUBLE) + public Double doubleField; + + @Inject @Preference(KEY_FLOAT) + public Float floatField; + + @Inject @Preference(KEY_LONG) + public Long longField; + + public Integer intArg; + public Boolean booleanArg; + + @Inject + public void set(@Preference(KEY_INT) Integer intArg, @Preference(KEY_BOOL) Boolean booleanArg) { + this.intArg = intArg; + this.booleanArg = booleanArg; + } + } + + public void testPreferencesQualifier() throws BackingStoreException { setPreference(TEST_PREFS_KEY, "abc"); setPreference(TEST_PREFS_KEY, TEST_PREFS_NODE, "123"); IEclipseContext context = EclipseContextFactory.create(); - InjectTarget target = (InjectTarget) ContextInjectionFactory.make(InjectTarget.class, context); + InjectTarget target = ContextInjectionFactory.make(InjectTarget.class, context); // default node assertEquals(1, target.counter); assertEquals("abc", target.pref); @@ -94,6 +156,81 @@ assertEquals("xyz", target.prefOptional2); } + public void testBaseTypeConversion() throws BackingStoreException { + // setup preferences + String nodePath = CoreTestsActivator.getDefault().getBundleContext().getBundle().getSymbolicName(); + IEclipsePreferences node = new InstanceScope().getNode(nodePath); + node.putInt(KEY_INT, 12); + node.putBoolean(KEY_BOOL, true); + node.putDouble(KEY_DOUBLE, 12.35345345345d); + node.putFloat(KEY_FLOAT, 5.13f); + node.putLong(KEY_LONG, 131232343453453L); +// node.putByteArray(KEY_BYTE_ARRAY, new byte[] { 12, 34, 45, 67}); + node.flush(); + + IEclipseContext context = EclipseContextFactory.create(); + InjectTargetPrimitive target = ContextInjectionFactory.make(InjectTargetPrimitive.class, context); + + assertEquals(12, target.intField); + assertEquals(true, target.booleanField); + assertEquals(12.35345345345d, target.doubleField); + assertEquals(5.13f, target.floatField); + assertEquals(131232343453453L, target.longField); +// assertNotNull(target.byteArrayField); +// assertEquals(4, target.byteArrayField.length); +// assertEquals(12, target.byteArrayField[0]); +// assertEquals(34, target.byteArrayField[1]); +// assertEquals(45, target.byteArrayField[2]); +// assertEquals(67, target.byteArrayField[3]); + + assertEquals(12, target.intArg); + assertEquals(true, target.booleanArg); + + // change + node.putInt(KEY_INT, 777); + node.putBoolean(KEY_BOOL, false); + + assertEquals(777, target.intField); + assertEquals(false, target.booleanField); + + assertEquals(777, target.intArg); + assertEquals(false, target.booleanArg); + } + + public void testAutoConversion() throws BackingStoreException { + // setup preferences + String nodePath = CoreTestsActivator.getDefault().getBundleContext().getBundle().getSymbolicName(); + IEclipsePreferences node = new InstanceScope().getNode(nodePath); + node.putInt(KEY_INT, 12); + node.putBoolean(KEY_BOOL, true); + node.putDouble(KEY_DOUBLE, 12.35345345345d); + node.putFloat(KEY_FLOAT, 5.13f); + node.putLong(KEY_LONG, 131232343453453L); + node.flush(); + + IEclipseContext context = EclipseContextFactory.create(); + InjectTargetConversion target = ContextInjectionFactory.make(InjectTargetConversion.class, context); + + assertEquals(new Integer(12), target.intField); + assertEquals(new Boolean(true), target.booleanField); + assertEquals(new Double(12.35345345345d), target.doubleField); + assertEquals(new Float(5.13f), target.floatField); + assertEquals(new Long(131232343453453L), target.longField); + + assertEquals(new Integer(12), target.intArg); + assertEquals(new Boolean(true), target.booleanArg); + + // change + node.putInt(KEY_INT, 777); + node.putBoolean(KEY_BOOL, false); + + assertEquals(new Integer(777), target.intField); + assertEquals(new Boolean(false), target.booleanField); + + assertEquals(new Integer(777), target.intArg); + assertEquals(new Boolean(false), target.booleanArg); + } + private void setPreference(String key, String value) throws BackingStoreException { String nodePath = CoreTestsActivator.getDefault().getBundleContext().getBundle().getSymbolicName(); IEclipsePreferences node = new InstanceScope().getNode(nodePath);