|
1 | 1 | package in.kuros.jfirebase.provider.firebase; |
2 | 2 |
|
| 3 | +import com.fasterxml.jackson.databind.ObjectMapper; |
3 | 4 | import com.google.cloud.firestore.FieldPath; |
4 | 5 | import in.kuros.jfirebase.exception.PersistenceException; |
5 | 6 | import in.kuros.jfirebase.metadata.AttributeValue; |
6 | 7 | import in.kuros.jfirebase.metadata.MapAttributeValue; |
| 8 | +import in.kuros.jfirebase.metadata.ValuePath; |
7 | 9 | import in.kuros.jfirebase.util.CustomCollectors; |
8 | 10 |
|
9 | 11 | import java.lang.reflect.Constructor; |
|
15 | 17 |
|
16 | 18 | public class AttributeValueHelper { |
17 | 19 |
|
| 20 | + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); |
| 21 | + |
18 | 22 | private final EntityHelper entityHelper; |
19 | 23 |
|
20 | 24 | public AttributeValueHelper() { |
@@ -116,4 +120,65 @@ private <T> Class<T> getDeclaringClass(final List<AttributeValue<T, ?>> attribut |
116 | 120 |
|
117 | 121 | return attributeValues.get(0).getAttribute().getDeclaringType(); |
118 | 122 | } |
| 123 | + |
| 124 | + @SuppressWarnings({"rawtypes", "unchecked"}) |
| 125 | + public <T> Map<String, Object> convertToObjectMap(final List<AttributeValue<T, ?>> attributeValues) { |
| 126 | + final Map<String, Object> result = new HashMap<>(); |
| 127 | + |
| 128 | + for (AttributeValue<T, ?> attributeValue : attributeValues) { |
| 129 | + if (MapAttributeValue.class.isAssignableFrom(attributeValue.getClass()) |
| 130 | + && ((MapAttributeValue) attributeValue).isKeyUpdate()) { |
| 131 | + final MapAttributeValue mapAttributeValue = (MapAttributeValue) attributeValue; |
| 132 | + if (!(mapAttributeValue.getKey() instanceof String)) { |
| 133 | + throw new IllegalArgumentException("Object keys are not supported in firebase/firestore"); |
| 134 | + } |
| 135 | + final String attributeName = attributeValue.getAttribute().getName(); |
| 136 | + final Map<String, Object> mapField = (Map<String, Object>) result.getOrDefault(attributeName, new HashMap<>()); |
| 137 | + mapField.put((String) mapAttributeValue.getKey(), parseValue(mapAttributeValue.getMapValue().getValue())); |
| 138 | + result.put(attributeName, mapField); |
| 139 | + } else { |
| 140 | + result.put(attributeValue.getAttribute().getName(), parseValue(attributeValue.getAttributeValue().getValue())); |
| 141 | + } |
| 142 | + } |
| 143 | + |
| 144 | + return result; |
| 145 | + } |
| 146 | + |
| 147 | + private Object parseValue(final Object value) { |
| 148 | + if (value instanceof Number || value instanceof String || value instanceof List) { |
| 149 | + return value; |
| 150 | + } |
| 151 | + |
| 152 | + if (value instanceof Enum<?>) { |
| 153 | + return ((Enum<?>)value).name(); |
| 154 | + } |
| 155 | + |
| 156 | + return OBJECT_MAPPER.convertValue(value, Map.class); |
| 157 | + } |
| 158 | + |
| 159 | + public void addValuePaths(final Map<String, Object> objectMap, final List<ValuePath<?>> valuePaths) { |
| 160 | + for (ValuePath<?> valuePath : valuePaths) { |
| 161 | + addValuePath(objectMap, valuePath, 0); |
| 162 | + } |
| 163 | + } |
| 164 | + |
| 165 | + public List<FieldPath> convertValuePathToFieldPaths(List<ValuePath<?>> valuePaths) { |
| 166 | + return valuePaths |
| 167 | + .stream() |
| 168 | + .map(valuePath -> FieldPath.of(valuePath.getPath())) |
| 169 | + .collect(Collectors.toList()); |
| 170 | + } |
| 171 | + |
| 172 | + @SuppressWarnings("unchecked") |
| 173 | + private void addValuePath(final Map<String, Object> objectMap, final ValuePath valuePath, final int index) { |
| 174 | + if (index + 1 >= valuePath.getPath().length) { |
| 175 | + objectMap.put(valuePath.getPath()[index], parseValue(valuePath.getValue())); |
| 176 | + return; |
| 177 | + } |
| 178 | + |
| 179 | + final Map<String, Object> out = (Map<String, Object>) objectMap.getOrDefault(valuePath.getPath()[index], new HashMap<>()); |
| 180 | + addValuePath(out, valuePath, index + 1); |
| 181 | + objectMap.put(valuePath.getPath()[index], out); |
| 182 | + |
| 183 | + } |
119 | 184 | } |
0 commit comments