Skip to content

Commit fcc4f16

Browse files
committed
Modify set value
1 parent 455196d commit fcc4f16

10 files changed

Lines changed: 230 additions & 94 deletions

File tree

pom.xml

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
<groupId>in.kuros</groupId>
1414
<artifactId>jFirebase</artifactId>
15-
<version>0.6.8</version>
15+
<version>0.6.9</version>
1616

1717

1818
<description>This project aims at building a wrapper over nosql technologies - Firebase</description>
@@ -75,6 +75,11 @@
7575
<artifactId>reflections</artifactId>
7676
<version>0.9.11</version>
7777
</dependency>
78+
<dependency>
79+
<groupId>com.fasterxml.jackson.core</groupId>
80+
<artifactId>jackson-databind</artifactId>
81+
<version>2.11.2</version>
82+
</dependency>
7883
<dependency>
7984
<groupId>com.google.firebase</groupId>
8085
<artifactId>firebase-admin</artifactId>
@@ -123,7 +128,7 @@
123128
<plugin>
124129
<groupId>org.apache.maven.plugins</groupId>
125130
<artifactId>maven-compiler-plugin</artifactId>
126-
<version>3.6.2</version>
131+
<version>3.8.1</version>
127132
<configuration>
128133
<source>1.8</source>
129134
<target>1.8</target>
@@ -134,7 +139,7 @@
134139
<plugin>
135140
<groupId>org.apache.maven.plugins</groupId>
136141
<artifactId>maven-release-plugin</artifactId>
137-
<version>2.1</version>
142+
<version>3.0.0-M1</version>
138143
<configuration>
139144
<arguments>-Psonatype-oss-release,random-jpa-release</arguments>
140145
<pushChanges>false</pushChanges>
@@ -178,15 +183,15 @@
178183
<plugin>
179184
<groupId>org.apache.maven.plugins</groupId>
180185
<artifactId>maven-deploy-plugin</artifactId>
181-
<version>2.7</version>
186+
<version>2.8.2</version>
182187
<configuration>
183188
<updateReleaseInfo>true</updateReleaseInfo>
184189
</configuration>
185190
</plugin>
186191
<plugin>
187192
<groupId>org.apache.maven.plugins</groupId>
188193
<artifactId>maven-source-plugin</artifactId>
189-
<version>2.4</version>
194+
<version>3.1.0</version>
190195
<executions>
191196
<execution>
192197
<id>attach-sources</id>
@@ -200,6 +205,10 @@
200205
<groupId>org.apache.maven.plugins</groupId>
201206
<artifactId>maven-javadoc-plugin</artifactId>
202207
<version>3.2.0</version>
208+
<configuration>
209+
<source>8</source>
210+
<detectJavaApiLink>false</detectJavaApiLink>
211+
</configuration>
203212
<executions>
204213
<execution>
205214
<id>attach-javadocs</id>
@@ -232,7 +241,7 @@
232241
<plugins>
233242
<plugin>
234243
<artifactId>maven-assembly-plugin</artifactId>
235-
<version>2.3</version>
244+
<version>3.1.1</version>
236245
<configuration>
237246
<descriptorRefs>
238247
<descriptorRef>jar-with-dependencies</descriptorRef>

src/main/java/in/kuros/jfirebase/metadata/SetAttribute.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ public final class SetAttribute<T> {
99

1010
private final List<AttributeValue<T, ?>> keys;
1111
private final List<AttributeValue<T, ?>> attributesToUpdate;
12+
private final List<ValuePath<?>> valuePaths;
1213

1314
private SetAttribute(final AttributeValue<T, ?> key) {
1415
keys = new ArrayList<>();
1516
keys.add(key);
1617
attributesToUpdate = new ArrayList<>();
18+
valuePaths = new ArrayList<>();
1719
}
1820

1921
public static <T, K, V> SetAttribute<T> withKeys(final Attribute<T, V> attribute, final V value) {
@@ -45,6 +47,11 @@ public <K, V> SetAttribute<T> set(final MapAttribute<T, K, V> mapAttribute, fina
4547
return this;
4648
}
4749

50+
public SetAttribute<T> set(final ValuePath valuePath) {
51+
valuePaths.add(valuePath);
52+
return this;
53+
}
54+
4855

4956
public interface Helper {
5057
static <T> List<AttributeValue<T, ?>> getKeys(SetAttribute<T> updateAttribute) {
@@ -56,6 +63,10 @@ public interface Helper {
5663
.attributesToUpdate;
5764
}
5865

66+
static <T> List<ValuePath<?>> getValuePaths(SetAttribute<T> setAttribute) {
67+
return setAttribute.valuePaths;
68+
}
69+
5970
static <T> Class<T> getDeclaringClass(SetAttribute<T> updateAttribute) {
6071
if (updateAttribute.keys.isEmpty()) {
6172
throw new IllegalStateException("No Keys provided");

src/main/java/in/kuros/jfirebase/metadata/UpdateAttribute.java

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
package in.kuros.jfirebase.metadata;
22

3-
import com.google.common.collect.Lists;
43
import in.kuros.jfirebase.util.CustomCollectors;
54

65
import java.util.ArrayList;
7-
import java.util.Arrays;
86
import java.util.List;
97
import java.util.Map;
108
import java.util.function.Supplier;
11-
import java.util.stream.Collectors;
129

1310

1411
public final class UpdateAttribute<T> {
@@ -64,12 +61,8 @@ public <K, V> UpdateAttribute<T> update(final MapAttribute<T, K, V> mapAttribute
6461
}
6562

6663

67-
public <V> UpdateAttribute<T> update(final Attribute<T, ?> attribute, final ValuePath<V> valuePath) {
68-
final List<String> path = Lists.newArrayList(attribute.getName());
69-
path.addAll(Arrays.asList(valuePath.getPath()));
70-
71-
final String joinedPath = String.join(".", path);
72-
valuePaths.add(new ValuePath<>(valuePath.getValue(), joinedPath));
64+
public <V> UpdateAttribute<T> update(final ValuePath<V> valuePath) {
65+
valuePaths.add(valuePath);
7366
return this;
7467
}
7568

@@ -88,13 +81,5 @@ public interface Helper {
8881
return updateAttribute.valuePaths.stream()
8982
.collect(CustomCollectors.toMap(vp -> vp.getPath()[0], ValuePath::getValue));
9083
}
91-
92-
static <T> Class<T> getDeclaringClass(UpdateAttribute<T> updateAttribute) {
93-
if (updateAttribute.keys.isEmpty()) {
94-
throw new IllegalStateException("No Keys provided");
95-
}
96-
97-
return updateAttribute.keys.get(0).getAttribute().getDeclaringType();
98-
}
9984
}
10085
}

src/main/java/in/kuros/jfirebase/provider/firebase/AttributeValueHelper.java

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package in.kuros.jfirebase.provider.firebase;
22

3+
import com.fasterxml.jackson.databind.ObjectMapper;
34
import com.google.cloud.firestore.FieldPath;
45
import in.kuros.jfirebase.exception.PersistenceException;
56
import in.kuros.jfirebase.metadata.AttributeValue;
67
import in.kuros.jfirebase.metadata.MapAttributeValue;
8+
import in.kuros.jfirebase.metadata.ValuePath;
79
import in.kuros.jfirebase.util.CustomCollectors;
810

911
import java.lang.reflect.Constructor;
@@ -15,6 +17,8 @@
1517

1618
public class AttributeValueHelper {
1719

20+
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
21+
1822
private final EntityHelper entityHelper;
1923

2024
public AttributeValueHelper() {
@@ -116,4 +120,65 @@ private <T> Class<T> getDeclaringClass(final List<AttributeValue<T, ?>> attribut
116120

117121
return attributeValues.get(0).getAttribute().getDeclaringType();
118122
}
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+
}
119184
}

src/main/java/in/kuros/jfirebase/provider/firebase/EntityHelper.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,23 @@
22

33
import in.kuros.jfirebase.entity.Entity;
44
import in.kuros.jfirebase.entity.EntityDeclarationException;
5+
import in.kuros.jfirebase.metadata.AttributeValue;
56

67
import java.lang.reflect.Field;
8+
import java.util.List;
9+
import java.util.Optional;
710
import java.util.Set;
811

912
public interface EntityHelper {
1013

1114
<T> String getDocumentPath(T entity);
1215

16+
<T> String getDocumentPath(List<AttributeValue<T, ?>> attributeValues);
17+
1318
<T> String getCollectionPath(T entity);
1419

20+
<T> String getCollectionPath(List<AttributeValue<T, ?>> attributeValues);
21+
1522
<T> void setId(T entity, String id);
1623

1724
<T> String getId(T entity);
@@ -22,6 +29,8 @@ public interface EntityHelper {
2229

2330
Field getUpdateTimeField(Class<?> type);
2431

32+
Optional<String> getUpdateTimeFieldName(Class<?> type);
33+
2534
<T> Set<Field> getAllRequiredIdFields(Class<T> type);
2635

2736
<T> void validateIdsNotNull(T object);

src/main/java/in/kuros/jfirebase/provider/firebase/EntityHelperImpl.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,22 @@
1414
import in.kuros.jfirebase.entity.IdReference;
1515
import in.kuros.jfirebase.entity.UpdateTime;
1616
import in.kuros.jfirebase.exception.PersistenceException;
17+
import in.kuros.jfirebase.metadata.Attribute;
18+
import in.kuros.jfirebase.metadata.AttributeValue;
19+
import in.kuros.jfirebase.metadata.Value;
1720

1821
import java.lang.reflect.Field;
1922
import java.lang.reflect.InvocationTargetException;
2023
import java.lang.reflect.Method;
2124
import java.util.Date;
2225
import java.util.List;
26+
import java.util.Map;
2327
import java.util.Objects;
28+
import java.util.Optional;
2429
import java.util.Set;
2530
import java.util.concurrent.ExecutionException;
31+
import java.util.function.Function;
32+
import java.util.stream.Collectors;
2633

2734
public class EntityHelperImpl implements EntityHelper {
2835

@@ -201,6 +208,11 @@ public Field getUpdateTimeField(final Class<?> type) {
201208
}
202209
}
203210

211+
@Override
212+
public Optional<String> getUpdateTimeFieldName(final Class<?> type) {
213+
return Optional.ofNullable(getUpdateTimeField(type)).map(Field::getName);
214+
}
215+
204216
@Override
205217
public <T> void validateIdsNotNull(final T object) {
206218
try {
@@ -232,6 +244,58 @@ public <T> Set<Field> getAllRequiredIdFields(final Class<T> type) {
232244
}
233245
}
234246

247+
@Override
248+
public <T> String getDocumentPath(final List<AttributeValue<T, ?>> attributeValues) {
249+
final Class<T> declaringClass = getDeclaringClass(attributeValues);
250+
final Field idField = getIdField(declaringClass);
251+
final String idValue = attributeValues.stream()
252+
.filter(attr -> attr.getAttribute().getField().equals(idField))
253+
.findFirst()
254+
.map(AttributeValue::getAttributeValue)
255+
.map(Value::getValue)
256+
.map(Object::toString)
257+
.orElseThrow(() -> new IllegalArgumentException("Id value not set"));
258+
259+
return getCollectionPath(attributeValues) + "/" + idValue;
260+
}
261+
262+
@Override
263+
public <T> String getCollectionPath(final List<AttributeValue<T, ?>> attributeValues) {
264+
final Class<T> declaringClass = getDeclaringClass(attributeValues);
265+
final Entity entity = EntityHelper.getEntity(declaringClass);
266+
267+
return getParentPath(attributeValues) + entity.value();
268+
}
269+
270+
private <T> String getParentPath(final List<AttributeValue<T, ?>> attributeValues) {
271+
final StringBuilder stringBuilder = new StringBuilder();
272+
final Class<T> declaringClass = getDeclaringClass(attributeValues);
273+
274+
final Map<String, AttributeValue<T, ?>> valueMap = attributeValues.stream()
275+
.collect(Collectors.toMap(attr -> attr.getAttribute().getName(), Function.identity()));
276+
277+
final List<MappedClassField> mappedClassFields = EntityParentCache.INSTANCE.getMappedClassFields(declaringClass);
278+
279+
for (MappedClassField mappedClassField : mappedClassFields) {
280+
281+
final String parentId = valueMap.get(mappedClassField.getField().getName()).getAttributeValue().getValue().toString();
282+
if (parentId == null) {
283+
throw new EntityDeclarationException("parent id cannot be null: " + mappedClassField.getField());
284+
}
285+
286+
stringBuilder.append(getParentCollection(mappedClassField))
287+
.append("/")
288+
.append(parentId)
289+
.append("/");
290+
}
291+
292+
return stringBuilder.toString();
293+
}
294+
295+
private <T> Class<T> getDeclaringClass(final List<AttributeValue<T, ?>> attributeValues) {
296+
return attributeValues.stream().findFirst().map(AttributeValue::getAttribute).map(Attribute::getDeclaringType).orElseThrow(() -> new IllegalArgumentException("Keys not set"));
297+
}
298+
235299
private List<Field> getIdReferenceFields(final Class<?> type) throws ExecutionException {
236300
return idReferences.get(type, () -> {
237301
final List<Field> references = Lists.newArrayList();

0 commit comments

Comments
 (0)