Skip to content

Commit 6e23489

Browse files
author
Inderjeet Singh
committed
Added SerializedName.pattern to enable regex mapping for an enum value to a field.
Currently, support for this beyond Enum isn't implemented.
1 parent 2271525 commit 6e23489

File tree

5 files changed

+87
-8
lines changed

5 files changed

+87
-8
lines changed

gson/src/main/java/com/google/gson/annotations/SerializedName.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,16 @@
8484
* @return the desired name of the field when it is serialized or deserialized
8585
*/
8686
String value();
87+
8788
/**
8889
* @return the alternative names of the field when it is deserialized
8990
*/
9091
String[] alternate() default {};
92+
93+
/**
94+
* @return the Java regular expression pattern to match names during deserialization.
95+
* Note that the matching order is {@link #value()}, {@link #alternate()} and
96+
* finally {@link #pattern()}.
97+
*/
98+
String pattern() default "";
9199
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (C) 2016 Gson Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.gson.internal.bind;
17+
18+
final class Pair<A, B> {
19+
public final A a;
20+
public final B b;
21+
22+
Pair(A a, B b) {
23+
this.a = a;
24+
this.b = b;
25+
}
26+
}

gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import java.util.concurrent.atomic.AtomicBoolean;
4040
import java.util.concurrent.atomic.AtomicInteger;
4141
import java.util.concurrent.atomic.AtomicIntegerArray;
42+
import java.util.regex.Pattern;
4243

4344
import com.google.gson.Gson;
4445
import com.google.gson.JsonArray;
@@ -789,6 +790,7 @@ public void write(JsonWriter out, Locale value) throws IOException {
789790
private static final class EnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
790791
private final Map<String, T> nameToConstant = new HashMap<String, T>();
791792
private final Map<T, String> constantToName = new HashMap<T, String>();
793+
private List<Pair<Pattern, T>> patternToConstant;
792794

793795
public EnumTypeAdapter(Class<T> classOfT) {
794796
try {
@@ -800,6 +802,14 @@ public EnumTypeAdapter(Class<T> classOfT) {
800802
for (String alternate : annotation.alternate()) {
801803
nameToConstant.put(alternate, constant);
802804
}
805+
String regex = annotation.pattern();
806+
if (regex != "") {
807+
Pattern pattern = Pattern.compile(regex);
808+
if (patternToConstant == null) {
809+
patternToConstant = new ArrayList<Pair<Pattern, T>>();
810+
}
811+
patternToConstant.add(new Pair<Pattern, T>(pattern, constant));
812+
}
803813
}
804814
nameToConstant.put(name, constant);
805815
constantToName.put(constant, name);
@@ -813,7 +823,19 @@ public EnumTypeAdapter(Class<T> classOfT) {
813823
in.nextNull();
814824
return null;
815825
}
816-
return nameToConstant.get(in.nextString());
826+
String value = in.nextString();
827+
T matched = nameToConstant.get(value);
828+
if (matched == null) {
829+
// Try the patterns
830+
if (patternToConstant != null) {
831+
for (Pair<Pattern, T> pair : patternToConstant) {
832+
if (pair.a.matcher(value).matches()) {
833+
return pair.b;
834+
}
835+
}
836+
}
837+
}
838+
return matched;
817839
}
818840

819841
@Override public void write(JsonWriter out, T value) throws IOException {

gson/src/test/java/com/google/gson/functional/EnumTest.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616

1717
package com.google.gson.functional;
1818

19+
import java.lang.reflect.Type;
20+
import java.util.ArrayList;
21+
import java.util.Collection;
22+
import java.util.EnumSet;
23+
import java.util.Set;
24+
1925
import com.google.gson.Gson;
2026
import com.google.gson.GsonBuilder;
2127
import com.google.gson.JsonDeserializationContext;
@@ -29,13 +35,6 @@
2935
import com.google.gson.common.MoreAsserts;
3036
import com.google.gson.reflect.TypeToken;
3137

32-
33-
import java.lang.reflect.Type;
34-
import java.util.ArrayList;
35-
import java.util.Collection;
36-
import java.util.EnumSet;
37-
import java.util.Set;
38-
3938
import junit.framework.TestCase;
4039
/**
4140
* Functional tests for Java 5.0 enums.

gson/src/test/java/com/google/gson/functional/SerializedNameTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package com.google.gson.functional;
1717

18+
import java.util.regex.Pattern;
19+
1820
import com.google.gson.Gson;
1921
import com.google.gson.annotations.SerializedName;
2022

@@ -51,4 +53,26 @@ private static final class MyClass {
5153
this.b = b;
5254
}
5355
}
56+
57+
public void testPatternForEnum() {
58+
Gson gson = new Gson();
59+
assertTrue(Pattern.compile("\\S*").matcher("REDIRECT").matches()); // verify that the pattern is correct
60+
Response target = gson.fromJson("{'error1':'AUTH_FAILURE','error2':'REDIRECT','error3':'SERVER_ERROR'}", Response.class);
61+
assertEquals(ErrorCode.AUTH_FAILURE, target.error1);
62+
assertEquals(ErrorCode.UNKNOWN, target.error2);
63+
assertEquals(ErrorCode.SERVER_ERROR, target.error3);
64+
}
65+
66+
private enum ErrorCode {
67+
AUTH_FAILURE,
68+
SERVER_ERROR,
69+
/** match all non-whitespace characters. Note that pattern is applied last. */
70+
@SerializedName(value="UNKNOWN", pattern="\\S*") UNKNOWN
71+
}
72+
73+
private static final class Response {
74+
ErrorCode error1;
75+
ErrorCode error2;
76+
ErrorCode error3;
77+
}
5478
}

0 commit comments

Comments
 (0)