Skip to content

Commit

Permalink
Merge pull request #1496 from ISISComputingGroup/fix_macro_defaults
Browse files Browse the repository at this point in the history
Fix deserialization of attributes marked with @SerializedName
  • Loading branch information
rerpha authored Oct 26, 2022
2 parents cb49622 + 88bb6db commit 48e0652
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Require-Bundle: org.eclipse.core.runtime,
uk.ac.stfc.isis.ibex.alarm,
org.diirt.vtype;bundle-version="3.1.5",
com.google.guava,
com.google.gson,
uk.ac.stfc.isis.ibex.managermode,
uk.ac.stfc.isis.ibex.validators;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-17
Expand Down
4 changes: 3 additions & 1 deletion base/uk.ac.stfc.isis.ibex.epics.tests/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ Require-Bundle: org.junit,
org.mockito.mockito-core;bundle-version="4.7.0",
net.bytebuddy.byte-buddy;bundle-version="1.12.13",
net.bytebuddy.byte-buddy-agent;bundle-version="1.12.13",
org.objenesis;bundle-version="3.2.0"
org.objenesis;bundle-version="3.2.0",
com.google.gson,
com.google.guava
Automatic-Module-Name: uk.ac.stfc.isis.ibex.epics.tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package uk.ac.stfc.isis.ibex.epics.tests.conversion.json;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;

import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;

import uk.ac.stfc.isis.ibex.epics.conversion.ConversionException;
import uk.ac.stfc.isis.ibex.epics.conversion.json.LowercaseEnumTypeAdapterFactory;

@RunWith(MockitoJUnitRunner.Strict.class)
public class LowercaseEnumTypeAdapterFactoryTest {

public static enum TestEnum {
IMPLICIT_ONE,
IMPLICIT_TWO;
}

public static enum TestEnumWithSerializedName {
@SerializedName("name1") EXPLICIT_ONE,
@SerializedName("name2") EXPLICIT_TWO;
}

public static enum TestEnumMixed {
MIXED_ONE,
@SerializedName("explicit_name") MIXED_TWO;
}

@Test
public void convert_enum() throws ConversionException {
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new LowercaseEnumTypeAdapterFactory())
.create();

assertEquals(TestEnum.IMPLICIT_ONE, gson.fromJson("\"implicit_one\"", TestEnum.class));
assertEquals(TestEnum.IMPLICIT_TWO, gson.fromJson("\"implicit_two\"", TestEnum.class));

assertEquals(TestEnumWithSerializedName.EXPLICIT_ONE, gson.fromJson("\"name1\"", TestEnumWithSerializedName.class));
assertEquals(TestEnumWithSerializedName.EXPLICIT_TWO, gson.fromJson("\"name2\"", TestEnumWithSerializedName.class));

assertEquals(TestEnumMixed.MIXED_ONE, gson.fromJson("\"mixed_one\"", TestEnumMixed.class));
assertEquals(TestEnumMixed.MIXED_TWO, gson.fromJson("\"explicit_name\"", TestEnumMixed.class));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;

import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
Expand All @@ -48,9 +50,23 @@ public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
return null;
}

final Map<String, T> lowercaseToConstant = new HashMap<String, T>();
for (T constant : rawType.getEnumConstants()) {
lowercaseToConstant.put(toLowercase(constant), constant);
final Map<String, T> jsonToEnumConstant = new HashMap<String, T>();
for (var constant : rawType.getEnumConstants()) {
String name = ((Enum<?>) constant).name();

try {
// Try to get an @SerializedName annotation.
// If the SerializedName annotation is present on the enum member,
// always use it in preference to the lowercase rule.
var annotation = rawType.getField(name).getAnnotation(SerializedName.class);
if (annotation != null) {
jsonToEnumConstant.put(annotation.value(), constant);
} else {
jsonToEnumConstant.put(toLowercase(constant), constant);
}
} catch (NoSuchFieldException | SecurityException e) {
throw new RuntimeException(e);
}
}

return new TypeAdapter<T>() {
Expand All @@ -60,6 +76,13 @@ public void write(JsonWriter out, T value) throws IOException {
out.nullValue();
} else {
out.value(toLowercase(value));
for (var entry : jsonToEnumConstant.entrySet()) {
if (Objects.equals(entry.getValue(), value)) {
out.value(entry.getKey());
return;
}
}
throw new RuntimeException("Invalid enum constant " + value + " provided to TypeAdapter write(). Allowed values: " + jsonToEnumConstant);
}
}

Expand All @@ -69,7 +92,7 @@ public T read(JsonReader reader) throws IOException {
reader.nextNull();
return null;
} else {
return lowercaseToConstant.get(reader.nextString());
return jsonToEnumConstant.get(reader.nextString());
}
}
};
Expand Down
14 changes: 11 additions & 3 deletions base/uk.ac.stfc.isis.ibex.targetplatform/targetplatform.target
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,6 @@
<location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="true" type="InstallableUnit">
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20220531185310/repository/"/>
<unit id="jakarta.servlet" version="5.0.0.v20210105-0527"/>
<unit id="com.google.gson" version="2.8.9.v20220111-1409"/>
<unit id="com.google.gson.source" version="2.8.9.v20220111-1409"/>
<unit id="com.google.guava" version="30.1.0.v20210127-2300"/>
<unit id="com.google.guava.source" version="30.1.0.v20210127-2300"/>
<unit id="jakarta.servlet.jsp.source" version="3.0.0.v20210105-0527"/>
Expand Down Expand Up @@ -219,7 +217,7 @@
</dependency>
</dependencies>
</location>
<location includeDependencyDepth="none" includeSource="true" missingManifest="generate" type="Maven">
<location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="generate" type="Maven">
<dependencies>
<dependency>
<groupId>org.glassfish.tyrus.bundles</groupId>
Expand All @@ -229,6 +227,16 @@
</dependency>
</dependencies>
</location>
<location includeDependencyDepth="none" includeSource="true" missingManifest="generate" type="Maven">
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.1</version>
<type>jar</type>
</dependency>
</dependencies>
</location>
</locations>
<environment>
<os>linux</os>
Expand Down

0 comments on commit 48e0652

Please sign in to comment.