build(Map)   B
last analyzed

Complexity

Conditions 6

Size

Total Lines 33
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 24
dl 0
loc 33
c 1
b 0
f 0
cc 6
rs 8.3706
1
package es.webbeta.serializer.metadata;
2
3
import es.webbeta.serializer.base.MetadataProperty;
4
import es.webbeta.serializer.type.FieldAccessType;
5
6
import java.util.ArrayList;
7
import java.util.List;
8
import java.util.Map;
9
10
@SuppressWarnings("unchecked")
11
public class MetadataConstructor {
0 ignored issues
show
Best Practice introduced by
This looks like a utility class. You may want to hide the implict public constructor behind a private one, so the class cannot be instantiated,
Loading history...
12
13
    private static final String KEY_VIRTUAL_PROPERTIES = "virtual_properties";
14
    private static final String KEY_PROPERTIES = "properties";
15
    private static final String KEY_ACCESS_TYPE = "access_type";
16
    private static final String KEY_ACCESSOR = "accessor";
17
    private static final String KEY_SERIALIZED_NAME = "serialized_name";
18
19
    private static final String KEY_GROUPS = "groups";
20
    private static final String KEY_GETTER = "getter";
21
22
    public static Metadata build(Map<?, ?> map) {
23
        if (map == null) return null;
24
        Map.Entry<String, Map<String, Object>> root =
25
                (Map.Entry<String, Map<String, Object>>) map.entrySet().iterator().next();
26
27
        String canonicalName = root.getKey();
28
        Map<String, Object> modifiers = root.getValue();
29
30
        Metadata metadata = new Metadata(canonicalName);
31
32
        for (Map.Entry<String, Object> modifierEntry : modifiers.entrySet()) {
33
            String key = modifierEntry.getKey();
34
35
            switch (key) {
0 ignored issues
show
Code Smell introduced by
You may want to add a default case to this switch to deal with unforseen inputs.

Default branches should deal with the unexpected. At a minimum, they should log the error and if applicable, return a default value (null, empty collection). If you really do not expect the default branch to ever be use, throw a RuntimeException when it is.

Loading history...
36
                case KEY_PROPERTIES: {
37
                    List<es.webbeta.serializer.metadata.MetadataProperty> properties =
38
                            buildProperties((Map<String, Map<String, Object>>) modifierEntry.getValue(), false);
39
                    metadata.setProperties(properties);
40
                    break;
41
                }
42
                case KEY_ACCESS_TYPE:
43
                    metadata.setAccessType(FieldAccessType.fromString((String) modifierEntry.getValue()));
44
                    break;
45
                case KEY_VIRTUAL_PROPERTIES: {
46
                    List<MetadataVirtualProperty> properties =
47
                            buildProperties((Map<String, Map<String, Object>>) modifierEntry.getValue(), true);
48
                    metadata.setVirtualProperties(properties);
49
                    break;
50
                }
51
            }
52
        }
53
54
        return metadata;
55
    }
56
57
    private static <T extends MetadataProperty> List<T> buildProperties(Map<String, Map<String, Object>> map, Boolean asVirtualProperties) {
58
        List<MetadataProperty> properties = new ArrayList<>();
59
60
        for (Map.Entry<String, Map<String, Object>> propertyEntry : map.entrySet()) {
61
            String propertyName = propertyEntry.getKey();
62
            Map<String, Object> args = propertyEntry.getValue();
63
64
            MetadataProperty metadataProperty = asVirtualProperties ?
65
                    new MetadataVirtualProperty(propertyName) :
66
                    new es.webbeta.serializer.metadata.MetadataProperty(propertyName);
67
68
            for (Map.Entry<String, Object> argEntry : args.entrySet()) {
69
                String key = argEntry.getKey();
70
71
                switch (key) {
0 ignored issues
show
Code Smell introduced by
You may want to add a default case to this switch to deal with unforseen inputs.

Default branches should deal with the unexpected. At a minimum, they should log the error and if applicable, return a default value (null, empty collection). If you really do not expect the default branch to ever be use, throw a RuntimeException when it is.

Loading history...
72
                    case KEY_GROUPS:
73
                        List<String> groups = new ArrayList<>();
74
                        for (Object rawGroup : (List<?>) argEntry.getValue()) {
75
                            String group = (String) rawGroup;
76
                            groups.add(group);
77
                        }
78
                        metadataProperty.setGroups(groups);
79
                        break;
80
                    case KEY_SERIALIZED_NAME:
81
                        metadataProperty.setSerializedName((String) argEntry.getValue());
82
                        break;
83
                }
84
85
                if (!asVirtualProperties) {
86
                    switch (key) {
0 ignored issues
show
Code Smell introduced by
You may want to add a default case to this switch to deal with unforseen inputs.

Default branches should deal with the unexpected. At a minimum, they should log the error and if applicable, return a default value (null, empty collection). If you really do not expect the default branch to ever be use, throw a RuntimeException when it is.

Loading history...
87
                        case KEY_ACCESS_TYPE:
88
                            metadataProperty.setAccessType(FieldAccessType.fromString((String) argEntry.getValue()));
89
                            break;
90
                        case KEY_ACCESSOR:
91
                            MetadataPropertyAccessor accessor =
92
                                    buildPropertyAccessor(metadataProperty, (Map<String, String>) argEntry.getValue());
93
                            metadataProperty.setAccessor(accessor);
94
                            break;
95
                    }
96
                }
97
            }
98
99
            properties.add(metadataProperty);
100
        }
101
102
        return (List<T>) properties;
103
    }
104
105
    private static MetadataPropertyAccessor buildPropertyAccessor(MetadataProperty metadataProperty, Map<String, String> map) {
106
        if (metadataProperty.getAccessType() != FieldAccessType.PUBLIC_METHOD) return null;
107
108
        String getter = null;
109
        for (Map.Entry<String, String> argEntry : map.entrySet()) {
110
            String key = argEntry.getKey();
111
112
            if (key.equals(KEY_GETTER))
113
                getter = argEntry.getValue();
114
        }
115
        return (getter == null) ?
116
                null :
117
                new MetadataPropertyAccessor(getter);
118
    }
119
120
}
121