1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.bremersee.geojson.model;
18
19 import com.fasterxml.jackson.annotation.JsonAnyGetter;
20 import com.fasterxml.jackson.annotation.JsonAnySetter;
21 import com.fasterxml.jackson.annotation.JsonIgnore;
22 import io.swagger.v3.oas.annotations.media.Schema;
23 import java.util.Collections;
24 import java.util.LinkedHashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Optional;
28 import java.util.StringTokenizer;
29 import lombok.EqualsAndHashCode;
30 import lombok.ToString;
31
32
33
34
35
36
37 @ToString
38 @EqualsAndHashCode
39 public abstract class UnknownAware {
40
41 @Schema(description = "Unknown properties.", hidden = true)
42 @JsonIgnore
43 private Map<String, Object> unknown;
44
45
46
47
48 protected UnknownAware() {
49 super();
50 }
51
52
53
54
55
56
57 protected UnknownAware(Map<String, Object> unknown) {
58 this.unknown = unknown;
59 }
60
61
62
63
64
65
66 @JsonAnyGetter
67 public Map<String, Object> unknown() {
68 return unknown;
69 }
70
71
72
73
74
75
76 public void unknown(Map<String, Object> unknown) {
77 if (unknown != null && !unknown.isEmpty()) {
78 this.unknown = unknown;
79 }
80 }
81
82
83
84
85
86
87
88 @JsonAnySetter
89 public void unknown(String name, Object value) {
90 if (name == null || name.trim().isEmpty()) {
91 return;
92 }
93 if (unknown == null) {
94 unknown = new LinkedHashMap<>();
95 }
96 unknown.put(name, value);
97 }
98
99
100
101
102
103
104 public boolean hasUnknown() {
105 return unknown != null && !unknown.isEmpty();
106 }
107
108
109
110
111
112
113
114
115
116 @SuppressWarnings({"unchecked", "rawtypes"})
117 public <T> Optional<T> findUnknown(String jsonPath, Class<T> clazz) {
118 if (!hasUnknown() || !isJsonPath(jsonPath) || clazz == null) {
119 return Optional.empty();
120 }
121 Object value = null;
122 Map<String, Object> tmpUnknown = unknown;
123 StringTokenizer tokenizer = new StringTokenizer(jsonPath.substring(2), ".");
124 while (tokenizer.hasMoreTokens()) {
125 String token = tokenizer.nextToken();
126 value = tmpUnknown.get(token);
127 if (value == null) {
128 break;
129 }
130 if (value instanceof Map map && tokenizer.hasMoreTokens()) {
131 try {
132 tmpUnknown = map;
133 } catch (Exception e) {
134 return Optional.empty();
135 }
136 }
137 }
138 if (value == null) {
139 return Optional.empty();
140 }
141 try {
142 return Optional.of(clazz.cast(value));
143 } catch (Exception e) {
144 return Optional.empty();
145 }
146 }
147
148
149
150
151
152
153
154
155
156 @SuppressWarnings({"Convert2MethodRef", "unchecked"})
157 public <E> Optional<List<E>> findUnknownList(String jsonPath, Class<E> clazz) {
158 if (clazz == null) {
159 return Optional.empty();
160 }
161 try {
162 return findUnknown(jsonPath, List.class)
163 .map(list -> Collections.unmodifiableList(list));
164
165 } catch (RuntimeException ignored) {
166 return Optional.empty();
167 }
168 }
169
170
171
172
173
174
175
176
177 public Optional<Map<String, Object>> findUnknownMap(String jsonPath) {
178 try {
179
180 return findUnknown(jsonPath, Map.class)
181 .map(map -> Collections.unmodifiableMap(map));
182
183 } catch (RuntimeException ignored) {
184 return Optional.empty();
185 }
186 }
187
188 private boolean isJsonPath(String jsonPath) {
189 return jsonPath != null && jsonPath.startsWith("$.") && jsonPath.length() > 2;
190 }
191
192 }