Skip to content

Commit

Permalink
Support for records (#499)
Browse files Browse the repository at this point in the history
Support for records added

Signed-off-by: David Kral <david.k.kral@oracle.com>
  • Loading branch information
Verdent authored Nov 4, 2021
1 parent de96336 commit 7a5b15a
Show file tree
Hide file tree
Showing 9 changed files with 252 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ jobs:
distribution: 'adopt'
java-version: ${{ matrix.java_version }}
- name: Yasson tests
run: mvn -U -C -Pstaging test
run: mvn -U -C -Pstaging verify
- name: JSONB-API TCK
run: cd yasson-tck && mvn -U -B test
71 changes: 68 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,50 @@
</plugins>
</build>
</profile>
<profile>
<id>jdk16</id>
<activation>
<jdk>[16,)</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<executions>
<execution>
<id>default-testCompile</id>
<configuration>
<release>16</release>
<compileSourceRoots>
<compileSourceRoot>${project.basedir}/src/test/java</compileSourceRoot>
<compileSourceRoot>${project.basedir}/src/test/java16</compileSourceRoot>
</compileSourceRoots>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>**/RecordTest.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>

<build>
Expand Down Expand Up @@ -271,6 +315,11 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
Expand All @@ -290,7 +339,7 @@
</configuration>
</execution>
<execution>
<id>multi-release-compile</id>
<id>multi-release-compile-9</id>
<goals>
<goal>compile</goal>
</goals>
Expand All @@ -302,6 +351,19 @@
<multiReleaseOutput>true</multiReleaseOutput>
</configuration>
</execution>
<execution>
<id>multi-release-compile-16</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<release>16</release>
<compileSourceRoots>
<compileSourceRoot>${project.basedir}/src/main/java16</compileSourceRoot>
</compileSourceRoots>
<multiReleaseOutput>true</multiReleaseOutput>
</configuration>
</execution>
<execution>
<id>base-compile</id>
<goals>
Expand Down Expand Up @@ -430,6 +492,7 @@
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<executions>
Expand All @@ -440,10 +503,12 @@
<goal>test</goal>
</goals>
<configuration>
<!-- <testFailureIgnore>true</testFailureIgnore>-->
<trimStackTrace>false</trimStackTrace>
<excludes>
<exclude>**/JavaxNamingExcludedTest.class</exclude>
<exclude>**/AnnotationIntrospectorWithoutOptionalModulesTest.class</exclude>
<exclude>**/JavaxNamingExcludedTest.java</exclude>
<exclude>**/AnnotationIntrospectorWithoutOptionalModulesTest.java</exclude>
<exclude>**/*Record*</exclude>
</excludes>
<argLine>
<!--Remove when CDI is updated to support modules
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -148,10 +148,12 @@ private String getJsonbPropertyCustomizedName(Property property, JsonbAnnotatedE
* @return JsonbCreator metadata object
*/
public JsonbCreator getCreator(Class<?> clazz) {
JsonbCreator jsonbCreator = null;
JsonbCreator jsonbCreator;
Constructor<?>[] declaredConstructors =
AccessController.doPrivileged((PrivilegedAction<Constructor<?>[]>) clazz::getDeclaredConstructors);

jsonbCreator = ClassMultiReleaseExtension.findJsonbCreator(clazz, declaredConstructors, this);

for (Constructor<?> constructor : declaredConstructors) {
final jakarta.json.bind.annotation.JsonbCreator annot = findAnnotation(constructor.getDeclaredAnnotations(),
jakarta.json.bind.annotation.JsonbCreator.class);
Expand Down Expand Up @@ -180,7 +182,7 @@ public JsonbCreator getCreator(Class<?> clazz) {
return jsonbCreator;
}

private JsonbCreator createJsonbCreator(Executable executable, JsonbCreator existing, Class<?> clazz) {
JsonbCreator createJsonbCreator(Executable executable, JsonbCreator existing, Class<?> clazz) {
if (existing != null) {
throw new JsonbException(Messages.getMessage(MessageKeys.MULTIPLE_JSONB_CREATORS, clazz));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 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
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/

package org.eclipse.yasson.internal;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import org.eclipse.yasson.internal.model.JsonbCreator;

/**
* Search for instance creator from other sources.
* Mainly intended to add extensibility for different java versions and new features.
*/
class ClassMultiReleaseExtension {

private ClassMultiReleaseExtension() {
throw new IllegalStateException("This class cannot be instantiated");
}

static boolean shouldTransformToPropertyName(Method method) {
return true;
}

static boolean isGetAccessorMethod(Method method) {
return false;
}

static JsonbCreator findJsonbCreator(Class<?> clazz, Constructor<?>[] declaredConstructors, AnnotationIntrospector introspector) {
return null;
}

}
9 changes: 7 additions & 2 deletions src/main/java/org/eclipse/yasson/internal/ClassParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,9 @@ private void parseMethods(Class<?> clazz,
if (!isPropertyMethod(method) || method.isBridge() || isSpecialCaseMethod(clazz, method)) {
continue;
}
final String propertyName = toPropertyMethod(name);
final String propertyName = ClassMultiReleaseExtension.shouldTransformToPropertyName(method)
? toPropertyMethod(name)
: name;

registerMethod(propertyName, method, classElement, classProperties);
}
Expand Down Expand Up @@ -230,6 +232,9 @@ private static boolean isSpecialCaseMethod(Class<?> clazz, Method m) {
}

private static boolean isGetter(Method m) {
if (ClassMultiReleaseExtension.isGetAccessorMethod(m)) {
return true;
}
return (m.getName().startsWith(GET_PREFIX) || m.getName().startsWith(IS_PREFIX)) && m.getParameterCount() == 0;
}

Expand All @@ -238,7 +243,7 @@ private static boolean isSetter(Method m) {
}

private static String toPropertyMethod(String name) {
return lowerFirstLetter(name.substring(name.startsWith(IS_PREFIX) ? 2 : 3, name.length()));
return lowerFirstLetter(name.substring(name.startsWith(IS_PREFIX) ? 2 : 3));
}

private static String lowerFirstLetter(String name) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (c) 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
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/

package org.eclipse.yasson.internal;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Set;

import org.eclipse.yasson.internal.model.JsonbCreator;

/**
* Search for instance creator from other sources.
* Mainly intended to add extensibility for different java versions and new features.
*/
class ClassMultiReleaseExtension {

private static final Set<String> NOT_VALID_ACCESSOR_METHODS = Set.of("equals", "hashCode", "toString");

private ClassMultiReleaseExtension() {
throw new IllegalStateException("This class cannot be instantiated");
}

static boolean shouldTransformToPropertyName(Method method) {
return !method.getDeclaringClass().isRecord();
}

static boolean isGetAccessorMethod(Method method) {
if (method.getDeclaringClass().isRecord()) {
return !NOT_VALID_ACCESSOR_METHODS.contains(method.getName());
}
return false;
}

static JsonbCreator findJsonbCreator(Class<?> clazz, Constructor<?>[] declaredConstructors, AnnotationIntrospector introspector) {
if (clazz.isRecord()) {
return introspector.createJsonbCreator(declaredConstructors[0], null, clazz);
}
return null;
}

}
18 changes: 18 additions & 0 deletions src/test/java16/org/eclipse/yasson/records/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (c) 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
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/

package org.eclipse.yasson.records;

import jakarta.json.bind.annotation.JsonbProperty;

public record Car(@JsonbProperty("typeChanged") String type, @JsonbProperty("colorChanged") String color) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (c) 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
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/

package org.eclipse.yasson.records;

public record CarWithoutAnnotations(String type, String color) {
}
44 changes: 44 additions & 0 deletions src/test/java16/org/eclipse/yasson/records/RecordTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 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
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/

package org.eclipse.yasson.records;

import org.eclipse.yasson.Jsonbs;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class RecordTest {

@Test
public void testRecordProcessing() {
Car car = new Car("skoda", "green");
String expected = "{\"colorChanged\":\"green\",\"typeChanged\":\"skoda\"}";

String json = Jsonbs.defaultJsonb.toJson(car);
assertEquals(expected, json);
Car deserialized = Jsonbs.defaultJsonb.fromJson(expected, Car.class);
assertEquals(car, deserialized);
}

@Test
public void testRecordProcessingWithoutJsonbProperties() {
CarWithoutAnnotations car = new CarWithoutAnnotations("skoda", "green");
String expected = "{\"color\":\"green\",\"type\":\"skoda\"}";

String json = Jsonbs.defaultJsonb.toJson(car);
assertEquals(expected, json);
CarWithoutAnnotations deserialized = Jsonbs.defaultJsonb.fromJson(expected, CarWithoutAnnotations.class);
assertEquals(car, deserialized);
}

}

0 comments on commit 7a5b15a

Please sign in to comment.