Skip to content

Commit e04ab17

Browse files
authored
SUPPORT-28804 add custom deserializer for attrs in import api (#748)
1 parent a248061 commit e04ab17

File tree

10 files changed

+1118
-239
lines changed

10 files changed

+1118
-239
lines changed

.git-blame-ignore-revs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ a8ec45c8ea4ba559247b654d01b0d35b21a68865
44
d0129c1095216d5c830900c8a6223ef5d4274de1
55
4bc5c823b8ebf5a00491c7e63e1ea49d29bf5ee7
66
352051999507bd78542e177d67ce1548a0752691
7+
bbe9f971763ca1b27687a6a51067a385a0d23b04

commercetools/commercetools-sdk-java-api/src/integrationTest/java/cleanup/DeleteEverythingIntegrationTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,15 @@ public void execute() {
8282
}
8383
}
8484

85-
private <TMethod extends SimplePagedQueryResourceRequest<TMethod, TResult, ?>, TResult extends ResourcePagedQueryResponse<TElement>, TElement extends DomainResource<TElement>> void deleteAllResources(
85+
private static <TMethod extends SimplePagedQueryResourceRequest<TMethod, TResult, ?>, TResult extends ResourcePagedQueryResponse<TElement>, TElement extends DomainResource<TElement>> void deleteAllResources(
8686
SimplePagedQueryResourceRequest<TMethod, TResult, ?> request, Consumer<TElement> deleteFn) {
8787

8888
QueryUtils.queryAll(request, list -> {
8989
list.forEach(deleteFn);
9090
}, 100).toCompletableFuture().join();
9191
}
9292

93-
private void checkDepends(Runnable block) {
93+
public static void checkDepends(Runnable block) {
9494
assertEventually(Duration.ofSeconds(60), Duration.ofMillis(1000), block);
9595
}
9696

@@ -212,7 +212,7 @@ private void deleteAllCategories() {
212212
} while (response.getResults().size() != 0);
213213
}
214214

215-
private void deleteAllCartDiscounts() {
215+
public static void deleteAllCartDiscounts() {
216216
checkDepends(() -> Assertions.assertThat(
217217
CommercetoolsTestUtils.getProjectApiRoot().discountCodes().get().executeBlocking().getBody().getCount())
218218
.isZero());

commercetools/commercetools-sdk-java-api/src/integrationTest/java/commercetools/cart_discount/CartDiscountIntegrationTests.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
package commercetools.cart_discount;
33

4+
import static cleanup.DeleteEverythingIntegrationTest.deleteAllCartDiscounts;
45
import static commercetools.cart_discount.CartDiscountFixtures.*;
56
import static commercetools.type.TypeFixtures.getFieldName;
67

@@ -16,10 +17,18 @@
1617
import commercetools.utils.CommercetoolsTestUtils;
1718

1819
import org.assertj.core.api.Assertions;
20+
import org.junit.jupiter.api.AfterAll;
21+
import org.junit.jupiter.api.BeforeAll;
1922
import org.junit.jupiter.api.Test;
2023

2124
public class CartDiscountIntegrationTests {
2225

26+
@BeforeAll
27+
@AfterAll
28+
public static void deleteCartDiscounts() {
29+
deleteAllCartDiscounts();
30+
}
31+
2332
@Test
2433
public void ref() {
2534
Optional<ReferenceTypeId> optional = ReferenceTypeId.findEnumViaJsonName("product-type");

commercetools/commercetools-sdk-java-api/src/main/java/com/commercetools/api/json/ApiModule.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public ApiModule(ModuleOptions options) {
4242
}
4343
else {
4444
addDeserializer(AttributeImpl.class,
45-
new AtrributeDeserializer(attributeAsDateString, attributeNumberAsDouble));
45+
new AttributeDeserializer(attributeAsDateString, attributeNumberAsDouble));
4646
}
4747
if (customFieldAsJsonNode) {
4848
addDeserializer(FieldContainerImpl.class, new CustomFieldJsonNodeDeserializer());
Lines changed: 8 additions & 235 deletions
Original file line numberDiff line numberDiff line change
@@ -1,247 +1,20 @@
11

22
package com.commercetools.api.json;
33

4-
import java.io.IOException;
5-
import java.time.LocalDate;
6-
import java.time.LocalTime;
7-
import java.time.ZonedDateTime;
8-
import java.util.List;
9-
import java.util.regex.Pattern;
10-
11-
import com.commercetools.api.models.common.LocalizedString;
12-
import com.commercetools.api.models.common.Reference;
13-
import com.commercetools.api.models.common.TypedMoney;
14-
import com.commercetools.api.models.product.*;
15-
import com.commercetools.api.models.product_type.AttributeLocalizedEnumValue;
16-
import com.commercetools.api.models.product_type.AttributePlainEnumValue;
17-
import com.fasterxml.jackson.core.JsonParser;
18-
import com.fasterxml.jackson.core.type.TypeReference;
19-
import com.fasterxml.jackson.databind.DeserializationContext;
20-
import com.fasterxml.jackson.databind.JsonDeserializer;
21-
import com.fasterxml.jackson.databind.JsonNode;
22-
import com.fasterxml.jackson.databind.node.JsonNodeType;
23-
24-
public class AtrributeDeserializer extends JsonDeserializer<AttributeImpl> {
25-
26-
private static Pattern p = Pattern.compile("^[0-9]");
27-
private static Pattern dateTime = Pattern
28-
.compile("^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}([.][0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})");
29-
private static Pattern date = Pattern.compile("^[0-9]{4}-[0-9]{2}-[0-9]{2}");
30-
private static Pattern time = Pattern.compile("^[0-9]{2}:[0-9]{2}:[0-9]{2}([.][0-9]{1,6})?");
31-
32-
private final boolean deserializeAsDate;
33-
34-
private final boolean deserializeNumberAsDouble;
35-
4+
/**
5+
* @deprecated typo in the class name, use AttributeDeserializer instead
6+
*/
7+
@Deprecated
8+
public class AtrributeDeserializer extends AttributeDeserializer {
369
public AtrributeDeserializer(boolean deserializeAsDateString) {
37-
this.deserializeAsDate = !deserializeAsDateString;
38-
this.deserializeNumberAsDouble = false;
10+
super(deserializeAsDateString);
3911
}
4012

4113
public AtrributeDeserializer(boolean deserializeAsDateString, boolean deserializeNumberAsDouble) {
42-
this.deserializeAsDate = !deserializeAsDateString;
43-
this.deserializeNumberAsDouble = deserializeNumberAsDouble;
14+
super(deserializeAsDateString, deserializeNumberAsDouble);
4415
}
4516

4617
public AtrributeDeserializer() {
47-
this.deserializeAsDate = true;
48-
this.deserializeNumberAsDouble = false;
49-
}
50-
51-
@Override
52-
public AttributeImpl deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
53-
54-
JsonNode node = p.readValueAsTree();
55-
JsonNode valueNode = node.get("value");
56-
57-
AttributeBuilder builder = Attribute.builder();
58-
builder.name(node.get("name").asText());
59-
60-
return (AttributeImpl) builder.value(p.getCodec().treeAsTokens(valueNode).readValueAs(typeRef(valueNode)))
61-
.build();
62-
}
63-
64-
private TypeReference<?> typeRef(JsonNode valueNode) {
65-
JsonNodeType valueNodeType = valueNode.getNodeType();
66-
switch (valueNodeType) {
67-
case BOOLEAN:
68-
return new TypeReference<Boolean>() {
69-
};
70-
case NUMBER:
71-
if (!deserializeNumberAsDouble && (valueNode.isInt() || valueNode.isLong())) {
72-
return new TypeReference<Long>() {
73-
};
74-
}
75-
return new TypeReference<Double>() {
76-
};
77-
case STRING:
78-
if (deserializeAsDate) {
79-
String val = valueNode.asText();
80-
if (p.matcher(val).find()) {
81-
if (dateTime.matcher(val).find()) {
82-
return new TypeReference<ZonedDateTime>() {
83-
};
84-
}
85-
if (date.matcher(val).matches()) {
86-
return new TypeReference<LocalDate>() {
87-
};
88-
}
89-
if (time.matcher(val).matches()) {
90-
return new TypeReference<LocalTime>() {
91-
};
92-
}
93-
}
94-
}
95-
return new TypeReference<String>() {
96-
};
97-
case OBJECT:
98-
if (valueNode.has("key") && valueNode.has("label")) {
99-
JsonNode label = valueNode.get("label");
100-
if (label.getNodeType() == JsonNodeType.OBJECT) {
101-
return new TypeReference<AttributeLocalizedEnumValue>() {
102-
};
103-
}
104-
return new TypeReference<AttributePlainEnumValue>() {
105-
};
106-
}
107-
if (valueNode.has("currencyCode")) {
108-
return new TypeReference<TypedMoney>() {
109-
};
110-
}
111-
if (valueNode.has("typeId")) {
112-
return new TypeReference<Reference>() {
113-
};
114-
}
115-
if (valueNode.has("value")) {
116-
return new TypeReference<Attribute>() {
117-
};
118-
}
119-
return new TypeReference<LocalizedString>() {
120-
};
121-
case ARRAY:
122-
JsonNode first = valueNode.get(0);
123-
switch (elemType(first)) {
124-
case STRING:
125-
return new TypeReference<List<String>>() {
126-
};
127-
case DATE:
128-
return new TypeReference<List<LocalDate>>() {
129-
};
130-
case DATETIME:
131-
return new TypeReference<List<ZonedDateTime>>() {
132-
};
133-
case TIME:
134-
return new TypeReference<List<LocalTime>>() {
135-
};
136-
case NUMBER:
137-
return new TypeReference<List<Double>>() {
138-
};
139-
case LONG:
140-
return new TypeReference<List<Long>>() {
141-
};
142-
case BOOLEAN:
143-
return new TypeReference<List<Boolean>>() {
144-
};
145-
case ENUM:
146-
return new TypeReference<List<AttributePlainEnumValue>>() {
147-
};
148-
case LOCALIZED_ENUM:
149-
return new TypeReference<List<AttributeLocalizedEnumValue>>() {
150-
};
151-
case LOCALIZED_STRING:
152-
return new TypeReference<List<LocalizedString>>() {
153-
};
154-
case MONEY:
155-
return new TypeReference<List<TypedMoney>>() {
156-
};
157-
case REFERENCE:
158-
return new TypeReference<List<Reference>>() {
159-
};
160-
case NESTED:
161-
return new TypeReference<List<Attribute>>() {
162-
};
163-
case SET_NESTED:
164-
return new TypeReference<List<List<Attribute>>>() {
165-
};
166-
default:
167-
return new TypeReference<List<JsonNode>>() {
168-
};
169-
}
170-
default:
171-
return new TypeReference<JsonNode>() {
172-
};
173-
}
174-
}
175-
176-
private ElemType elemType(JsonNode valueNode) {
177-
if (valueNode == null) {
178-
return ElemType.JSON_NODE;
179-
}
180-
JsonNodeType valueNodeType = valueNode.getNodeType();
181-
switch (valueNodeType) {
182-
case OBJECT:
183-
if (valueNode.has("key") && valueNode.has("label")) {
184-
JsonNode label = valueNode.get("label");
185-
if (label.getNodeType() == JsonNodeType.OBJECT) {
186-
return ElemType.LOCALIZED_ENUM;
187-
}
188-
return ElemType.ENUM;
189-
}
190-
if (valueNode.has("currencyCode")) {
191-
return ElemType.MONEY;
192-
}
193-
if (valueNode.has("typeId")) {
194-
return ElemType.REFERENCE;
195-
}
196-
if (valueNode.has("value")) {
197-
return ElemType.NESTED;
198-
}
199-
return ElemType.LOCALIZED_STRING;
200-
case NUMBER:
201-
if (!deserializeNumberAsDouble && (valueNode.isInt() || valueNode.isLong())) {
202-
return ElemType.LONG;
203-
}
204-
return ElemType.NUMBER;
205-
case STRING:
206-
if (deserializeAsDate) {
207-
String val = valueNode.asText();
208-
if (p.matcher(val).find()) {
209-
if (dateTime.matcher(val).find()) {
210-
return ElemType.DATETIME;
211-
}
212-
if (date.matcher(val).matches()) {
213-
return ElemType.DATE;
214-
}
215-
if (time.matcher(val).matches()) {
216-
return ElemType.TIME;
217-
}
218-
}
219-
}
220-
return ElemType.STRING;
221-
case ARRAY:
222-
return ElemType.SET_NESTED;
223-
case BOOLEAN:
224-
return ElemType.BOOLEAN;
225-
default:
226-
return ElemType.JSON_NODE;
227-
}
228-
}
229-
230-
private enum ElemType {
231-
STRING,
232-
DATE,
233-
DATETIME,
234-
TIME,
235-
NUMBER,
236-
LONG,
237-
BOOLEAN,
238-
ENUM,
239-
LOCALIZED_ENUM,
240-
LOCALIZED_STRING,
241-
REFERENCE,
242-
MONEY,
243-
JSON_NODE,
244-
NESTED,
245-
SET_NESTED
18+
super();
24619
}
24720
}

0 commit comments

Comments
 (0)