Skip to content

Commit 2e670e6

Browse files
committed
remove redundant class type hint from ISerializable, with some tests
1 parent 076d192 commit 2e670e6

File tree

3 files changed

+145
-114
lines changed

3 files changed

+145
-114
lines changed

src/main/java/cat/nyaa/nyaacore/configuration/ISerializable.java

+16-7
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,12 @@ static List<Object> asPrimitiveList(List<?> list) {
9797
if (o == null) continue;
9898
if (o instanceof ISerializable) {
9999
YamlConfiguration tmp = new YamlConfiguration();
100+
tmp.set(TYPE_KEY, o.getClass().getName());
100101
pushSerializable(tmp, (ISerializable) o);
101102
primitiveList.add(tmp);
102103
} else if (o instanceof Map) {
103104
YamlConfiguration tmp = new YamlConfiguration();
104-
pushMap(tmp, (Map) o);
105+
pushMap(tmp, (Map) o, false);
105106
primitiveList.add(tmp);
106107
} else if (o instanceof List) {
107108
primitiveList.add(asPrimitiveList((List) o));
@@ -114,8 +115,15 @@ static List<Object> asPrimitiveList(List<?> list) {
114115
return primitiveList;
115116
}
116117

117-
// push primitive objects then dispatch complex objects into corresponding methods
118-
static void pushMap(ConfigurationSection config, Map<?, ?> map) {
118+
/**
119+
* push primitive objects then dispatch complex objects into corresponding methods
120+
* @param config the ConfigurationSection to be pushed into.
121+
* @param map the String-Object map
122+
* @param belongsToISerializable If the map is the shadowMap of some ISerializable.
123+
* If it is, nested ISerializable objects do not needs type hint
124+
* as class field indicates the correct type.
125+
*/
126+
static void pushMap(ConfigurationSection config, Map<?, ?> map, boolean belongsToISerializable) {
119127
for (Map.Entry<?, ?> e : map.entrySet()) {
120128
if (!(e.getKey() instanceof String)) {
121129
throw new IllegalArgumentException("Map key is not string: " + e.getKey().toString());
@@ -124,9 +132,11 @@ static void pushMap(ConfigurationSection config, Map<?, ?> map) {
124132
Object obj = e.getValue();
125133
if (obj == null) continue;
126134
if (obj instanceof ISerializable) {
127-
((ISerializable) obj).serialize(config.createSection(key));
135+
ConfigurationSection section = config.createSection(key);
136+
if (!belongsToISerializable) section.set(TYPE_KEY, obj.getClass().getName());
137+
((ISerializable) obj).serialize(section);
128138
} else if (obj instanceof Map) {
129-
pushMap(config.createSection(key), (Map<?, ?>) obj);
139+
pushMap(config.createSection(key), (Map<?, ?>) obj, false);
130140
} else if (obj instanceof List) {
131141
config.set(key, asPrimitiveList((List) obj));
132142
//throw new IllegalArgumentException("List serialization not implemented");
@@ -143,7 +153,6 @@ static void pushMap(ConfigurationSection config, Map<?, ?> map) {
143153
static void pushSerializable(ConfigurationSection config, ISerializable serializable) {
144154
Class<?> clz = serializable.getClass();
145155
Map<String, Object> shallowMap = new HashMap<>();
146-
shallowMap.put(TYPE_KEY, clz.getName());
147156
for (Field f : clz.getDeclaredFields()) {
148157
// standalone config
149158
StandaloneConfig standaloneAnno = f.getAnnotation(StandaloneConfig.class);
@@ -183,7 +192,7 @@ static void pushSerializable(ConfigurationSection config, ISerializable serializ
183192
} catch (ReflectiveOperationException ex) {
184193
Bukkit.getLogger().log(Level.SEVERE, "Failed to serialize object", ex);
185194
}
186-
pushMap(config, shallowMap);
195+
pushMap(config, shallowMap, true);
187196
}
188197
}
189198

src/test/java/cat/nyaa/nyaacore/configuration/DataObject.java

-59
This file was deleted.

src/test/java/cat/nyaa/nyaacore/configuration/ISerializableTest.java

+129-48
Original file line numberDiff line numberDiff line change
@@ -4,75 +4,156 @@
44
import org.junit.Test;
55

66
import java.io.StringReader;
7-
import java.util.ArrayList;
7+
import java.util.Collections;
8+
import java.util.LinkedList;
89
import java.util.List;
910

1011
import static org.junit.Assert.assertEquals;
1112
import static org.junit.Assert.assertNotNull;
12-
import static org.junit.Assert.assertTrue;
1313

1414
public class ISerializableTest {
15-
@Test
16-
public void test1() throws Exception {
15+
private static final boolean enable_print = false;
16+
//private static final boolean enable_print = true;
17+
18+
private <T extends ISerializable> T process(T obj) throws ReflectiveOperationException{
1719
YamlConfiguration cfg = new YamlConfiguration();
18-
DataObject obj1 = new DataObject();
19-
DataObject obj2 = new DataObject();
20-
obj1.fillNestedList();
21-
obj1.serialize(cfg);
22-
String yml = cfg.saveToString();
23-
final String ans = "str: The quick brown fox jumps over the lazy dog\n__class__: cat.nyaa.nyaacore.configuration.DataObject\nnumber_int: 42\nnumber_long: 42\nenum_1: VALUE_A\nenum_2: LEAVES\nmap:\n key1: value1\n key2: value2\n key3: value3\n key4: value4\nanotherDataObject:\n x: 42\n __class__: cat.nyaa.nyaacore.configuration.DataObject$NestedObject\n d: 42.42\nmapOfDataObject:\n obj2:\n x: 42\n __class__: cat.nyaa.nyaacore.configuration.DataObject$NestedObject\n d: 42.42\n obj1:\n x: 42\n __class__: cat.nyaa.nyaacore.configuration.DataObject$NestedObject\n d: 42.42\nnestedList:\n '0':\n - 0\n - 1\n - 2\n - 3\n - 4\n - 5\n - 6\n - 7\n - 8\n - 9\n '11':\n - 30\n - 31\n - 32\n - 33\n - 34\n - 35\n - 36\n - 37\n - 38\n - 39\n '110':\n - 60\n - 61\n - 62\n - 63\n - 64\n - 65\n - 66\n - 67\n - 68\n - 69\n '1':\n - 10\n - 11\n - 12\n - 13\n - 14\n - 15\n - 16\n - 17\n - 18\n - 19\n '100':\n - 40\n - 41\n - 42\n - 43\n - 44\n - 45\n - 46\n - 47\n - 48\n - 49\n '111':\n - 70\n - 71\n - 72\n - 73\n - 74\n - 75\n - 76\n - 77\n - 78\n - 79\n '101':\n - 50\n - 51\n - 52\n - 53\n - 54\n - 55\n - 56\n - 57\n - 58\n - 59\n '1001':\n - 90\n - 91\n - 92\n - 93\n - 94\n - 95\n - 96\n - 97\n - 98\n - 99\n '1000':\n - 80\n - 81\n - 82\n - 83\n - 84\n - 85\n - 86\n - 87\n - 88\n - 89\n '10':\n - 20\n - 21\n - 22\n - 23\n - 24\n - 25\n - 26\n - 27\n - 28\n - 29\n";
24-
assertEquals(ans, yml);
25-
26-
YamlConfiguration parse = YamlConfiguration.loadConfiguration(new StringReader(yml));
27-
obj2.deserialize(parse);
28-
for (int i=0;i<=9;i++) {
29-
for (int j=0;j<=9;j++)
30-
assertEquals((long)(i*10+j), (long)obj2.nestedList.get(Integer.toString(i,2)).get(j));
31-
}
20+
obj.serialize(cfg);
21+
T newObj = (T)obj.getClass().newInstance();
22+
if (enable_print) System.out.println(cfg.saveToString());
23+
newObj.deserialize(YamlConfiguration.loadConfiguration(new StringReader(cfg.saveToString())));
24+
return newObj;
3225
}
3326

34-
static class Test2Class implements ISerializable {
27+
private void print(ISerializable obj) {
28+
if (!enable_print) return;
29+
YamlConfiguration cfg = new YamlConfiguration();
30+
obj.serialize(cfg);
31+
System.out.println(cfg.saveToString());
32+
}
33+
34+
public static enum TestEnum {
35+
VALUE_A,
36+
VALUE_B,
37+
VALUE_C,
38+
VALUE_D,
39+
VALUE_E;
40+
}
41+
42+
public static class Test1Class implements ISerializable {
43+
@Serializable
44+
public Integer i;
45+
@Serializable
46+
public Double d;
47+
@Serializable
48+
public String s;
3549
@Serializable
36-
List<Object> objs = new ArrayList<>();
50+
public TestEnum e;
3751

38-
Test2Class() {
39-
objs.add(new DataObject());
40-
objs.add(new DataObject());
41-
objs.add(new DataObject.NestedObject());
52+
public Test1Class fill() {
53+
i = 42;
54+
d = 42.42;
55+
s = "42";
56+
e = TestEnum.VALUE_D;
57+
return this;
4258
}
59+
60+
public void assertEq() {
61+
assertEquals((Integer)42, i);
62+
assertEquals((Double)42.42, d);
63+
assertEquals("42", s);
64+
assertEquals(TestEnum.VALUE_D, e);
65+
}
66+
}
67+
68+
@Test
69+
public void test1() throws Exception {
70+
process(new Test1Class().fill()).assertEq();
71+
}
72+
73+
static class Test2Class implements ISerializable {
74+
@Serializable(name = "object.nested.double")
75+
Test1Class obj;
4376
}
4477

4578
@Test
4679
public void test2() throws Exception {
47-
YamlConfiguration cfg = new YamlConfiguration();
48-
Test2Class cls = new Test2Class();
49-
((DataObject) cls.objs.get(1)).fillNestedList();
50-
cls.serialize(cfg);
51-
//System.out.println(cfg.saveToString());
52-
cls.objs = null;
53-
cls.deserialize(YamlConfiguration.loadConfiguration(new StringReader(cfg.saveToString())));
54-
assertTrue(List.class.isAssignableFrom(cls.objs.getClass()));
55-
assertEquals(DataObject.class, cls.objs.get(0).getClass());
56-
assertEquals(DataObject.class, cls.objs.get(1).getClass());
57-
assertEquals(DataObject.NestedObject.class, cls.objs.get(2).getClass());
58-
for (int i = 0; i <= 9; i++) {
59-
for (int j = 0; j <= 9; j++)
60-
assertEquals((long) (i * 10 + j), (long) ((DataObject) cls.objs.get(1)).nestedList.get(Integer.toString(i, 2)).get(j));
61-
}
80+
Test2Class obj = new Test2Class();
81+
obj.obj = new Test1Class().fill();
82+
Test2Class n = process(obj);
83+
assertNotNull(n);
84+
assertNotNull(n.obj);
85+
assertEquals(Test2Class.class, n.getClass());
86+
n.obj.assertEq();
6287
}
6388

6489
static class Test3Class implements ISerializable {
65-
@Serializable(name = "object.nested.double")
66-
DataObject.NestedObject obj = new DataObject.NestedObject();
90+
@Serializable
91+
List<Test1Class> list;
6792
}
6893

6994
@Test
7095
public void test3() throws Exception {
71-
YamlConfiguration cfg = new YamlConfiguration();
72-
Test3Class cls = new Test3Class();
73-
cls.serialize(cfg);
74-
cls.obj = null;
75-
cls.deserialize(cfg);
76-
assertNotNull(cls.obj);
96+
Test3Class o = new Test3Class();
97+
o.list = new LinkedList<>();
98+
for (int i = 0;i<5;i++) o.list.add(new Test1Class().fill());
99+
Test3Class n = process(o);
100+
assertEquals(5, o.list.size());
101+
for (int i = 0;i<5;i++) n.list.get(i).assertEq();
102+
}
103+
104+
static class Test4Class implements ISerializable {
105+
@Serializable
106+
int depth;
107+
@Serializable
108+
Test4Class nested;
109+
public Test4Class() {}
110+
public Test4Class(int depth) {
111+
this.depth = depth;
112+
if (depth > 0) {
113+
nested = new Test4Class(depth - 1);
114+
}
115+
}
116+
117+
public void check(int depth) {
118+
assertEquals(depth, this.depth);
119+
if (depth > 0) {
120+
assertNotNull(nested);
121+
nested.check(depth - 1);
122+
}
123+
}
124+
}
125+
126+
@Test
127+
public void test4() throws Exception {
128+
process(new Test4Class(10)).check(10);
129+
}
130+
131+
static class Test5Class implements ISerializable {
132+
@Serializable
133+
int depth;
134+
@Serializable
135+
List<Test5Class> nested;
136+
public Test5Class() {}
137+
public Test5Class(int depth) {
138+
this.depth = depth;
139+
if (depth > 0) {
140+
nested = Collections.singletonList(new Test5Class(depth - 1));
141+
}
142+
}
143+
144+
public void check(int depth) {
145+
assertEquals(depth, this.depth);
146+
if (depth > 0) {
147+
assertNotNull(nested);
148+
assertEquals(1, nested.size());
149+
nested.get(0).check(depth - 1);
150+
}
151+
}
152+
}
153+
154+
@Test
155+
public void test5() throws Exception {
156+
process(new Test5Class(10)).check(10);
77157
}
78-
}
158+
}
159+

0 commit comments

Comments
 (0)