• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

goblint / GobPie / 9678350809

26 Jun 2024 10:54AM UTC coverage: 58.518%. First build
9678350809

Pull #72

github

web-flow
Merge 986be0326 into e8d777526
Pull Request #72: Add functional tests

123 of 233 branches covered (52.79%)

Branch coverage included in aggregate %.

128 of 160 new or added lines in 20 files covered. (80.0%)

406 of 671 relevant lines covered (60.51%)

2.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

79.31
/src/main/java/api/json/GobPieConfValidatorAdapterFactory.java
1
package api.json;
2

3
import com.google.gson.Gson;
4
import com.google.gson.JsonParseException;
5
import com.google.gson.TypeAdapter;
6
import com.google.gson.TypeAdapterFactory;
7
import com.google.gson.internal.bind.ReflectiveTypeAdapterFactory;
8
import com.google.gson.reflect.TypeToken;
9

10
import java.lang.reflect.Field;
11
import java.util.LinkedHashMap;
12
import java.util.Map;
13

14
/**
15
 * A class for handling unexpected fields in GobPie configuration.
16
 * Code adapted from <a href="https://github.com/google/gson/issues/188">a Gson library issue</a>.
17
 *
18
 * @since 0.0.4
19
 */
20

21
public class GobPieConfValidatorAdapterFactory implements TypeAdapterFactory {
3✔
22

23
    @Override
24
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
25
        // If the type adapter is a reflective type adapter, we want to modify the implementation using reflection.
26
        // The trick is to replace the Map object used to look up the property name.
27
        // Instead of returning null if the property is not found,
28
        // we throw a Json exception to terminate the deserialization.
29
        TypeAdapter<T> delegateAdapter = gson.getDelegateAdapter(this, type);
5✔
30

31
        // Check if the type adapter is a reflective, cause this solution only work for reflection.
32
        if (delegateAdapter instanceof ReflectiveTypeAdapterFactory.Adapter) {
3✔
33

34
            try {
35
                // Get reference to the existing boundFields.
36
                Field f = findBoundField(delegateAdapter.getClass());
4✔
37
                f.setAccessible(true);
3✔
38
                // Finally, push our custom map back using reflection.
39
                f.set(delegateAdapter, getBoundFields(f, delegateAdapter));
6✔
NEW
40
            } catch (Exception e) {
×
41
                // Should never happen if the implementation doesn't change.
NEW
42
                throw new IllegalStateException(e);
×
43
            }
1✔
44

45
        }
46
        return delegateAdapter;
2✔
47
    }
48

49
    @SuppressWarnings("unchecked")
50
    private static <T> Object getBoundFields(Field f, TypeAdapter<T> delegate) throws IllegalAccessException {
51
        Object boundFields = f.get(delegate);
4✔
52

53
        // Then replace it with our implementation throwing exception if the value is null.
54
        boundFields = new LinkedHashMap<>((Map<Object, Object>) boundFields) {
10✔
55

56
            @Override
57
            public Object get(Object key) {
58
                Object value = super.get(key);
4✔
59
                if (value == null) {
2✔
60
                    throw new JsonParseException(String.valueOf(key));
6✔
61
                }
62
                return value;
2✔
63
            }
64

65
        };
66
        return boundFields;
2✔
67
    }
68

69
    private static Field findBoundField(Class<?> startingClass) throws NoSuchFieldException {
70
        for (Class<?> c = startingClass; c != null; c = c.getSuperclass()) {
8!
71
            try {
72
                return c.getDeclaredField("boundFields");
4✔
73
            } catch (NoSuchFieldException e) {
1✔
74
                // OK: continue with superclasses
75
            }
76
        }
NEW
77
        throw new NoSuchFieldException("boundFields starting from " + (startingClass != null ? startingClass.getName() : null));
×
78
    }
79
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc