Skip to content

Commit ed3607a

Browse files
Fold FlexMapConverter into FlexObjectConverter.
1 parent f103488 commit ed3607a

File tree

10 files changed

+81
-304
lines changed

10 files changed

+81
-304
lines changed

objectbox-java/src/main/java/io/objectbox/converter/FlexMapConverter.java

Lines changed: 0 additions & 246 deletions
This file was deleted.

objectbox-java/src/main/java/io/objectbox/converter/FlexObjectConverter.java

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@
1616
* Converts between {@link Object} properties and byte arrays using FlexBuffers.
1717
* <p>
1818
* Types are limited to those supported by FlexBuffers, including that map keys must be {@link String}.
19+
* (There are subclasses available that auto-convert {@link Integer} and {@link Long} key maps,
20+
* see {@link #convertToKey}.)
1921
* <p>
20-
* Regardless of the stored type, integers are restored as {@link Long} if the value does not fit {@link Integer},
21-
* otherwise as {@link Integer}. So e.g. when storing a {@link Long} value of {@code 1L}, the value restored from the
22+
* If any item requires 64 bits for storage in the FlexBuffers Map/Vector (a large Long, a Double)
23+
* all integers are restored as {@link Long}, otherwise {@link Integer}.
24+
* So e.g. when storing only a {@link Long} value of {@code 1L}, the value restored from the
2225
* database will be of type {@link Integer}.
26+
* (There are subclasses available that always restore as {@link Long}, see {@link #shouldRestoreAsLong}.)
2327
* <p>
2428
* Values of type {@link Float} are always restored as {@link Double}.
2529
* Cast to {@link Float} to obtain the original value.
@@ -85,6 +89,15 @@ private void addValue(FlexBuffersBuilder builder, Object value) {
8589
}
8690
}
8791

92+
/**
93+
* Checks Java map key is of the expected type, otherwise throws.
94+
*/
95+
protected void checkMapKeyType(Object rawKey) {
96+
if (!(rawKey instanceof String)) {
97+
throw new IllegalArgumentException("Map keys must be String");
98+
}
99+
}
100+
88101
private void addMap(FlexBuffersBuilder builder, String mapKey, Map<Object, Object> map) {
89102
int mapStart = builder.startMap();
90103

@@ -94,9 +107,7 @@ private void addMap(FlexBuffersBuilder builder, String mapKey, Map<Object, Objec
94107
if (rawKey == null || value == null) {
95108
throw new IllegalArgumentException("Map keys or values must not be null");
96109
}
97-
if (!(rawKey instanceof String)) {
98-
throw new IllegalArgumentException("Map keys must be String");
99-
}
110+
checkMapKeyType(rawKey);
100111
String key = rawKey.toString();
101112
if (value instanceof Map) {
102113
//noinspection unchecked
@@ -189,13 +200,22 @@ public Object convertToEntityProperty(byte[] databaseValue) {
189200
}
190201
}
191202

203+
/**
204+
* Converts a FlexBuffers string map key to the Java map key (e.g. String to Integer).
205+
* <p>
206+
* This required conversion restricts all keys (root and embedded maps) to the same type.
207+
*/
208+
Object convertToKey(String keyValue) {
209+
return keyValue;
210+
}
211+
192212
/**
193213
* Returns true if the width in bytes stored in the private parentWidth field of FlexBuffers.Reference is 8.
194214
* Note: FlexBuffers stores all items in a map/vector using the size of the widest item. However,
195215
* an item's size is only as wide as needed, e.g. a 64-bit integer (Java Long, 8 bytes) will be
196216
* reduced to 1 byte if it does not exceed its value range.
197217
*/
198-
private boolean shouldRestoreAsLong(FlexBuffers.Reference reference) {
218+
protected boolean shouldRestoreAsLong(FlexBuffers.Reference reference) {
199219
try {
200220
Field parentWidthF = reference.getClass().getDeclaredField("parentWidth");
201221
parentWidthF.setAccessible(true);
@@ -217,7 +237,8 @@ private Map<Object, Object> buildMap(FlexBuffers.Map map) {
217237
// So set initial capacity based on default load factor 0.75 accordingly.
218238
Map<Object, Object> resultMap = new HashMap<>((int) (entryCount / 0.75 + 1));
219239
for (int i = 0; i < entryCount; i++) {
220-
String key = keys.get(i).toString();
240+
String rawKey = keys.get(i).toString();
241+
Object key = convertToKey(rawKey);
221242
FlexBuffers.Reference value = values.get(i);
222243
if (value.isMap()) {
223244
resultMap.put(key, buildMap(value.asMap()));

objectbox-java/src/main/java/io/objectbox/converter/IntegerFlexMapConverter.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
package io.objectbox.converter;
22

33
/**
4-
* Used to automatically convert {@code Map<Integer, V>}.
4+
* Used to automatically convert {@code Map&lt;Integer, V&gt;}.
55
*/
6-
public class IntegerFlexMapConverter extends FlexMapConverter {
6+
public class IntegerFlexMapConverter extends FlexObjectConverter {
7+
8+
@Override
9+
protected void checkMapKeyType(Object rawKey) {
10+
if (!(rawKey instanceof Integer)) {
11+
throw new IllegalArgumentException("Map keys must be Integer");
12+
}
13+
}
14+
715
@Override
816
Integer convertToKey(String keyValue) {
917
return Integer.valueOf(keyValue);

objectbox-java/src/main/java/io/objectbox/converter/IntegerLongMapConverter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import io.objectbox.flatbuffers.FlexBuffers;
44

55
/**
6-
* Used to automatically convert {@code Map<Integer, Long>}.
6+
* Used to automatically convert {@code Map&lt;Integer, Long&gt;}.
7+
* <p>
8+
* Unlike {@link FlexObjectConverter} always restores integer map values as {@link Long}.
79
*/
810
public class IntegerLongMapConverter extends IntegerFlexMapConverter {
911
@Override

objectbox-java/src/main/java/io/objectbox/converter/LongFlexMapConverter.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,15 @@
33
/**
44
* Used to automatically convert {@code Map<Long, V>}.
55
*/
6-
public class LongFlexMapConverter extends FlexMapConverter {
6+
public class LongFlexMapConverter extends FlexObjectConverter {
7+
8+
@Override
9+
protected void checkMapKeyType(Object rawKey) {
10+
if (!(rawKey instanceof Long)) {
11+
throw new IllegalArgumentException("Map keys must be Long");
12+
}
13+
}
14+
715
@Override
816
Object convertToKey(String keyValue) {
917
return Long.valueOf(keyValue);

objectbox-java/src/main/java/io/objectbox/converter/LongLongMapConverter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import io.objectbox.flatbuffers.FlexBuffers;
44

55
/**
6-
* Used to automatically convert {@code Map<Long, Long>}.
6+
* Used to automatically convert {@code Map&lt;Long, Long&gt;}.
7+
* <p>
8+
* Unlike {@link FlexObjectConverter} always restores integer map values as {@link Long}.
79
*/
810
public class LongLongMapConverter extends LongFlexMapConverter {
911
@Override
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
package io.objectbox.converter;
22

33
/**
4-
* Used to automatically convert {@code Map<String, V>}.
4+
* Used to automatically convert {@code Map&lt;String, V&gt;}.
55
*/
6-
public class StringFlexMapConverter extends FlexMapConverter {
7-
@Override
8-
Object convertToKey(String keyValue) {
9-
return keyValue;
10-
}
6+
public class StringFlexMapConverter extends FlexObjectConverter {
117
}

0 commit comments

Comments
 (0)