Skip to content

Commit bd40f05

Browse files
committed
Add a StringToNumberConverter
1 parent 5d8c6ca commit bd40f05

File tree

2 files changed

+168
-0
lines changed

2 files changed

+168
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
2+
package org.scijava.convert;
3+
4+
import org.scijava.plugin.Plugin;
5+
import org.scijava.util.Types;
6+
7+
/**
8+
* Converts a {@link String} to a {@link Number}. Currently handles all boxed
9+
* and unboxed primitives, along with the Numbers. In particular,
10+
* {@link String}s converted {@link Number}s are just {@link Double}s, as this
11+
* features the broadest range of integers.
12+
*
13+
* @author Gabriel Selzer
14+
*/
15+
@Plugin(type = Converter.class)
16+
public class StringToNumberConverter extends AbstractConverter<String, Number> {
17+
18+
@Override
19+
@SuppressWarnings("unchecked")
20+
public <T> T convert(Object src, Class<T> dest) {
21+
// ensure type is well-behaved, rather than a primitive type
22+
Class<T> saneDest = Types.box(dest);
23+
if (!(src instanceof String)) throw new IllegalArgumentException(
24+
"Expected src to be a String but got a " + src.getClass());
25+
if (!(Number.class.isAssignableFrom(saneDest)))
26+
throw new IllegalArgumentException(
27+
"Expected dest to be Number.class (or a subclass of Number, or a numerical primitive), but got " +
28+
saneDest);
29+
String srcString = (String) src;
30+
if (saneDest == Byte.class) return (T) new Byte(srcString);
31+
if (saneDest == Short.class) return (T) new Short(srcString);
32+
if (saneDest == Integer.class) return (T) new Integer(srcString);
33+
if (saneDest == Long.class) return (T) new Long(srcString);
34+
if (saneDest == Float.class) return (T) new Float(srcString);
35+
if (saneDest == Double.class) return (T) new Double(srcString);
36+
if (saneDest == Number.class) return (T) new Double(srcString);
37+
else throw new IllegalArgumentException("Unknown destination type: " +
38+
saneDest);
39+
}
40+
41+
@Override
42+
public Class<Number> getOutputType() {
43+
return Number.class;
44+
}
45+
46+
@Override
47+
public Class<String> getInputType() {
48+
return String.class;
49+
}
50+
51+
@Override
52+
public boolean canConvert(Object src, Class<?> dest) {
53+
if (!Types.isAssignable(src.getClass(), String.class)) return false;
54+
return Types.isAssignable(Types.box(dest), Number.class);
55+
}
56+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
2+
package org.scijava.convert;
3+
4+
import org.junit.Assert;
5+
import org.junit.Before;
6+
import org.junit.Test;
7+
8+
/**
9+
* Tests {@link StringToNumberConverter}
10+
*
11+
* @author Gabriel Selzer
12+
*/
13+
public class StringToNumberConverterTest {
14+
15+
Converter<String, Number> conv;
16+
17+
@Before
18+
public void setUp() {
19+
conv = new StringToNumberConverter();
20+
}
21+
22+
@Test
23+
public void stringToByteTest() {
24+
String s = "0";
25+
Assert.assertTrue(conv.canConvert(s, Byte.class));
26+
Assert.assertEquals(new Byte((byte) 0), conv.convert(s, Byte.class));
27+
}
28+
29+
@Test
30+
public void stringToPrimitiveByteTest() {
31+
String s = "0";
32+
Assert.assertTrue(conv.canConvert(s, byte.class));
33+
Assert.assertEquals(0, (int) conv.convert(s, byte.class));
34+
}
35+
36+
@Test
37+
public void stringToShortTest() {
38+
String s = "0";
39+
Assert.assertTrue(conv.canConvert(s, Short.class));
40+
Assert.assertEquals(new Short((short) 0), conv.convert(s, Short.class));
41+
}
42+
43+
@Test
44+
public void stringToPrimitiveShortTest() {
45+
String s = "0";
46+
Assert.assertTrue(conv.canConvert(s, short.class));
47+
Assert.assertEquals(0, (int) conv.convert(s, short.class));
48+
}
49+
50+
@Test
51+
public void stringToIntegerTest() {
52+
String s = "0";
53+
Assert.assertTrue(conv.canConvert(s, Integer.class));
54+
Assert.assertEquals(new Integer(0), conv.convert(s, Integer.class));
55+
}
56+
57+
@Test
58+
public void stringToPrimitiveIntegerTest() {
59+
String s = "0";
60+
Assert.assertTrue(conv.canConvert(s, int.class));
61+
Assert.assertEquals(0, (int) conv.convert(s, int.class));
62+
}
63+
64+
@Test
65+
public void stringToLongTest() {
66+
String s = "0";
67+
Assert.assertTrue(conv.canConvert(s, Long.class));
68+
Assert.assertEquals(new Long(0), conv.convert(s, Long.class));
69+
}
70+
71+
@Test
72+
public void stringToPrimitiveLongTest() {
73+
String s = "0";
74+
Assert.assertTrue(conv.canConvert(s, long.class));
75+
Assert.assertEquals(0L, (long) conv.convert(s, long.class));
76+
}
77+
78+
@Test
79+
public void stringToFloatTest() {
80+
String s = "0";
81+
Assert.assertTrue(conv.canConvert(s, Float.class));
82+
Assert.assertEquals(new Float(0), conv.convert(s, Float.class));
83+
}
84+
85+
@Test
86+
public void stringToPrimitiveFloat() {
87+
String s = "0";
88+
Assert.assertTrue(conv.canConvert(s, float.class));
89+
Assert.assertEquals(0f, conv.convert(s, float.class), 1e-6);
90+
}
91+
92+
@Test
93+
public void stringToDoubleTest() {
94+
String s = "0";
95+
Assert.assertTrue(conv.canConvert(s, Double.class));
96+
Assert.assertEquals(new Double(0), conv.convert(s, Double.class));
97+
}
98+
99+
@Test
100+
public void stringToPrimitiveDouble() {
101+
String s = "0";
102+
Assert.assertTrue(conv.canConvert(s, double.class));
103+
Assert.assertEquals(0d, conv.convert(s, double.class), 1e-6);
104+
}
105+
106+
@Test
107+
public void stringToNumberTest() {
108+
String s = "0";
109+
Assert.assertTrue(conv.canConvert(s, Number.class));
110+
Assert.assertEquals(0d, conv.convert(s, Number.class));
111+
}
112+
}

0 commit comments

Comments
 (0)