Skip to content

Commit

Permalink
Merge branch '2.11' into 2.12
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Aug 12, 2020
2 parents 6d7226c + f07bda2 commit 0e1cd09
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 47 deletions.
1 change: 1 addition & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ Project: jackson-databind
(reported by isaki@github)
#2796: `TypeFactory.constructType()` does not take `TypeBindings` correctly
(reported by Daniel H)
#2815: Add `JsonFormat.Shape` awareness for UUID serialization (`UUIDSerializer`)

2.11.1 (25-Jun-2020)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,24 @@ public class UUIDSerializer
{
final static char[] HEX_CHARS = "0123456789abcdef".toCharArray();

public UUIDSerializer() { super(UUID.class); }
/**
* Configuration setting that indicates if serialization as binary
* (native or Base64-encoded) has been forced; {@code null} means
* "use default heuristic"
*
* @since 2.11.3
*/
protected final Boolean _asBinary;

public UUIDSerializer() { this(null); }

/**
* @since 2.11.3
*/
protected UUIDSerializer(Boolean asBinary) {
super(UUID.class);
_asBinary = asBinary;
}

@Override
public boolean isEmpty(SerializerProvider prov, UUID value)
Expand All @@ -45,6 +62,7 @@ public JsonSerializer<?> createContextual(SerializerProvider serializers,
JsonFormat.Value format = findFormatOverrides(serializers,
property, handledType());
Boolean asBinary = null;

if (format != null) {
JsonFormat.Shape shape = format.getShape();
if (shape == JsonFormat.Shape.BINARY) {
Expand All @@ -54,7 +72,9 @@ public JsonSerializer<?> createContextual(SerializerProvider serializers,
}
// otherwise leave as `null` meaning about same as NATURAL
}
// !!! TODO:
if (asBinary != _asBinary) {
return new UUIDSerializer(asBinary);
}
return this;
}

Expand All @@ -63,15 +83,9 @@ public void serialize(UUID value, JsonGenerator gen, SerializerProvider provider
throws IOException
{
// First: perhaps we could serialize it as raw binary data?
if (gen.canWriteBinaryNatively()) {
// 07-Dec-2013, tatu: One nasty case; that of TokenBuffer. While it can
// technically retain binary data, we do not want to do use binary
// with it, as that results in UUIDs getting converted to Base64 for
// most conversions.
if (!(gen instanceof TokenBuffer)) {
gen.writeBinary(_asBytes(value));
return;
}
if (_writeAsBinary(gen)) {
gen.writeBinary(_asBytes(value));
return;
}

// UUID.toString() works ok functionally, but we can make it go much faster
Expand All @@ -96,6 +110,20 @@ public void serialize(UUID value, JsonGenerator gen, SerializerProvider provider
gen.writeString(ch, 0, 36);
}

// @since 2.11.3
protected boolean _writeAsBinary(JsonGenerator g)
{
if (_asBinary != null) {
return _asBinary;
}
// 07-Dec-2013, tatu: One nasty case; that of TokenBuffer. While it can
// technically retain binary data, we do not want to do use binary
// with it, as that results in UUIDs getting converted to Base64 for
// most conversions.
return !(g instanceof TokenBuffer) && g.canWriteBinaryNatively();
}


// Need to add bit of extra info, format
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
* that are not Enums, Collections, Maps, or standard Date/Time types)
*/
public class JDKTypeSerializationTest
extends com.fasterxml.jackson.databind.BaseMapTest
extends BaseMapTest
{
private final ObjectMapper MAPPER = objectMapper();
private final ObjectMapper MAPPER = sharedMapper();

static class InetAddressBean {
public InetAddress value;
Expand Down Expand Up @@ -182,40 +182,6 @@ public void testDuplicatedByteBufferWithCustomPosition() throws IOException
assertEquals(exp, MAPPER.writeValueAsString(bbuf.duplicate()));
}

// Verify that efficient UUID codec won't mess things up:
public void testUUIDs() throws IOException
{
// first, couple of generated UUIDs:
for (String value : new String[] {
"76e6d183-5f68-4afa-b94a-922c1fdb83f8",
"540a88d1-e2d8-4fb1-9396-9212280d0a7f",
"2c9e441d-1cd0-472d-9bab-69838f877574",
"591b2869-146e-41d7-8048-e8131f1fdec5",
"82994ac2-7b23-49f2-8cc5-e24cf6ed77be",
"00000007-0000-0000-0000-000000000000"
}) {
UUID uuid = UUID.fromString(value);
String json = MAPPER.writeValueAsString(uuid);
assertEquals(quote(uuid.toString()), json);

// Also, wrt [#362], should convert cleanly
String str = MAPPER.convertValue(uuid, String.class);
assertEquals(value, str);
}

// then use templating; note that these are not exactly valid UUIDs
// wrt spec (type bits etc), but JDK UUID should deal ok
final String TEMPL = "00000000-0000-0000-0000-000000000000";
final String chars = "123456789abcdef";

for (int i = 0; i < chars.length(); ++i) {
String value = TEMPL.replace('0', chars.charAt(i));
UUID uuid = UUID.fromString(value);
String json = MAPPER.writeValueAsString(uuid);
assertEquals(quote(uuid.toString()), json);
}
}

// [databind#2197]
public void testVoidSerialization() throws Exception
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.fasterxml.jackson.databind.ser.jdk;

import java.io.IOException;
import java.util.UUID;

import com.fasterxml.jackson.annotation.JsonFormat;

import com.fasterxml.jackson.databind.*;

public class UUIDSerializationTest extends BaseMapTest
{
static class UUIDWrapperVanilla {
public UUID uuid;

public UUIDWrapperVanilla(UUID u) { uuid = u; }
}

static class UUIDWrapperBinary {
// default with JSON is String, for use of (base64-encoded) Binary:
@JsonFormat(shape = JsonFormat.Shape.BINARY)
public UUID uuid;

public UUIDWrapperBinary(UUID u) { uuid = u; }
}

private final ObjectMapper MAPPER = sharedMapper();

// Verify that efficient UUID codec won't mess things up:
public void testBasicUUIDs() throws IOException
{
// first, couple of generated UUIDs:
for (String value : new String[] {
"76e6d183-5f68-4afa-b94a-922c1fdb83f8",
"540a88d1-e2d8-4fb1-9396-9212280d0a7f",
"2c9e441d-1cd0-472d-9bab-69838f877574",
"591b2869-146e-41d7-8048-e8131f1fdec5",
"82994ac2-7b23-49f2-8cc5-e24cf6ed77be",
"00000007-0000-0000-0000-000000000000"
}) {
UUID uuid = UUID.fromString(value);
String json = MAPPER.writeValueAsString(uuid);
assertEquals(quote(uuid.toString()), json);

// Also, wrt [#362], should convert cleanly
String str = MAPPER.convertValue(uuid, String.class);
assertEquals(value, str);
}

// then use templating; note that these are not exactly valid UUIDs
// wrt spec (type bits etc), but JDK UUID should deal ok
final String TEMPL = "00000000-0000-0000-0000-000000000000";
final String chars = "123456789abcdef";

for (int i = 0; i < chars.length(); ++i) {
String value = TEMPL.replace('0', chars.charAt(i));
UUID uuid = UUID.fromString(value);
String json = MAPPER.writeValueAsString(uuid);
assertEquals(quote(uuid.toString()), json);
}
}

public void testShapeOverrides() throws Exception
{
final String nullUUIDStr = "00000000-0000-0000-0000-000000000000";
final UUID nullUUID = UUID.fromString(nullUUIDStr);

// First, see that Binary per-property override works:
assertEquals("{\"uuid\":\"AAAAAAAAAAAAAAAAAAAAAA==\"}",
MAPPER.writeValueAsString(new UUIDWrapperBinary(nullUUID)));

// but that without one we'd get String
assertEquals("{\"uuid\":\""+nullUUIDStr+"\"}",
MAPPER.writeValueAsString(new UUIDWrapperVanilla(nullUUID)));

// but can also override by type
ObjectMapper m = newJsonMapper();
m.configOverride(UUID.class)
.setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.BINARY));
assertEquals("{\"uuid\":\"AAAAAAAAAAAAAAAAAAAAAA==\"}",
m.writeValueAsString(new UUIDWrapperVanilla(nullUUID)));
}
}

0 comments on commit 0e1cd09

Please sign in to comment.