From ca183933acb4d34f7c05872bc73e2160a97ffd6b Mon Sep 17 00:00:00 2001 From: Evan Galpin Date: Thu, 16 Jun 2022 11:20:28 -0400 Subject: [PATCH] Make JsonPointer java.io.Serializable (#762) --- .../fasterxml/jackson/core/JsonPointer.java | 45 +++++++++++++++++-- .../jackson/core/TestJsonPointer.java | 35 +++++++++++++++ 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/core/JsonPointer.java b/src/main/java/com/fasterxml/jackson/core/JsonPointer.java index 4b892981b7..f3cf93d954 100644 --- a/src/main/java/com/fasterxml/jackson/core/JsonPointer.java +++ b/src/main/java/com/fasterxml/jackson/core/JsonPointer.java @@ -1,6 +1,12 @@ package com.fasterxml.jackson.core; import com.fasterxml.jackson.core.io.NumberInput; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.io.ObjectStreamException; +import java.io.Serializable; /** * Implementation of @@ -17,8 +23,9 @@ * * @since 2.3 */ -public class JsonPointer +public class JsonPointer implements Serializable { + private static final long serialVersionUID = 1L; /** * Character used to separate segments. * @@ -59,7 +66,7 @@ public class JsonPointer * so that {@link #toString} should be as efficient as possible. */ protected final String _asString; - + protected final String _matchingPropertyName; protected final int _matchingElementIndex; @@ -69,7 +76,7 @@ public class JsonPointer /* Construction /********************************************************** */ - + /** * Constructor used for creating "empty" instance, used to represent * state that matches current node. @@ -643,4 +650,36 @@ private static void _appendEscape(StringBuilder sb, char c) { } sb.append(c); } + + private Object writeReplace() { + return new SerializableJsonPointer(_asString); + } + + /** + * This must only exist to allow both final properties and implementation of + * Externalizable/Serializable for JsonPointer + */ + private static class SerializableJsonPointer implements Externalizable { + private String _asString; + + public SerializableJsonPointer() { + } + + public SerializableJsonPointer(String asString) { + _asString = asString; + } + + @Override + public void writeExternal(ObjectOutput out) throws IOException { + out.writeUTF(_asString); + } + + @Override + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + _asString = in.readUTF(); + } + private Object readResolve() throws ObjectStreamException { + return compile(_asString); + } + } } diff --git a/src/test/java/com/fasterxml/jackson/core/TestJsonPointer.java b/src/test/java/com/fasterxml/jackson/core/TestJsonPointer.java index af8bafeee1..5b6bd0cf42 100644 --- a/src/test/java/com/fasterxml/jackson/core/TestJsonPointer.java +++ b/src/test/java/com/fasterxml/jackson/core/TestJsonPointer.java @@ -1,5 +1,12 @@ package com.fasterxml.jackson.core; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + public class TestJsonPointer extends BaseTest { public void testSimplePath() throws Exception @@ -228,4 +235,32 @@ public void testLongNumbers() throws Exception assertTrue(ptr.matches()); assertNull(ptr.tail()); } + + private static byte[] pickle(T obj) + throws IOException + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(obj); + oos.close(); + return baos.toByteArray(); + } + + private static T unpickle(byte[] b, Class cl) + throws IOException, ClassNotFoundException + { + ByteArrayInputStream bais = new ByteArrayInputStream(b); + ObjectInputStream ois = new ObjectInputStream(bais); + Object o = ois.readObject(); + return cl.cast(o); + } + public void testPointerSerialization() throws Exception { + + final String INPUT = "/Image/15/name"; + JsonPointer original = JsonPointer.compile(INPUT); + JsonPointer copy = unpickle(pickle(original), JsonPointer.class); + assertNotSame(copy, original); + assertEquals(original, copy); + + } }