1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.linecorp.centraldogma.common;
17
18 import java.io.IOException;
19
20 import javax.annotation.Nullable;
21
22 import com.fasterxml.jackson.core.JsonParser;
23 import com.fasterxml.jackson.databind.DeserializationContext;
24 import com.fasterxml.jackson.databind.JsonMappingException;
25 import com.fasterxml.jackson.databind.JsonNode;
26 import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
27
28
29
30
31
32
33 public class RevisionJsonDeserializer extends StdDeserializer<Revision> {
34
35 private static final long serialVersionUID = -2337105643062794190L;
36
37
38
39
40 public RevisionJsonDeserializer() {
41 super(Revision.class);
42 }
43
44 @Override
45 public Revision deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
46 final JsonNode node = p.readValueAsTree();
47 if (node.isNumber()) {
48 validateRevisionNumber(ctx, node, "major", false);
49 return new Revision(node.intValue());
50 }
51
52 if (node.isTextual()) {
53 try {
54 return new Revision(node.textValue());
55 } catch (IllegalArgumentException e) {
56 ctx.reportInputMismatch(Revision.class, e.getMessage());
57
58 throw new Error();
59 }
60 }
61
62 if (!node.isObject()) {
63 ctx.reportInputMismatch(Revision.class,
64 "A revision must be a non-zero integer or " +
65 "an object that contains \"major\" and \"minor\" properties.");
66
67 throw new Error();
68 }
69
70 final JsonNode majorNode = node.get("major");
71 final JsonNode minorNode = node.get("minor");
72 final int major;
73
74 validateRevisionNumber(ctx, majorNode, "major", false);
75 major = majorNode.intValue();
76 if (minorNode != null) {
77 validateRevisionNumber(ctx, minorNode, "minor", true);
78 if (minorNode.intValue() != 0) {
79 ctx.reportInputMismatch(Revision.class,
80 "A revision must not have a non-zero \"minor\" property.");
81 }
82 }
83
84 return new Revision(major);
85 }
86
87 private static void validateRevisionNumber(DeserializationContext ctx, @Nullable JsonNode node,
88 String type, boolean zeroAllowed) throws JsonMappingException {
89 if (node == null) {
90 ctx.reportInputMismatch(Revision.class, "missing %s revision number", type);
91
92 throw new Error();
93 }
94
95 if (!node.canConvertToInt() || !zeroAllowed && node.intValue() == 0) {
96 ctx.reportInputMismatch(Revision.class,
97 "A %s revision number must be %s integer.",
98 type, zeroAllowed ? "an" : "a non-zero");
99
100 throw new Error();
101 }
102 }
103 }