Skip to content

Commit 1d1bdea

Browse files
sjoshidsjoshid
sjoshid
authored and
sjoshid
committed
1) Calling field setters if available before falling back to setting fields directly.
1 parent ad5d6a8 commit 1d1bdea

File tree

1 file changed

+126
-54
lines changed

1 file changed

+126
-54
lines changed

src/main/java/org/influxdb/impl/InfluxDBResultMapper.java

+126-54
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
package org.influxdb.impl;
2222

2323
import java.lang.reflect.Field;
24+
import java.lang.reflect.InvocationTargetException;
25+
import java.lang.reflect.Method;
2426
import java.time.Instant;
2527
import java.time.format.DateTimeFormatter;
2628
import java.time.format.DateTimeFormatterBuilder;
@@ -51,6 +53,8 @@ public class InfluxDBResultMapper {
5153
private static final
5254
ConcurrentMap<String, ConcurrentMap<String, Field>> CLASS_FIELD_CACHE = new ConcurrentHashMap<>();
5355

56+
private static final ConcurrentMap<String, ConcurrentMap<String, Method>> CLASS_SETTERS_CACHE = new ConcurrentHashMap<>();
57+
5458
private static final int FRACTION_MIN_WIDTH = 0;
5559
private static final int FRACTION_MAX_WIDTH = 9;
5660
private static final boolean ADD_DECIMAL_POINT = true;
@@ -217,11 +221,25 @@ void cacheMeasurementClass(final Class<?>... classVarAgrs) {
217221
influxColumnAndFieldMap = initialMap;
218222
}
219223

224+
ConcurrentMap<String, Method> classFieldSetters = new ConcurrentHashMap<>();
225+
ConcurrentMap<String, Method> fieldSetters = CLASS_SETTERS_CACHE.putIfAbsent(clazz.getName(), classFieldSetters);
226+
if (fieldSetters == null) {
227+
fieldSetters = classFieldSetters;
228+
}
229+
220230
Class<?> c = clazz;
221231
while (c != null) {
222232
for (Field field : c.getDeclaredFields()) {
223233
Column colAnnotation = field.getAnnotation(Column.class);
224234
if (colAnnotation != null) {
235+
String fieldName = field.getName();
236+
String setterName = "set".concat(fieldName.substring(0,1).toUpperCase().concat(fieldName.substring(1)));
237+
try {
238+
Method setter = c.getDeclaredMethod(setterName, field.getType());
239+
fieldSetters.put(colAnnotation.name(), setter);
240+
} catch (NoSuchMethodException e) {
241+
//sj_todo ignore? maybe print a warning that no setter found?
242+
}
225243
influxColumnAndFieldMap.put(colAnnotation.name(), field);
226244
}
227245
}
@@ -254,16 +272,18 @@ <T> List<T> parseSeriesAs(final QueryResult.Series series, final Class<T> clazz,
254272
final TimeUnit precision) {
255273
int columnSize = series.getColumns().size();
256274
ConcurrentMap<String, Field> colNameAndFieldMap = CLASS_FIELD_CACHE.get(clazz.getName());
275+
ConcurrentMap<String, Method> fieldSettersMap = CLASS_SETTERS_CACHE.get(clazz.getName());
257276
try {
258277
T object = null;
259278
for (List<Object> row : series.getValues()) {
260279
for (int i = 0; i < columnSize; i++) {
280+
Method fieldSetter = fieldSettersMap.get(series.getColumns().get(i));
261281
Field correspondingField = colNameAndFieldMap.get(series.getColumns().get(i)/*InfluxDB columnName*/);
262-
if (correspondingField != null) {
282+
if (correspondingField != null || fieldSetter != null) {
263283
if (object == null) {
264284
object = clazz.newInstance();
265285
}
266-
setFieldValue(object, correspondingField, row.get(i), precision);
286+
setFieldValue(object, correspondingField, fieldSetter, row.get(i), precision);
267287
}
268288
}
269289
// When the "GROUP BY" clause is used, "tags" are returned as Map<String,String> and
@@ -273,9 +293,10 @@ <T> List<T> parseSeriesAs(final QueryResult.Series series, final Class<T> clazz,
273293
if (series.getTags() != null && !series.getTags().isEmpty()) {
274294
for (Entry<String, String> entry : series.getTags().entrySet()) {
275295
Field correspondingField = colNameAndFieldMap.get(entry.getKey()/*InfluxDB columnName*/);
276-
if (correspondingField != null) {
296+
Method fieldSetter = fieldSettersMap.get(entry.getKey());
297+
if (correspondingField != null || fieldSetter != null ) {
277298
// I don't think it is possible to reach here without a valid "object"
278-
setFieldValue(object, correspondingField, entry.getValue(), precision);
299+
setFieldValue(object, correspondingField, fieldSetter, entry.getValue(), precision);
279300
}
280301
}
281302
}
@@ -284,7 +305,7 @@ <T> List<T> parseSeriesAs(final QueryResult.Series series, final Class<T> clazz,
284305
object = null;
285306
}
286307
}
287-
} catch (InstantiationException | IllegalAccessException e) {
308+
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
288309
throw new InfluxDBMapperException(e);
289310
}
290311
return result;
@@ -302,8 +323,8 @@ <T> List<T> parseSeriesAs(final QueryResult.Series series, final Class<T> clazz,
302323
* @throws IllegalArgumentException
303324
* @throws IllegalAccessException
304325
*/
305-
<T> void setFieldValue(final T object, final Field field, final Object value, final TimeUnit precision)
306-
throws IllegalArgumentException, IllegalAccessException {
326+
<T> void setFieldValue(final T object, final Field field, final Method fieldSetter, final Object value, final TimeUnit precision)
327+
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
307328
if (value == null) {
308329
return;
309330
}
@@ -312,9 +333,15 @@ <T> void setFieldValue(final T object, final Field field, final Object value, fi
312333
if (!field.isAccessible()) {
313334
field.setAccessible(true);
314335
}
315-
if (fieldValueModified(fieldType, field, object, value, precision)
316-
|| fieldValueForPrimitivesModified(fieldType, field, object, value)
317-
|| fieldValueForPrimitiveWrappersModified(fieldType, field, object, value)) {
336+
if (!fieldSetter.isAccessible()) {
337+
fieldSetter.setAccessible(true);
338+
}
339+
if (assignInstant(fieldType, field, fieldSetter, object, value, precision)
340+
|| assignString(fieldType, field, fieldSetter, object, value)
341+
|| assignDouble(fieldType, field, fieldSetter, object, value)
342+
|| assignInteger(fieldType, field, fieldSetter, object, value)
343+
|| assignLong(fieldType, field, fieldSetter, object, value)
344+
|| assignBoolean(fieldType, field, fieldSetter, object, value)) {
318345
return;
319346
}
320347
String msg = "Class '%s' field '%s' is from an unsupported type '%s'.";
@@ -328,14 +355,9 @@ <T> void setFieldValue(final T object, final Field field, final Object value, fi
328355
}
329356
}
330357

331-
<T> boolean fieldValueModified(final Class<?> fieldType, final Field field, final T object, final Object value,
332-
final TimeUnit precision)
333-
throws IllegalArgumentException, IllegalAccessException {
334-
if (String.class.isAssignableFrom(fieldType)) {
335-
field.set(object, String.valueOf(value));
336-
return true;
337-
}
338-
if (Instant.class.isAssignableFrom(fieldType)) {
358+
<T> boolean assignInstant(final Class<?> fieldType, final Field field, final Method fieldSetter, final T object, final Object value, final TimeUnit precision) throws InvocationTargetException, IllegalAccessException {
359+
boolean isInstantAssigned = false;
360+
if(Instant.class.isAssignableFrom(fieldType)) {
339361
Instant instant;
340362
if (value instanceof String) {
341363
instant = Instant.from(RFC3339_FORMATTER.parse(String.valueOf(value)));
@@ -348,52 +370,102 @@ <T> boolean fieldValueModified(final Class<?> fieldType, final Field field, fina
348370
} else {
349371
throw new InfluxDBMapperException("Unsupported type " + field.getClass() + " for field " + field.getName());
350372
}
351-
field.set(object, instant);
352-
return true;
373+
if(fieldSetter != null && fieldSetter.isAccessible()) {
374+
fieldSetter.invoke(object, instant);
375+
isInstantAssigned = true;
376+
} else {
377+
field.set(object, instant);
378+
isInstantAssigned = true;
379+
}
353380
}
354-
return false;
381+
return isInstantAssigned;
355382
}
356383

357-
<T> boolean fieldValueForPrimitivesModified(final Class<?> fieldType, final Field field, final T object,
358-
final Object value) throws IllegalArgumentException, IllegalAccessException {
359-
if (double.class.isAssignableFrom(fieldType)) {
360-
field.setDouble(object, ((Double) value).doubleValue());
361-
return true;
362-
}
363-
if (long.class.isAssignableFrom(fieldType)) {
364-
field.setLong(object, ((Double) value).longValue());
365-
return true;
366-
}
367-
if (int.class.isAssignableFrom(fieldType)) {
368-
field.setInt(object, ((Double) value).intValue());
369-
return true;
370-
}
371-
if (boolean.class.isAssignableFrom(fieldType)) {
372-
field.setBoolean(object, Boolean.valueOf(String.valueOf(value)).booleanValue());
373-
return true;
384+
<T> boolean assignString(final Class<?> fieldType, final Field field, final Method fieldSetter, final T object, final Object value) throws InvocationTargetException, IllegalAccessException {
385+
boolean isStringAssigned = false;
386+
if(String.class.isAssignableFrom(fieldType)) {
387+
final String stringValue = String.valueOf(value);
388+
if(fieldSetter != null && fieldSetter.isAccessible()) {
389+
fieldSetter.invoke(object, stringValue);
390+
isStringAssigned = true;
391+
} else {
392+
field.set(object, stringValue);
393+
isStringAssigned = true;
394+
}
374395
}
375-
return false;
396+
return isStringAssigned;
376397
}
377398

378-
<T> boolean fieldValueForPrimitiveWrappersModified(final Class<?> fieldType, final Field field, final T object,
379-
final Object value) throws IllegalArgumentException, IllegalAccessException {
380-
if (Double.class.isAssignableFrom(fieldType)) {
381-
field.set(object, value);
382-
return true;
399+
<T> boolean assignDouble(final Class<?> fieldType, final Field field, final Method fieldSetter, final T object, final Object value) throws InvocationTargetException, IllegalAccessException {
400+
boolean isDoubleAssigned = false;
401+
if(double.class.isAssignableFrom(fieldType) || Double.class.isAssignableFrom(fieldType)) {
402+
if(fieldSetter != null && fieldSetter.isAccessible()) {
403+
fieldSetter.invoke(object, value);
404+
isDoubleAssigned = true;
405+
} else if(double.class.isAssignableFrom(fieldType)) {
406+
final double doubleValue = (Double) value;
407+
field.setDouble(object, doubleValue);
408+
isDoubleAssigned = true;
409+
} else if(Double.class.isAssignableFrom(fieldType)) {
410+
field.set(object, value);
411+
isDoubleAssigned = true;
412+
}
383413
}
384-
if (Long.class.isAssignableFrom(fieldType)) {
385-
field.set(object, Long.valueOf(((Double) value).longValue()));
386-
return true;
414+
return isDoubleAssigned;
415+
}
416+
417+
<T> boolean assignLong(final Class<?> fieldType, final Field field, final Method fieldSetter, final T object, final Object value) throws InvocationTargetException, IllegalAccessException {
418+
boolean isLongAssigned = false;
419+
if(long.class.isAssignableFrom(fieldType) || Long.class.isAssignableFrom(fieldType)) {
420+
final long longValue = ((Double) value).longValue();
421+
if(fieldSetter != null && fieldSetter.isAccessible()) {
422+
fieldSetter.invoke(object, longValue);
423+
isLongAssigned = true;
424+
} else if(long.class.isAssignableFrom(fieldType)) {
425+
field.setLong(object, longValue);
426+
isLongAssigned = true;
427+
} else if(Long.class.isAssignableFrom(fieldType)) {
428+
field.set(object, longValue);
429+
isLongAssigned = true;
430+
}
387431
}
388-
if (Integer.class.isAssignableFrom(fieldType)) {
389-
field.set(object, Integer.valueOf(((Double) value).intValue()));
390-
return true;
432+
return isLongAssigned;
433+
}
434+
435+
<T> boolean assignInteger(final Class<?> fieldType, final Field field, final Method fieldSetter, final T object, final Object value) throws InvocationTargetException, IllegalAccessException {
436+
boolean isIntegerAssigned = false;
437+
if(int.class.isAssignableFrom(fieldType) || Integer.class.isAssignableFrom(fieldType)) {
438+
final int intValue = ((Double) value).intValue();
439+
if(fieldSetter != null && fieldSetter.isAccessible()) {
440+
fieldSetter.invoke(object, intValue);
441+
isIntegerAssigned = true;
442+
} else if(int.class.isAssignableFrom(fieldType)) {
443+
field.setInt(object, intValue);
444+
isIntegerAssigned = true;
445+
} else if(Integer.class.isAssignableFrom(fieldType)) {
446+
field.set(object, intValue);
447+
isIntegerAssigned = true;
448+
}
391449
}
392-
if (Boolean.class.isAssignableFrom(fieldType)) {
393-
field.set(object, Boolean.valueOf(String.valueOf(value)));
394-
return true;
450+
return isIntegerAssigned;
451+
}
452+
453+
<T> boolean assignBoolean(final Class<?> fieldType, final Field field, final Method fieldSetter, final T object, final Object value) throws InvocationTargetException, IllegalAccessException {
454+
boolean isBooleanAssigned = false;
455+
if(boolean.class.isAssignableFrom(fieldType) || Boolean.class.isAssignableFrom(fieldType)) {
456+
final boolean boolValue = Boolean.parseBoolean(String.valueOf(value));
457+
if(fieldSetter != null && fieldSetter.isAccessible()) {
458+
fieldSetter.invoke(object, boolValue);
459+
isBooleanAssigned = true;
460+
} else if(boolean.class.isAssignableFrom(fieldType)) {
461+
field.setBoolean(object, boolValue);
462+
isBooleanAssigned = true;
463+
} else if(Boolean.class.isAssignableFrom(fieldType)) {
464+
field.set(object, boolValue);
465+
isBooleanAssigned = true;
466+
}
395467
}
396-
return false;
468+
return isBooleanAssigned;
397469
}
398470

399471
private Long toMillis(final long value, final TimeUnit precision) {

0 commit comments

Comments
 (0)