StringToNumberConverter.java

1
package fr.sii.ogham.core.convert;
2
3
import java.math.BigDecimal;
4
import java.math.BigInteger;
5
6
import fr.sii.ogham.core.exception.convert.ConversionException;
7
8
/**
9
 * Converts a string to a number. It also handles {@link Byte}s. This class is
10
 * copied from Spring.
11
 * 
12
 * @author Aurélien Baudet
13
 *
14
 */
15
public class StringToNumberConverter implements SupportingConverter {
16
17
	@Override
18
	public <T> T convert(Object source, Class<T> targetType) {
19
		String text = (String) source;
20
		String trimmed = trimAllWhitespace(text);
21 1 1. convert : negated conditional → RUN_ERROR
		if(trimmed==null) {
22
			return null;
23
		}
24
		try {
25
			T value = convertNumber(trimmed, targetType);
26 1 1. convert : negated conditional → RUN_ERROR
			if(value==null) {
27
				throw new ConversionException("Cannot convert String [" + text + "] to target class [" + targetType.getName() + "]");
28
			}
29 1 1. convert : replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convert → RUN_ERROR
			return value;
30
		} catch(NumberFormatException e) {
31
			throw new ConversionException("Failed to convert "+source+" to "+targetType.getSimpleName(), e);
32
		}
33
	}
34
35
	@Override
36
	public boolean supports(Class<?> sourceType, Class<?> targetType) {
37 3 1. supports : negated conditional → RUN_ERROR
2. supports : negated conditional → RUN_ERROR
3. supports : replaced boolean return with true for fr/sii/ogham/core/convert/StringToNumberConverter::supports → RUN_ERROR
		return String.class.isAssignableFrom(sourceType) && Number.class.isAssignableFrom(targetType);
38
	}
39
	
40
	@SuppressWarnings("unchecked")
41
	private <T> T convertNumber(String trimmed, Class<T> targetType) {	// NOSONAR: code from Spring
42 1 1. convertNumber : negated conditional → RUN_ERROR
		if (Byte.class == targetType) {
43 2 1. convertNumber : negated conditional → RUN_ERROR
2. convertNumber : replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR
			return (T) (isHexOrOctalNumber(trimmed) ? Byte.decode(trimmed) : Byte.valueOf(trimmed));
44
		}
45 1 1. convertNumber : negated conditional → RUN_ERROR
		if (Short.class == targetType) {
46 2 1. convertNumber : negated conditional → RUN_ERROR
2. convertNumber : replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR
			return (T) (isHexOrOctalNumber(trimmed) ? Short.decode(trimmed) : Short.valueOf(trimmed));
47
		}
48 1 1. convertNumber : negated conditional → RUN_ERROR
		if (Integer.class == targetType) {
49 2 1. convertNumber : replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR
2. convertNumber : negated conditional → RUN_ERROR
			return (T) (isHexOrOctalNumber(trimmed) ? Integer.decode(trimmed) : Integer.valueOf(trimmed));
50
		}
51 1 1. convertNumber : negated conditional → RUN_ERROR
		if (Long.class == targetType) {
52 2 1. convertNumber : replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR
2. convertNumber : negated conditional → RUN_ERROR
			return (T) (isHexOrOctalNumber(trimmed) ? Long.decode(trimmed) : Long.valueOf(trimmed));
53
		}
54 1 1. convertNumber : negated conditional → RUN_ERROR
		if (BigInteger.class == targetType) {
55 2 1. convertNumber : replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR
2. convertNumber : negated conditional → RUN_ERROR
			return (T) (isHexOrOctalNumber(trimmed) ? decodeBigInteger(trimmed) : new BigInteger(trimmed));
56
		}
57 1 1. convertNumber : negated conditional → RUN_ERROR
		if (Float.class == targetType) {
58 1 1. convertNumber : replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR
			return (T) Float.valueOf(trimmed);
59
		}
60 1 1. convertNumber : negated conditional → RUN_ERROR
		if (Double.class == targetType) {
61 1 1. convertNumber : replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR
			return (T) Double.valueOf(trimmed);
62
		}
63 2 1. convertNumber : negated conditional → RUN_ERROR
2. convertNumber : negated conditional → RUN_ERROR
		if (BigDecimal.class == targetType || Number.class == targetType) {
64 1 1. convertNumber : replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR
			return (T) new BigDecimal(trimmed);
65
		}
66
		return null;
67
	}
68
69
	private static boolean isHexOrOctalNumber(String value) {
70 1 1. isHexOrOctalNumber : negated conditional → RUN_ERROR
		int index = value.startsWith("-") ? 1 : 0;
71 3 1. isHexOrOctalNumber : negated conditional → RUN_ERROR
2. isHexOrOctalNumber : negated conditional → RUN_ERROR
3. isHexOrOctalNumber : replaced boolean return with true for fr/sii/ogham/core/convert/StringToNumberConverter::isHexOrOctalNumber → RUN_ERROR
		return value.startsWith("#", index) || value.startsWith("0", index);
72
	}
73
74
	private static String trimAllWhitespace(String str) {
75 2 1. trimAllWhitespace : negated conditional → RUN_ERROR
2. trimAllWhitespace : negated conditional → RUN_ERROR
		if (str == null || str.length() == 0) {
76 1 1. trimAllWhitespace : replaced return value with "" for fr/sii/ogham/core/convert/StringToNumberConverter::trimAllWhitespace → RUN_ERROR
			return null;
77
		}
78
		int len = str.length();
79
		StringBuilder sb = new StringBuilder(str.length());
80 2 1. trimAllWhitespace : negated conditional → RUN_ERROR
2. trimAllWhitespace : changed conditional boundary → RUN_ERROR
		for (int i = 0; i < len; i++) {
81
			char c = str.charAt(i);
82 1 1. trimAllWhitespace : negated conditional → RUN_ERROR
			if (!Character.isWhitespace(c)) {
83
				sb.append(c);
84
			}
85
		}
86 1 1. trimAllWhitespace : replaced return value with "" for fr/sii/ogham/core/convert/StringToNumberConverter::trimAllWhitespace → RUN_ERROR
		return sb.toString();
87
	}
88
89
	private static BigInteger decodeBigInteger(String value) {
90
		int radix = 10;
91
		int index = 0;
92
		boolean negative = false;
93
94
		// Handle minus sign, if present.
95 1 1. decodeBigInteger : negated conditional → RUN_ERROR
		if (value.startsWith("-")) {
96
			negative = true;
97 1 1. decodeBigInteger : Changed increment from 1 to -1 → RUN_ERROR
			index++;
98
		}
99
100
		// Handle radix specifier, if present.
101 2 1. decodeBigInteger : negated conditional → RUN_ERROR
2. decodeBigInteger : negated conditional → RUN_ERROR
		if (value.startsWith("0x", index) || value.startsWith("0X", index)) {
102 1 1. decodeBigInteger : Changed increment from 2 to -2 → RUN_ERROR
			index += 2;
103
			radix = 16;
104 1 1. decodeBigInteger : negated conditional → RUN_ERROR
		} else if (value.startsWith("#", index)) {
105 1 1. decodeBigInteger : Changed increment from 1 to -1 → RUN_ERROR
			index++;
106
			radix = 16;
107 4 1. decodeBigInteger : negated conditional → RUN_ERROR
2. decodeBigInteger : Replaced integer addition with subtraction → RUN_ERROR
3. decodeBigInteger : changed conditional boundary → RUN_ERROR
4. decodeBigInteger : negated conditional → RUN_ERROR
		} else if (value.startsWith("0", index) && value.length() > 1 + index) {
108 1 1. decodeBigInteger : Changed increment from 1 to -1 → RUN_ERROR
			index++;
109
			radix = 8;
110
		}
111
112
		BigInteger result = new BigInteger(value.substring(index), radix);
113 2 1. decodeBigInteger : negated conditional → RUN_ERROR
2. decodeBigInteger : replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::decodeBigInteger → RUN_ERROR
		return negative ? result.negate() : result;
114
	}
115
}

Mutations

21

1.1
Location : convert
Killed by :
negated conditional → RUN_ERROR

26

1.1
Location : convert
Killed by :
negated conditional → RUN_ERROR

29

1.1
Location : convert
Killed by :
replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convert → RUN_ERROR

37

1.1
Location : supports
Killed by :
negated conditional → RUN_ERROR

2.2
Location : supports
Killed by :
negated conditional → RUN_ERROR

3.3
Location : supports
Killed by :
replaced boolean return with true for fr/sii/ogham/core/convert/StringToNumberConverter::supports → RUN_ERROR

42

1.1
Location : convertNumber
Killed by :
negated conditional → RUN_ERROR

43

1.1
Location : convertNumber
Killed by :
negated conditional → RUN_ERROR

2.2
Location : convertNumber
Killed by :
replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR

45

1.1
Location : convertNumber
Killed by :
negated conditional → RUN_ERROR

46

1.1
Location : convertNumber
Killed by :
negated conditional → RUN_ERROR

2.2
Location : convertNumber
Killed by :
replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR

48

1.1
Location : convertNumber
Killed by :
negated conditional → RUN_ERROR

49

1.1
Location : convertNumber
Killed by :
replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR

2.2
Location : convertNumber
Killed by :
negated conditional → RUN_ERROR

51

1.1
Location : convertNumber
Killed by :
negated conditional → RUN_ERROR

52

1.1
Location : convertNumber
Killed by :
replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR

2.2
Location : convertNumber
Killed by :
negated conditional → RUN_ERROR

54

1.1
Location : convertNumber
Killed by :
negated conditional → RUN_ERROR

55

1.1
Location : convertNumber
Killed by :
replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR

2.2
Location : convertNumber
Killed by :
negated conditional → RUN_ERROR

57

1.1
Location : convertNumber
Killed by :
negated conditional → RUN_ERROR

58

1.1
Location : convertNumber
Killed by :
replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR

60

1.1
Location : convertNumber
Killed by :
negated conditional → RUN_ERROR

61

1.1
Location : convertNumber
Killed by :
replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR

63

1.1
Location : convertNumber
Killed by :
negated conditional → RUN_ERROR

2.2
Location : convertNumber
Killed by :
negated conditional → RUN_ERROR

64

1.1
Location : convertNumber
Killed by :
replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::convertNumber → RUN_ERROR

70

1.1
Location : isHexOrOctalNumber
Killed by :
negated conditional → RUN_ERROR

71

1.1
Location : isHexOrOctalNumber
Killed by :
negated conditional → RUN_ERROR

2.2
Location : isHexOrOctalNumber
Killed by :
negated conditional → RUN_ERROR

3.3
Location : isHexOrOctalNumber
Killed by :
replaced boolean return with true for fr/sii/ogham/core/convert/StringToNumberConverter::isHexOrOctalNumber → RUN_ERROR

75

1.1
Location : trimAllWhitespace
Killed by :
negated conditional → RUN_ERROR

2.2
Location : trimAllWhitespace
Killed by :
negated conditional → RUN_ERROR

76

1.1
Location : trimAllWhitespace
Killed by :
replaced return value with "" for fr/sii/ogham/core/convert/StringToNumberConverter::trimAllWhitespace → RUN_ERROR

80

1.1
Location : trimAllWhitespace
Killed by :
negated conditional → RUN_ERROR

2.2
Location : trimAllWhitespace
Killed by :
changed conditional boundary → RUN_ERROR

82

1.1
Location : trimAllWhitespace
Killed by :
negated conditional → RUN_ERROR

86

1.1
Location : trimAllWhitespace
Killed by :
replaced return value with "" for fr/sii/ogham/core/convert/StringToNumberConverter::trimAllWhitespace → RUN_ERROR

95

1.1
Location : decodeBigInteger
Killed by :
negated conditional → RUN_ERROR

97

1.1
Location : decodeBigInteger
Killed by :
Changed increment from 1 to -1 → RUN_ERROR

101

1.1
Location : decodeBigInteger
Killed by :
negated conditional → RUN_ERROR

2.2
Location : decodeBigInteger
Killed by :
negated conditional → RUN_ERROR

102

1.1
Location : decodeBigInteger
Killed by :
Changed increment from 2 to -2 → RUN_ERROR

104

1.1
Location : decodeBigInteger
Killed by :
negated conditional → RUN_ERROR

105

1.1
Location : decodeBigInteger
Killed by :
Changed increment from 1 to -1 → RUN_ERROR

107

1.1
Location : decodeBigInteger
Killed by :
negated conditional → RUN_ERROR

2.2
Location : decodeBigInteger
Killed by :
Replaced integer addition with subtraction → RUN_ERROR

3.3
Location : decodeBigInteger
Killed by :
changed conditional boundary → RUN_ERROR

4.4
Location : decodeBigInteger
Killed by :
negated conditional → RUN_ERROR

108

1.1
Location : decodeBigInteger
Killed by :
Changed increment from 1 to -1 → RUN_ERROR

113

1.1
Location : decodeBigInteger
Killed by :
negated conditional → RUN_ERROR

2.2
Location : decodeBigInteger
Killed by :
replaced return value with null for fr/sii/ogham/core/convert/StringToNumberConverter::decodeBigInteger → RUN_ERROR

Active mutators

Tests examined


Report generated by PIT 1.13.1