|
| 1 | +package io.objectbox.converter; |
| 2 | + |
| 3 | +import io.objectbox.flatbuffers.ArrayReadWriteBuf; |
| 4 | +import io.objectbox.flatbuffers.FlexBuffers; |
| 5 | +import io.objectbox.flatbuffers.FlexBuffersBuilder; |
| 6 | + |
| 7 | +import java.nio.ByteBuffer; |
| 8 | +import java.util.HashMap; |
| 9 | +import java.util.Map; |
| 10 | +import java.util.Map.Entry; |
| 11 | + |
| 12 | +/** |
| 13 | + * Converts a String map entity property to a byte array database value using FlexBuffers. |
| 14 | + */ |
| 15 | +public class StringMapConverter implements PropertyConverter<Map<String, String>, byte[]> { |
| 16 | + @Override |
| 17 | + public byte[] convertToDatabaseValue(Map<String, String> map) { |
| 18 | + if (map == null) return null; |
| 19 | + |
| 20 | + FlexBuffersBuilder builder = new FlexBuffersBuilder( |
| 21 | + new ArrayReadWriteBuf(), |
| 22 | + FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS |
| 23 | + ); |
| 24 | + int mapStart = builder.startMap(); |
| 25 | + |
| 26 | + for (Entry<String, String> entry : map.entrySet()) { |
| 27 | + if (entry.getKey() == null || entry.getValue() == null) { |
| 28 | + throw new IllegalArgumentException("Map keys or values must not be null"); |
| 29 | + } |
| 30 | + builder.putString(entry.getKey(), entry.getValue()); |
| 31 | + } |
| 32 | + |
| 33 | + builder.endMap(null, mapStart); |
| 34 | + ByteBuffer buffer = builder.finish(); |
| 35 | + |
| 36 | + byte[] out = new byte[buffer.limit()]; |
| 37 | + buffer.get(out); |
| 38 | + return out; |
| 39 | + } |
| 40 | + |
| 41 | + @Override |
| 42 | + public Map<String, String> convertToEntityProperty(byte[] databaseValue) { |
| 43 | + if (databaseValue == null) return null; |
| 44 | + |
| 45 | + FlexBuffers.Map map = FlexBuffers.getRoot(new ArrayReadWriteBuf(databaseValue, databaseValue.length)).asMap(); |
| 46 | + |
| 47 | + // As recommended by docs, iterate keys and values vectors in parallel to avoid binary search of key vector. |
| 48 | + int entryCount = map.size(); |
| 49 | + FlexBuffers.KeyVector keys = map.keys(); |
| 50 | + FlexBuffers.Vector values = map.values(); |
| 51 | + Map<String, String> resultMap = new HashMap<>(entryCount); |
| 52 | + for (int i = 0; i < entryCount; i++) { |
| 53 | + String key = keys.get(i).toString(); |
| 54 | + String value = values.get(i).asString(); |
| 55 | + resultMap.put(key, value); |
| 56 | + } |
| 57 | + |
| 58 | + return resultMap; |
| 59 | + } |
| 60 | +} |
0 commit comments