Skip to content

Commit 9db8d4f

Browse files
committed
started adding of support getter-setter into mapping
1 parent 1b38fda commit 9db8d4f

File tree

2 files changed

+105
-31
lines changed

2 files changed

+105
-31
lines changed

jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/JBBPMapper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ private static void processFieldOfMappedClass(
219219
if (record.binAnnotation.custom()) {
220220
JBBPUtils.assertNotNull(customFieldProcessor, "There is a custom mapping field, in the case you must provide a custom mapping field processor");
221221
final Object value = customFieldProcessor.prepareObjectForMapping(rootStructure, record.binAnnotation, record.mappingField);
222-
MappedFieldRecord.setFieldValue(instance, record.mappingField, null, value);
222+
MappedFieldRecord.setFieldValue(instance, record.setter, record.mappingField, null, value);
223223
} else {
224224
final JBBPAbstractField binField;
225225

@@ -364,7 +364,7 @@ public static List<MappedFieldRecord> findAffectedFields(final Object instance)
364364
}
365365

366366
try {
367-
result.add(new MappedFieldRecord(mappingField, mappingClass, mappedAnno));
367+
result.add(new MappedFieldRecord(mappingField, null, null, mappingClass, mappedAnno));
368368
} catch (IllegalStateException ex) {
369369
throw new JBBPMapperException(ex.getMessage(), null, mappingClass, mappingField, ex);
370370
}

jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/MappedFieldRecord.java

Lines changed: 103 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public final class MappedFieldRecord implements Comparable<MappedFieldRecord> {
8484
final JBBPFieldArrayStruct structArray = (JBBPFieldArrayStruct) binField;
8585
final Class<?> componentType = record.mappingField.getType().getComponentType();
8686

87-
Object valueArray = getFieldValue(instance, record.mappingField);
87+
Object valueArray = getFieldValue(instance, record.getter, record.mappingField);
8888

8989
valueArray = valueArray == null ? Array.newInstance(componentType, structArray.size()) : valueArray;
9090

@@ -100,41 +100,41 @@ public final class MappedFieldRecord implements Comparable<MappedFieldRecord> {
100100
Array.set(valueArray, i, JBBPMapper.map(structArray.getElementAt(i), curInstance, customFieldProcessor));
101101
}
102102
}
103-
setFieldValue(instance, record.mappingField, binField, valueArray);
103+
setFieldValue(instance, record.setter, record.mappingField, binField, valueArray);
104104
} else {
105105
// primitive
106-
mapArrayField(instance, record.mappingField, (JBBPAbstractArrayField<?>) binField, record.binAnnotation.bitOrder() == JBBPBitOrder.MSB0);
106+
mapArrayField(instance, record.setter, record.mappingField, (JBBPAbstractArrayField<?>) binField, record.binAnnotation.bitOrder() == JBBPBitOrder.MSB0);
107107
}
108108
} else {
109109
throw new JBBPMapperException("Can't map a non-array value to an array mapping field", binField, record.mappingClass, record.mappingField, null);
110110
}
111111
};
112112
private static final FieldProcessor PROC_NUM = (record, rootStructure, instance, customFieldProcessor, binField, flags, instantiators) -> {
113113
if (binField instanceof JBBPNumericField) {
114-
mapNumericField(instance, record.mappingField, (JBBPNumericField) binField, record.binAnnotation.bitOrder() == JBBPBitOrder.MSB0);
114+
mapNumericField(instance, record.setter, record.mappingField, (JBBPNumericField) binField, record.binAnnotation.bitOrder() == JBBPBitOrder.MSB0);
115115
} else if (binField instanceof JBBPFieldString) {
116116
if (record.mappingField.getType().isPrimitive()) {
117117
throw new JBBPMapperException("Can't map a string to a primitive mapping field", binField, record.mappingClass, record.mappingField, null);
118118
} else {
119-
setFieldValue(instance, record.mappingField, binField, ((JBBPFieldString) binField).getAsString());
119+
setFieldValue(instance, record.setter, record.mappingField, binField, ((JBBPFieldString) binField).getAsString());
120120
}
121121
} else if (binField instanceof JBBPFieldStruct) {
122122
if (record.mappingField.getType().isPrimitive()) {
123123
throw new JBBPMapperException("Can't map a structure to a primitive mapping field", binField, record.mappingClass, record.mappingField, null);
124124
} else {
125-
final Object curValue = getFieldValue(instance, record.mappingField);
125+
final Object curValue = getFieldValue(instance, record.getter, record.mappingField);
126126
if (curValue == null) {
127-
setFieldValue(instance, record.mappingField, binField, JBBPMapper.map((JBBPFieldStruct) binField, tryMakeInstance(record.mappingField.getType(), binField, instance, record.mappingField, instantiators), customFieldProcessor));
127+
setFieldValue(instance, record.setter, record.mappingField, binField, JBBPMapper.map((JBBPFieldStruct) binField, tryMakeInstance(record.mappingField.getType(), binField, instance, record.mappingField, instantiators), customFieldProcessor));
128128
} else {
129-
setFieldValue(instance, record.mappingField, binField, JBBPMapper.map((JBBPFieldStruct) binField, curValue, customFieldProcessor));
129+
setFieldValue(instance, record.setter, record.mappingField, binField, JBBPMapper.map((JBBPFieldStruct) binField, curValue, customFieldProcessor));
130130
}
131131
}
132132
} else {
133133
boolean processed = false;
134134
if (record.mappingField.getType() == String.class && binField instanceof JBBPAbstractArrayField) {
135135
final String convertedValue = convertFieldValueToString((JBBPAbstractArrayField<?>) binField);
136136
if (convertedValue != null) {
137-
setFieldValue(instance, record.mappingField, binField, convertedValue);
137+
setFieldValue(instance, record.setter, record.mappingField, binField, convertedValue);
138138
processed = true;
139139
}
140140
}
@@ -146,6 +146,8 @@ public final class MappedFieldRecord implements Comparable<MappedFieldRecord> {
146146

147147
public final Field mappingField;
148148
public final Class<?> mappingClass;
149+
public final Method setter;
150+
public final Method getter;
149151
public final Bin binAnnotation;
150152
public final boolean bitWideField;
151153
public final String fieldName;
@@ -155,8 +157,13 @@ public final class MappedFieldRecord implements Comparable<MappedFieldRecord> {
155157
public final FieldProcessor proc;
156158

157159
MappedFieldRecord(final Field mappingField,
160+
final Method setter,
161+
final Method getter,
158162
final Class<?> mappingClass,
159163
final Bin binAnnotation) {
164+
this.setter = setter;
165+
this.getter = getter;
166+
160167
this.mappingField = mappingField;
161168
this.mappingClass = mappingClass;
162169
this.binAnnotation = binAnnotation;
@@ -190,42 +197,51 @@ public final class MappedFieldRecord implements Comparable<MappedFieldRecord> {
190197
* Map a parsed array to an array field in mapping class.
191198
*
192199
* @param mappingClassInstance a mapping class instance, must not be null
200+
* @param setter detected setter for the field, can be null
193201
* @param mappingField a field in the mapping class to be set, must not be
194202
* null
195203
* @param arrayField a binary parsed array field, must not be null
196204
* @param invertBitOrder flag shows that values of an array must be bit
197205
* reversed before set
198206
*/
199-
private static void mapArrayField(final Object mappingClassInstance, final Field mappingField, final JBBPAbstractArrayField<?> arrayField, final boolean invertBitOrder) {
207+
private static void mapArrayField(final Object mappingClassInstance, final Method setter, final Field mappingField, final JBBPAbstractArrayField<?> arrayField, final boolean invertBitOrder) {
200208
try {
209+
final Object value;
201210
if (arrayField instanceof JBBPFieldArrayLong && mappingField.getType().getComponentType() == double.class) {
202211
final long[] longarray = (long[]) arrayField.getValueArrayAsObject(invertBitOrder);
203212
final double[] doublearray = new double[longarray.length];
204213
for (int i = 0; i < longarray.length; i++) {
205214
doublearray[i] = Double.longBitsToDouble(longarray[i]);
206215
}
207-
mappingField.set(mappingClassInstance, doublearray);
216+
value = doublearray;
208217
} else if (arrayField instanceof JBBPFieldArrayInt && mappingField.getType().getComponentType() == float.class) {
209218
final int[] intarray = (int[]) arrayField.getValueArrayAsObject(invertBitOrder);
210219
final float[] floatarray = new float[intarray.length];
211220
for (int i = 0; i < intarray.length; i++) {
212221
floatarray[i] = Float.intBitsToFloat(intarray[i]);
213222
}
214-
mappingField.set(mappingClassInstance, floatarray);
223+
value = floatarray;
215224
} else if (arrayField instanceof JBBPFieldArrayUShort && mappingField.getType().getComponentType() == char.class) {
216225
final short[] shortarray = (short[]) arrayField.getValueArrayAsObject(invertBitOrder);
217226
final char[] chararray = new char[shortarray.length];
218227
for (int i = 0; i < shortarray.length; i++) {
219228
chararray[i] = (char) shortarray[i];
220229
}
221-
mappingField.set(mappingClassInstance, chararray);
230+
value = chararray;
231+
} else {
232+
value = arrayField.getValueArrayAsObject(invertBitOrder);
233+
}
234+
if (setter == null) {
235+
mappingField.set(mappingClassInstance, value);
222236
} else {
223-
mappingField.set(mappingClassInstance, arrayField.getValueArrayAsObject(invertBitOrder));
237+
setter.invoke(mappingClassInstance, value);
224238
}
225239
} catch (IllegalAccessException ex) {
226240
throw new JBBPMapperException("Can't get access to a mapping field", arrayField, mappingClassInstance.getClass(), mappingField, ex);
227241
} catch (IllegalArgumentException ex) {
228242
throw new JBBPMapperException("Can't set argument to a mapping field", arrayField, mappingClassInstance.getClass(), mappingField, ex);
243+
} catch (InvocationTargetException ex) {
244+
throw new JBBPMapperException("Can't set argument to field through setter", arrayField, mappingClassInstance.getClass(), mappingField, ex);
229245
}
230246
}
231247

@@ -279,38 +295,80 @@ private static String convertFieldValueToString(final JBBPAbstractArrayField<?>
279295
* class.
280296
*
281297
* @param mappingClassInstance the mapping class instance, must not be null
298+
* @param setter detected setter for field, can be null
282299
* @param mappingField a mapping field to set the value, must not be null
283300
* @param numericField a parsed numeric field which value should be used, must
284301
* not be null
285302
* @param invertBitOrder flag shows that the parsed numeric field value must
286303
* be reversed in its bit before setting
287304
*/
288-
private static void mapNumericField(final Object mappingClassInstance, final Field mappingField, final JBBPNumericField numericField, final boolean invertBitOrder) {
305+
private static void mapNumericField(final Object mappingClassInstance, final Method setter, final Field mappingField, final JBBPNumericField numericField, final boolean invertBitOrder) {
289306
final Class<?> fieldClass = mappingField.getType();
290307
try {
291308
if (fieldClass == byte.class) {
292-
mappingField.setByte(mappingClassInstance, (byte) (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsInt()));
309+
final byte value = (byte) (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsInt());
310+
if (setter == null) {
311+
mappingField.setByte(mappingClassInstance, value);
312+
} else {
313+
setter.invoke(mappingClassInstance, value);
314+
}
293315
} else if (fieldClass == boolean.class) {
294-
mappingField.setBoolean(mappingClassInstance, numericField.getAsBool());
316+
if (setter == null) {
317+
mappingField.setBoolean(mappingClassInstance, numericField.getAsBool());
318+
} else {
319+
setter.invoke(mappingClassInstance, numericField.getAsBool());
320+
}
295321
} else if (fieldClass == char.class) {
296-
mappingField.setChar(mappingClassInstance, (char) (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsInt()));
322+
final char value = (char) (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsInt());
323+
if (setter == null) {
324+
mappingField.setChar(mappingClassInstance, value);
325+
} else {
326+
setter.invoke(mappingClassInstance, value);
327+
}
297328
} else if (fieldClass == short.class) {
298-
mappingField.setShort(mappingClassInstance, (short) (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsInt()));
329+
final short value = (short) (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsInt());
330+
if (setter == null) {
331+
mappingField.setShort(mappingClassInstance, value);
332+
} else {
333+
setter.invoke(mappingClassInstance, value);
334+
}
299335
} else if (fieldClass == int.class) {
300-
mappingField.setInt(mappingClassInstance, (int) (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsInt()));
336+
final int value = (int) (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsInt());
337+
if (setter == null) {
338+
mappingField.setInt(mappingClassInstance, value);
339+
} else {
340+
setter.invoke(mappingClassInstance, value);
341+
}
301342
} else if (fieldClass == long.class) {
302-
mappingField.setLong(mappingClassInstance, (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsLong()));
343+
final long value = (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsLong());
344+
if (setter == null) {
345+
mappingField.setLong(mappingClassInstance, value);
346+
} else {
347+
setter.invoke(mappingClassInstance, value);
348+
}
303349
} else if (fieldClass == float.class) {
350+
final float value;
304351
if (numericField instanceof JBBPFieldInt) {
305-
mappingField.setFloat(mappingClassInstance, invertBitOrder ? Float.intBitsToFloat((int) numericField.getAsInvertedBitOrder()) : Float.intBitsToFloat(numericField.getAsInt()));
352+
value = invertBitOrder ? Float.intBitsToFloat((int) numericField.getAsInvertedBitOrder()) : Float.intBitsToFloat(numericField.getAsInt());
306353
} else {
307-
mappingField.setFloat(mappingClassInstance, invertBitOrder ? Float.intBitsToFloat((int) numericField.getAsInvertedBitOrder()) : numericField.getAsFloat());
354+
value = invertBitOrder ? Float.intBitsToFloat((int) numericField.getAsInvertedBitOrder()) : numericField.getAsFloat();
355+
}
356+
if (setter == null) {
357+
mappingField.setFloat(mappingClassInstance, value);
358+
} else {
359+
setter.invoke(mappingClassInstance, value);
308360
}
309361
} else if (fieldClass == double.class) {
362+
final double value;
310363
if (numericField instanceof JBBPFieldLong) {
311-
mappingField.setDouble(mappingClassInstance, invertBitOrder ? Double.longBitsToDouble(numericField.getAsInvertedBitOrder()) : Double.longBitsToDouble(numericField.getAsLong()));
364+
value = invertBitOrder ? Double.longBitsToDouble(numericField.getAsInvertedBitOrder()) : Double.longBitsToDouble(numericField.getAsLong());
365+
} else {
366+
value = invertBitOrder ? Double.longBitsToDouble(numericField.getAsInvertedBitOrder()) : numericField.getAsDouble();
367+
}
368+
if (setter == null) {
369+
mappingField.setDouble(mappingClassInstance, value);
312370
} else {
313-
mappingField.setDouble(mappingClassInstance, invertBitOrder ? Double.longBitsToDouble(numericField.getAsInvertedBitOrder()) : numericField.getAsDouble());
371+
setter.invoke(mappingClassInstance, value);
314372
}
315373
} else {
316374
throw new JBBPMapperException("Unsupported mapping class field type to be mapped for binary parsed data", (JBBPAbstractField) numericField, mappingClassInstance.getClass(), mappingField, null);
@@ -319,24 +377,33 @@ private static void mapNumericField(final Object mappingClassInstance, final Fie
319377
throw new JBBPMapperException("Can't get access to a mapping field", (JBBPAbstractField) numericField, mappingClassInstance.getClass(), mappingField, ex);
320378
} catch (IllegalArgumentException ex) {
321379
throw new JBBPMapperException("Can't set argument to a mapping field", (JBBPAbstractField) numericField, mappingClassInstance.getClass(), mappingField, ex);
380+
} catch (InvocationTargetException ex) {
381+
throw new JBBPMapperException("Can't set argument to a mapping field through setter", (JBBPAbstractField) numericField, mappingClassInstance.getClass(), mappingField, ex);
322382
}
323383
}
324384

325385
/**
326386
* Get a value of a field from a class instance.
327387
*
328388
* @param classInstance a class instance object
389+
* @param getter method to get field value, can be null
329390
* @param classField a class field which value must be returned, must not be
330391
* null
331392
* @return the field value for the class instance
332393
*/
333-
private static Object getFieldValue(final Object classInstance, final Field classField) {
394+
private static Object getFieldValue(final Object classInstance, final Method getter, final Field classField) {
334395
try {
335-
return classField.get(classInstance);
396+
if (getter == null)
397+
return classField.get(classInstance);
398+
else {
399+
return getter.invoke(classInstance);
400+
}
336401
} catch (IllegalArgumentException ex) {
337402
throw new JBBPMapperException("Can't set get value from a mapping field", null, classInstance.getClass(), classField, ex);
338403
} catch (IllegalAccessException ex) {
339404
throw new JBBPMapperException("Can't get access to a mapping field", null, classInstance.getClass(), classField, ex);
405+
} catch (InvocationTargetException ex) {
406+
throw new JBBPMapperException("Can't get field value through getter", null, classInstance.getClass(), classField, ex);
340407
}
341408
}
342409

@@ -345,18 +412,25 @@ private static Object getFieldValue(final Object classInstance, final Field clas
345412
* fields!
346413
*
347414
* @param classInstance a class instance
415+
* @param setter setter for the field, can be null
348416
* @param classField a mapping class field which should be set by the value,
349417
* must not be null
350418
* @param binField a parsed bin field which value will be set, can be null
351419
* @param value a value to be set to the class field
352420
*/
353-
static void setFieldValue(final Object classInstance, final Field classField, final JBBPAbstractField binField, final Object value) {
421+
static void setFieldValue(final Object classInstance, final Method setter, final Field classField, final JBBPAbstractField binField, final Object value) {
354422
try {
355-
classField.set(classInstance, value);
423+
if (setter == null)
424+
classField.set(classInstance, value);
425+
else {
426+
setter.invoke(classInstance, value);
427+
}
356428
} catch (IllegalArgumentException ex) {
357429
throw new JBBPMapperException("Can't set value to a mapping field", binField, classInstance.getClass(), classField, ex);
358430
} catch (IllegalAccessException ex) {
359431
throw new JBBPMapperException("Can't get access to a mapping field", binField, classInstance.getClass(), classField, ex);
432+
} catch (InvocationTargetException ex) {
433+
throw new JBBPMapperException("Can't set field value through setter", binField, classInstance.getClass(), classField, ex);
360434
}
361435
}
362436

0 commit comments

Comments
 (0)