Skip to content

Commit cfc7382

Browse files
ind1godkulp
authored andcommitted
Performance improvement
1 parent d371468 commit cfc7382

File tree

1 file changed

+186
-27
lines changed

1 file changed

+186
-27
lines changed

src/main/java/org/codehaus/jettison/mapped/DefaultConverter.java

+186-27
Original file line numberDiff line numberDiff line change
@@ -33,35 +33,194 @@ public void setEnforce32BitInt(boolean enforce32BitInt) {
3333

3434
public Object convertToJSONPrimitive(String text) {
3535
if(text == null) return text;
36-
Object primitive = null;
37-
// Attempt to convert to Integer
38-
try {
39-
primitive = enforce32BitInt ? Integer.valueOf(text) : Long.valueOf(text);
40-
} catch (Exception e) {/**/}
41-
// Attempt to convert to double
42-
if (primitive == null) {
43-
try {
44-
Double v = Double.valueOf(text);
45-
if( !v.isInfinite() && !v.isNaN() ) {
46-
primitive = v;
36+
37+
// If there's at least one character
38+
if (text.length() >= 1) {
39+
// find the first character
40+
char first = text.charAt(0);
41+
42+
// Is it incompatible with a number?
43+
if ((first < '0' || first > '9') && first != '-') {
44+
// Yes it is, so special case check for Boolean values
45+
if (first == 't') {
46+
if (text.equals("true")) {
47+
return Boolean.TRUE;
48+
}
49+
} else if (first == 'f') {
50+
if (text.equals("false")) {
51+
return Boolean.FALSE;
52+
}
4753
}
48-
else {
54+
55+
// Definitely not a Boolean or a number, so return the original value
56+
return text;
57+
}
58+
}
59+
60+
Object primitive = null;
61+
62+
if (enforce32BitInt) {
63+
primitive = getInteger(text);
64+
} else {
65+
primitive = getLong(text);
66+
}
67+
68+
if (primitive == null) {
69+
Double dbl = getDouble(text);
70+
71+
if (dbl != null) {
72+
if (dbl.isInfinite() || dbl.isNaN()) {
4973
primitive = text;
5074
}
51-
} catch (Exception e) {/**/}
52-
}
53-
// Attempt to convert to boolean
54-
if (primitive == null) {
55-
if(text.trim().equalsIgnoreCase("true") || text.trim().equalsIgnoreCase("false")) {
56-
primitive = Boolean.valueOf(text);
57-
}
58-
}
59-
60-
if (primitive == null || !primitive.toString().equals(text)) {
61-
// Default String
62-
primitive = text;
63-
}
64-
65-
return primitive;
75+
else {
76+
primitive = dbl;
77+
}
78+
}
79+
}
80+
81+
if (primitive == null || !primitive.toString().equals(text)) {
82+
// Default String
83+
primitive = text;
84+
}
85+
86+
return primitive;
87+
}
88+
89+
private static final int MAX_LENGTH_LONG = String.valueOf(Long.MAX_VALUE).length();
90+
private static final int MAX_LENGTH_LONG_NEGATIVE = String.valueOf(Long.MAX_VALUE).length() + 1;
91+
92+
/**
93+
* Try to get a Long value efficiently, avoiding Exceptions
94+
*/
95+
private static Long getLong(String text)
96+
{
97+
// handle an empty string
98+
if (text.isEmpty()) return null;
99+
100+
// if the text is too long it can't be a Long
101+
if (text.charAt(0) == '-') {
102+
if (text.length() > MAX_LENGTH_LONG_NEGATIVE) {
103+
return null;
104+
}
105+
} else if (text.length() > MAX_LENGTH_LONG) {
106+
return null;
107+
}
108+
109+
// Handle a leading minus sign
110+
int i = 0;
111+
if (text.charAt(0) == '-') {
112+
if (text.length() > 1) {
113+
i++;
114+
} else {
115+
return null;
116+
}
117+
}
118+
119+
// Check each character is a digit
120+
for (; i < text.length(); i++) {
121+
if (!Character.isDigit(text.charAt(i))) {
122+
return null;
123+
}
124+
}
125+
126+
// It looks like it might be a Long, so give it a go
127+
try {
128+
return Long.parseLong(text);
129+
} catch (Exception e) {
130+
// It isn't a Long
131+
return null;
132+
}
133+
}
134+
135+
private static final int MAX_LENGTH_INTEGER = String.valueOf(Integer.MAX_VALUE).length();
136+
private static final int MAX_LENGTH_INTEGER_NEGATIVE = String.valueOf(Integer.MAX_VALUE).length() + 1;
137+
138+
/**
139+
* Try to get an Integer value efficiently, avoiding Exceptions
140+
*/
141+
private static Integer getInteger(String text) {
142+
// handle an empty string
143+
if (text.isEmpty()) return null;
144+
145+
// if the text is too long it can't be an Integer
146+
if (text.charAt(0) == '-') {
147+
if (text.length() > MAX_LENGTH_INTEGER_NEGATIVE) {
148+
return null;
149+
}
150+
}
151+
else if (text.length() > MAX_LENGTH_INTEGER) {
152+
return null;
153+
}
154+
155+
// Handle a leading minus sign
156+
int i = 0;
157+
if (text.charAt(0) == '-') {
158+
if (text.length() > 1) {
159+
i++;
160+
} else {
161+
return null;
162+
}
163+
}
164+
165+
// Check each character is a digit
166+
for (; i < text.length(); i++) {
167+
if (!Character.isDigit(text.charAt(i))) {
168+
return null;
169+
}
170+
}
171+
172+
// It looks like it might be an Integer, so give it a go
173+
try {
174+
return Integer.parseInt(text);
175+
} catch (Exception e) {
176+
// It isn't an Integer
177+
return null;
178+
}
179+
}
180+
181+
/**
182+
* Try to get a Double value efficiently, avoiding Exceptions
183+
*/
184+
private static Double getDouble(String text) {
185+
boolean foundDP = false;
186+
boolean foundExp = false;
187+
188+
// handle an empty string
189+
if (text.isEmpty())
190+
return null;
191+
192+
// Handle a leading minus sign
193+
int i = 0;
194+
if (text.charAt(0) == '-') {
195+
if (text.length() > 1)
196+
i++;
197+
else
198+
return null;
199+
}
200+
201+
// Check each character is a digit
202+
for (; i < text.length(); i++) {
203+
char next = text.charAt(i);
204+
if (!Character.isDigit(next)) {
205+
if (next == '.') {
206+
if (foundDP)
207+
return null;
208+
foundDP = true;
209+
} else if (next == 'E' || next == 'e') {
210+
if (foundExp)
211+
return null;
212+
foundExp = true;
213+
} else
214+
return null;
215+
}
216+
}
217+
218+
// It looks like it might be a Double, so give it a go
219+
try {
220+
return Double.parseDouble(text);
221+
} catch (Exception e) {
222+
// It isn't a Double
223+
return null;
224+
}
66225
}
67226
}

0 commit comments

Comments
 (0)