From ab26fa9da19c53f09a67e6e45167724d6ffffada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Kr=C3=A1l?= Date: Wed, 26 May 2021 09:45:31 +0200 Subject: [PATCH] Transient and property annotation merging (#493) Signed-off-by: David Kral --- .../eclipse/yasson/internal/ClassParser.java | 20 +++-- .../basic/PropertyMismatchTest.java | 75 +++++++++++++++++-- 2 files changed, 82 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/ClassParser.java b/src/main/java/org/eclipse/yasson/internal/ClassParser.java index 0c377206f..63ee6e7a4 100644 --- a/src/main/java/org/eclipse/yasson/internal/ClassParser.java +++ b/src/main/java/org/eclipse/yasson/internal/ClassParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -100,14 +100,22 @@ void parseProperties(ClassModel classModel, JsonbAnnotatedElement> clas } private static void mergePropertyModels(List unsortedMerged) { - PropertyModel[] clone = unsortedMerged.toArray(new PropertyModel[unsortedMerged.size()]); + PropertyModel[] clone = unsortedMerged.toArray(new PropertyModel[0]); for (int i = 0; i < clone.length; i++) { for (int j = i + 1; j < clone.length; j++) { - if (clone[i].equals(clone[j])) { + PropertyModel firstPropertyModel = clone[i]; + PropertyModel secondPropertyModel = clone[j]; + if (firstPropertyModel.equals(secondPropertyModel)) { // Need to merge two properties - unsortedMerged.remove(clone[i]); - unsortedMerged.remove(clone[j]); - unsortedMerged.add(new PropertyModel(clone[i], clone[j])); + unsortedMerged.remove(firstPropertyModel); + unsortedMerged.remove(secondPropertyModel); + if (!firstPropertyModel.isReadable() && !firstPropertyModel.isWritable()) { + unsortedMerged.add(secondPropertyModel); + } else if (!secondPropertyModel.isReadable() && !secondPropertyModel.isWritable()) { + unsortedMerged.add(firstPropertyModel); + } else { + unsortedMerged.add(new PropertyModel(firstPropertyModel, secondPropertyModel)); + } } } } diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/basic/PropertyMismatchTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/basic/PropertyMismatchTest.java index 8d0e81103..505e9627a 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/basic/PropertyMismatchTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/basic/PropertyMismatchTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -12,17 +12,20 @@ package org.eclipse.yasson.defaultmapping.basic; -import org.junit.jupiter.api.*; -import static org.junit.jupiter.api.Assertions.*; -import static org.eclipse.yasson.Jsonbs.*; - +import java.net.URI; import java.time.Instant; import java.util.HashMap; import java.util.HashSet; +import java.util.Objects; +import jakarta.json.bind.annotation.JsonbProperty; import jakarta.json.bind.annotation.JsonbTransient; - import org.jboss.weld.exceptions.IllegalStateException; +import org.junit.jupiter.api.Test; + +import static org.eclipse.yasson.Jsonbs.defaultJsonb; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; /** * Tests to verify that read-only properties (properties with no field or setter) @@ -128,7 +131,65 @@ public void setFoo(Instant instant) { this.internalInstantProperty = instant; } } - + + @Test + public void testTransientAndPropertyAnnotationMerge() { + TransientAndPropertyAnnotationMerge object = new TransientAndPropertyAnnotationMerge(); + String expected = "{\"number\":\"http://localhost/\"}"; + String json = defaultJsonb.toJson(object); + assertEquals(expected, json); + TransientAndPropertyAnnotationMerge deserialized = defaultJsonb.fromJson(expected, + TransientAndPropertyAnnotationMerge.class); + assertEquals(object, deserialized); + } + + public static class TransientAndPropertyAnnotationMerge { + + @JsonbTransient + private Integer number; + + @JsonbProperty("number") + private URI someLink; + + public TransientAndPropertyAnnotationMerge() { + number = -1; + someLink = URI.create("http://localhost/"); + } + + public Integer getNumber() { + return number; + } + + public void setNumber(Integer number) { + this.number = number; + } + + public URI getSomeLink() { + return someLink; + } + + public void setSomeLink(URI someLink) { + this.someLink = someLink; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TransientAndPropertyAnnotationMerge that = (TransientAndPropertyAnnotationMerge) o; + return Objects.equals(number, that.number) && Objects.equals(someLink, that.someLink); + } + + @Override + public int hashCode() { + return Objects.hash(number, someLink); + } + } + /** * Test that properties of the same name with different * field/getter/setter types behave properly and that we don't