Skip to content

Commit c2dd463

Browse files
committed
Fix UnlModify serialization
1 parent b7bb749 commit c2dd463

File tree

6 files changed

+152
-60
lines changed

6 files changed

+152
-60
lines changed

xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/TransactionDeserializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public Transaction deserialize(JsonParser jsonParser, DeserializationContext ctx
7171
if (UnlModify.class.isAssignableFrom(transactionTypeClass)) {
7272
// if (objectNode.get("Account").isEmpty()) {
7373
if (objectNode.has("Account")) {
74-
objectNode.remove("Account");
74+
//objectNode.remove("Account");
7575
}
7676
}
7777

xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/TransactionSerializer.java

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -40,38 +40,38 @@
4040
* Custom deserializer for {@link Transaction}s, which deserializes to a specific {@link Transaction} type based on the
4141
* TransactionType JSON field.
4242
*/
43-
public class TransactionSerializer { //} extends StdSerializer<Transaction> {
44-
//
45-
// /**
46-
// * No-args constructor.
47-
// */
48-
// protected TransactionSerializer() {
49-
// super(Transaction.class);
50-
// }
51-
//
52-
// @Override
53-
// public void serialize(Transaction value, JsonGenerator gen, SerializerProvider provider) throws IOException {
54-
//
55-
// if (UnlModify.class.isAssignableFrom(value.getClass())) {
56-
// gen.writeStartObject();
57-
//
58-
// // 1. Delegate to Jackson for the existing fields:
59-
// provider.defaultSerializeValue(value, gen); // Delegate to Jackson
60-
//
61-
//// ObjectMapperFactory.create().writeValue(gen, value);
62-
//
63-
// // Serialize the existing fields (delegate to Jackson's default if possible)
64-
//// gen.writeObject((UnlModify) value); // This will handle the standard Transaction fields
65-
//
66-
// // Add the extra "Account" field here because by marking it @Derived in the Immutable, this field does not show
67-
// // up during serialization.
68-
// gen.writeFieldName("Account");
69-
// gen.writeString(value.account().value());
70-
//
71-
// gen.writeEndObject();
72-
// } else {
73-
// // Rely on Jackson's automatic serialization
74-
// gen.writeObject(value);
75-
// }
76-
// }
43+
public class TransactionSerializer extends StdSerializer<Transaction> {
44+
45+
/**
46+
* No-args constructor.
47+
*/
48+
protected TransactionSerializer() {
49+
super(Transaction.class);
50+
}
51+
52+
@Override
53+
public void serialize(Transaction value, JsonGenerator gen, SerializerProvider provider) throws IOException {
54+
55+
if (UnlModify.class.isAssignableFrom(value.getClass())) {
56+
gen.writeStartObject();
57+
58+
// 1. Delegate to Jackson for the existing fields:
59+
provider.defaultSerializeValue(value, gen); // Delegate to Jackson
60+
61+
// ObjectMapperFactory.create().writeValue(gen, value);
62+
63+
// Serialize the existing fields (delegate to Jackson's default if possible)
64+
// gen.writeObject((UnlModify) value); // This will handle the standard Transaction fields
65+
66+
// Add the extra "Account" field here because by marking it @Derived in the Immutable, this field does not show
67+
// up during serialization.
68+
gen.writeFieldName("Account");
69+
gen.writeString(value.account().value());
70+
71+
gen.writeEndObject();
72+
} else {
73+
// Rely on Jackson's automatic serialization
74+
gen.writeObject(value);
75+
}
76+
}
7777
}

xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/UnlModifyTransactionSerializer.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,16 @@
2121
*/
2222

2323
import com.fasterxml.jackson.core.JsonGenerator;
24+
import com.fasterxml.jackson.databind.JsonNode;
25+
import com.fasterxml.jackson.databind.ObjectMapper;
2426
import com.fasterxml.jackson.databind.SerializerProvider;
2527
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
2628
import org.xrpl.xrpl4j.model.transactions.Transaction;
2729
import org.xrpl.xrpl4j.model.transactions.UnlModify;
30+
import org.xrpl.xrpl4j.model.transactions.metadata.CreatedNode;
2831

2932
import java.io.IOException;
33+
import java.util.Map;
3034

3135
/**
3236
* Custom deserializer for {@link Transaction}s, which deserializes to a specific {@link Transaction} type based on the
@@ -44,14 +48,28 @@ protected UnlModifyTransactionSerializer() {
4448
@Override
4549
public void serialize(UnlModify value, JsonGenerator gen, SerializerProvider provider) throws IOException {
4650

51+
// ObjectMapper codec = (ObjectMapper) jsonParser.getCodec();
52+
// JsonNode jsonNode = jsonParser.readValueAsTree();
53+
// Map.Entry<String, JsonNode> nodeFieldAndValue = jsonNode.fields().next();
54+
// String affectedNodeType = nodeFieldAndValue.getKey();
55+
56+
// codec.getTypeFactory().constructParametricType(CreatedNode.class, ledgerObjectClass)
57+
58+
59+
// ObjectMapper objectMapper = (ObjectMapper) gen.getCodec();
60+
// String json = objectMapper.writeValueAsString(value);
61+
62+
// provider.defaultSerializeValue()
63+
64+
4765
// if (UnlModify.class.isAssignableFrom(value.getClass())) {
4866
// gen.writeStartObject();
4967

5068
// if (gen.getCurrentValue() == null
5169
// gen.getCurrentValue().toString().length() == 1
5270
// ) {
5371
// 1. Delegate to Jackson for the existing fields:
54-
provider.defaultSerializeValue(value, gen); // Delegate to Jackson
72+
// provider.defaultSerializeValue(value, gen); // Delegate to Jackson
5573
// }
5674

5775
// ObjectMapperFactory.create().writeValue(gen, value);

xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/Xrpl4jModule.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public Xrpl4jModule() {
6161
addSerializer(LedgerIndex.class, new LedgerIndexSerializer());
6262
addDeserializer(LedgerIndex.class, new LedgerIndexDeserializer());
6363

64-
addSerializer(UnlModify.class, new UnlModifyTransactionSerializer());
64+
// addSerializer(UnlModify.class, new UnlModifyTransactionSerializer());
6565
addDeserializer(Transaction.class, new TransactionDeserializer());
6666

6767
addDeserializer(ServerInfo.class, new ServerInfoDeserializer());

xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/UnlModify.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
2929
import com.google.common.primitives.UnsignedInteger;
3030
import org.immutables.value.Value;
31+
import org.xrpl.xrpl4j.crypto.keys.ImmutablePublicKey;
3132
import org.xrpl.xrpl4j.crypto.keys.PublicKey;
3233
import org.xrpl.xrpl4j.model.client.common.LedgerIndex;
3334

@@ -92,9 +93,11 @@ default TransactionType transactionType() {
9293
* @return Always returns ACCOUNT_ZERO, which is the base58 encoding of the number zero.
9394
*/
9495
@Override
95-
@JsonProperty(value = "Account", access = Access.WRITE_ONLY)
96+
@JsonProperty(value = "Account"
97+
, access = Access.READ_WRITE
98+
)
9699
@Value.Derived
97-
@JsonIgnore(false)
100+
@JsonSerialize
98101
default Address account() {
99102
return ACCOUNT_ZERO;
100103
}

xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/json/UnlModifyJsonTests.java

Lines changed: 92 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@
2020
* =========================LICENSE_END==================================
2121
*/
2222

23-
import static org.assertj.core.api.FactoryBasedNavigableListAssert.assertThat;
23+
import static org.assertj.core.api.Assertions.assertThat;
24+
import static org.xrpl.xrpl4j.model.AddressConstants.ACCOUNT_ZERO;
2425

2526
import com.fasterxml.jackson.core.JsonProcessingException;
2627
import com.google.common.primitives.UnsignedInteger;
28+
import com.google.common.primitives.UnsignedLong;
2729
import org.assertj.core.api.Assertions;
2830
import org.json.JSONException;
2931
import org.junit.jupiter.api.Test;
@@ -36,6 +38,9 @@
3638
import org.xrpl.xrpl4j.model.transactions.UnlModify;
3739
import org.xrpl.xrpl4j.model.transactions.XrpCurrencyAmount;
3840

41+
import java.util.Collections;
42+
import java.util.Map;
43+
3944
public class UnlModifyJsonTests extends AbstractJsonTest {
4045

4146
@Test
@@ -64,12 +69,12 @@ public void testJsonWithAccountZero() throws JsonProcessingException, JSONExcept
6469
@Test
6570
public void testJsonWithAccountZeroAndUnknownFields() throws JsonProcessingException, JSONException {
6671
UnlModify unlModify = UnlModify.builder()
72+
.putUnknownFields("Foo", "Bar")
6773
.fee(XrpCurrencyAmount.ofDrops(12))
6874
.sequence(UnsignedInteger.valueOf(2470665))
6975
.ledgerSequence(LedgerIndex.of(UnsignedInteger.valueOf(67850752)))
7076
.unlModifyValidator("EDB6FC8E803EE8EDC2793F1EC917B2EE41D35255618DEB91D3F9B1FC89B75D4539")
7177
.unlModifyDisabling(UnsignedInteger.valueOf(1))
72-
.putUnknownFields("Foo", "Bar")
7378
.build();
7479

7580
String json = "{" +
@@ -96,42 +101,79 @@ public void testJsonWithEmptyAccount() throws JsonProcessingException, JSONExcep
96101
.unlModifyDisabling(UnsignedInteger.valueOf(1))
97102
.build();
98103

99-
String json = "{" +
100-
"\"Account\":\"\"," +
104+
// What we expect the ObjectMapper to Serialize (given the above object)
105+
String expectedSerializedJson = "{" +
106+
"\"Account\":\"" + ACCOUNT_ZERO + "\"," +
101107
"\"Fee\":\"12\"," +
102108
"\"LedgerSequence\":67850752," +
103109
"\"Sequence\":2470665," +
104110
"\"SigningPubKey\":\"\"," +
105111
"\"TransactionType\":\"UNLModify\"," +
106112
"\"UNLModifyDisabling\":1," +
107-
"\"UNLModifyValidator\":\"EDB6FC8E803EE8EDC2793F1EC917B2EE41D35255618DEB91D3F9B1FC89B75D4539\"}";
113+
"\"UNLModifyValidator\":\"EDB6FC8E803EE8EDC2793F1EC917B2EE41D35255618DEB91D3F9B1FC89B75D4539\"" +
114+
"}";
108115

109-
assertCanSerializeAndDeserialize(unlModify, json);
116+
String serialized = objectMapper.writeValueAsString(unlModify);
117+
JSONAssert.assertEquals(expectedSerializedJson, serialized, JSONCompareMode.STRICT);
118+
119+
// What we provide the ObjectMapper to Deserialize
120+
String expectedDeserializedJson = "{" +
121+
"\"Account\":\"\"," + // <-- The crux of the test!
122+
"\"Fee\":\"12\"," +
123+
"\"LedgerSequence\":67850752," +
124+
"\"Sequence\":2470665," +
125+
"\"SigningPubKey\":\"\"," +
126+
"\"TransactionType\":\"UNLModify\"," +
127+
"\"UNLModifyDisabling\":1," +
128+
"\"UNLModifyValidator\":\"EDB6FC8E803EE8EDC2793F1EC917B2EE41D35255618DEB91D3F9B1FC89B75D4539\"" +
129+
"}";
130+
131+
Transaction deserialized = objectMapper.readValue(expectedDeserializedJson, Transaction.class);
132+
assertThat(deserialized).isEqualTo(unlModify);
110133
}
111134

112135
@Test
113136
public void testJsonWithEmptyAccountAndUnknownFields() throws JsonProcessingException, JSONException {
114137
UnlModify unlModify = UnlModify.builder()
138+
.putUnknownFields("Foo", "Bar")
115139
.fee(XrpCurrencyAmount.ofDrops(12))
116140
.sequence(UnsignedInteger.valueOf(2470665))
117141
.ledgerSequence(LedgerIndex.of(UnsignedInteger.valueOf(67850752)))
118142
.unlModifyValidator("EDB6FC8E803EE8EDC2793F1EC917B2EE41D35255618DEB91D3F9B1FC89B75D4539")
119143
.unlModifyDisabling(UnsignedInteger.valueOf(1))
120-
.putUnknownFields("Foo", "Bar")
121144
.build();
122145

123-
String json = "{" +
124-
"\"Foo\" : \"Bar\",\n" +
125-
"\"Account\":\"\"," +
146+
// What we expect the ObjectMapper to Serialize (given the above object)
147+
String expectedSerializedJson = "{" +
148+
"\"Account\":\"" + ACCOUNT_ZERO + "\"," +
149+
"\"Foo\" : \"Bar\",\n" + // <-- The crux of the test!
126150
"\"Fee\":\"12\"," +
127151
"\"LedgerSequence\":67850752," +
128152
"\"Sequence\":2470665," +
129153
"\"SigningPubKey\":\"\"," +
130154
"\"TransactionType\":\"UNLModify\"," +
131155
"\"UNLModifyDisabling\":1," +
132-
"\"UNLModifyValidator\":\"EDB6FC8E803EE8EDC2793F1EC917B2EE41D35255618DEB91D3F9B1FC89B75D4539\"}";
156+
"\"UNLModifyValidator\":\"EDB6FC8E803EE8EDC2793F1EC917B2EE41D35255618DEB91D3F9B1FC89B75D4539\"" +
157+
"}";
133158

134-
assertCanSerializeAndDeserialize(unlModify, json);
159+
String serialized = objectMapper.writeValueAsString(unlModify);
160+
JSONAssert.assertEquals(expectedSerializedJson, serialized, JSONCompareMode.STRICT);
161+
162+
// What we provide the ObjectMapper to Deserialize
163+
String expectedDeserializedJson = "{" +
164+
"\"Foo\" : \"Bar\",\n" + // <-- The crux of the test!
165+
"\"Account\":\"\"," + // <-- The crux of the test!
166+
"\"Fee\":\"12\"," +
167+
"\"LedgerSequence\":67850752," +
168+
"\"Sequence\":2470665," +
169+
"\"SigningPubKey\":\"\"," +
170+
"\"TransactionType\":\"UNLModify\"," +
171+
"\"UNLModifyDisabling\":1," +
172+
"\"UNLModifyValidator\":\"EDB6FC8E803EE8EDC2793F1EC917B2EE41D35255618DEB91D3F9B1FC89B75D4539\"" +
173+
"}";
174+
175+
Transaction deserialized = objectMapper.readValue(expectedDeserializedJson, Transaction.class);
176+
assertThat(deserialized).isEqualTo(unlModify);
135177
}
136178

137179
@Test
@@ -144,7 +186,8 @@ public void testJsonWithMissingAccount() throws JsonProcessingException, JSONExc
144186
.unlModifyDisabling(UnsignedInteger.valueOf(1))
145187
.build();
146188

147-
String json = "{" +
189+
String expectedJson = "{" +
190+
"\"Account\":\"" + ACCOUNT_ZERO + "\"," +
148191
"\"Fee\":\"12\"," +
149192
"\"LedgerSequence\":67850752," +
150193
"\"Sequence\":2470665," +
@@ -153,7 +196,20 @@ public void testJsonWithMissingAccount() throws JsonProcessingException, JSONExc
153196
"\"UNLModifyDisabling\":1," +
154197
"\"UNLModifyValidator\":\"EDB6FC8E803EE8EDC2793F1EC917B2EE41D35255618DEB91D3F9B1FC89B75D4539\"}";
155198

156-
assertCanSerializeAndDeserialize(unlModify, json);
199+
String serialized = objectMapper.writeValueAsString(unlModify);
200+
JSONAssert.assertEquals(expectedJson, serialized, JSONCompareMode.STRICT);
201+
202+
String jsonForDeserialization = "{" +
203+
"\"Fee\":\"12\"," +
204+
"\"LedgerSequence\":67850752," +
205+
"\"Sequence\":2470665," +
206+
"\"SigningPubKey\":\"\"," +
207+
"\"TransactionType\":\"UNLModify\"," +
208+
"\"UNLModifyDisabling\":1," +
209+
"\"UNLModifyValidator\":\"EDB6FC8E803EE8EDC2793F1EC917B2EE41D35255618DEB91D3F9B1FC89B75D4539\"}";
210+
211+
Transaction deserialized = objectMapper.readValue(jsonForDeserialization, Transaction.class);
212+
assertThat(deserialized).isEqualTo(unlModify);
157213
}
158214

159215
@Test
@@ -164,28 +220,43 @@ public void testJsonWithMissingAccountAndUnknownFields() throws JsonProcessingEx
164220
.ledgerSequence(LedgerIndex.of(UnsignedInteger.valueOf(67850752)))
165221
.unlModifyValidator("EDB6FC8E803EE8EDC2793F1EC917B2EE41D35255618DEB91D3F9B1FC89B75D4539")
166222
.unlModifyDisabling(UnsignedInteger.valueOf(1))
167-
.putUnknownFields("Foo", "Bar")
168223
.build();
169224

170-
String json = "{" +
171-
"\"Foo\" : \"Bar\",\n" +
225+
// What we expect the ObjectMapper to Serialize (given the above object)
226+
String expectedSerializedJson = "{" +
227+
"\"Account\":\"" + ACCOUNT_ZERO + "\"," +
172228
"\"Fee\":\"12\"," +
173229
"\"LedgerSequence\":67850752," +
174230
"\"Sequence\":2470665," +
175231
"\"SigningPubKey\":\"\"," +
176232
"\"TransactionType\":\"UNLModify\"," +
177233
"\"UNLModifyDisabling\":1," +
178-
"\"UNLModifyValidator\":\"EDB6FC8E803EE8EDC2793F1EC917B2EE41D35255618DEB91D3F9B1FC89B75D4539\"}";
234+
"\"UNLModifyValidator\":\"EDB6FC8E803EE8EDC2793F1EC917B2EE41D35255618DEB91D3F9B1FC89B75D4539\"" +
235+
"}";
179236

180-
assertCanSerializeAndDeserialize(unlModify, json);
237+
String serialized = objectMapper.writeValueAsString(unlModify);
238+
JSONAssert.assertEquals(expectedSerializedJson, serialized, JSONCompareMode.STRICT);
239+
240+
// What we provide the ObjectMapper to Deserialize
241+
String expectedDeserializedJson = "{" +
242+
"\"Account\":\"" + ACCOUNT_ZERO + "\"," +
243+
"\"Fee\":\"12\"," +
244+
"\"LedgerSequence\":67850752," +
245+
"\"Sequence\":2470665," +
246+
"\"SigningPubKey\":\"\"," +
247+
"\"TransactionType\":\"UNLModify\"," +
248+
"\"UNLModifyDisabling\":1," +
249+
"\"UNLModifyValidator\":\"EDB6FC8E803EE8EDC2793F1EC917B2EE41D35255618DEB91D3F9B1FC89B75D4539\"" +
250+
"}";
251+
252+
Transaction deserialized = objectMapper.readValue(expectedDeserializedJson, Transaction.class);
253+
assertThat(deserialized).isEqualTo(unlModify);
181254
}
182255

183256
// Using Transcation
184257
// Using Immutable
185258
// Using UnlModify
186259

187-
188-
189260
// @Test
190261
// public void testDeserializeJson() throws JsonProcessingException {
191262
// String json = "{" +

0 commit comments

Comments
 (0)