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.AllArgsConstructor;
30 import lombok.EqualsAndHashCode;
31 import lombok.NoArgsConstructor;
32 import lombok.ToString;
33
34
35
36
37
38
39 @ToString
40 @EqualsAndHashCode
41 @NoArgsConstructor
42 @AllArgsConstructor
43 public abstract class UnknownAware {
44
45 @Schema(description = "Unknown properties.", hidden = true)
46 @JsonIgnore
47 private Map<String, Object> unknown;
48
49
50
51
52
53
54 @JsonAnyGetter
55 public Map<String, Object> unknown() {
56 return unknown;
57 }
58
59
60
61
62
63
64 public void unknown(Map<String, Object> unknown) {
65 if (unknown != null && !unknown.isEmpty()) {
66 this.unknown = unknown;
67 }
68 }
69
70
71
72
73
74
75
76 @JsonAnySetter
77 public void unknown(String name, Object value) {
78 if (name == null || name.trim().isEmpty()) {
79 return;
80 }
81 if (unknown == null) {
82 unknown = new LinkedHashMap<>();
83 }
84 unknown.put(name, value);
85 }
86
87
88
89
90
91
92 public boolean hasUnknown() {
93 return unknown != null && !unknown.isEmpty();
94 }
95
96
97
98
99
100
101
102
103
104 @SuppressWarnings({"unchecked", "rawtypes"})
105 public <T> Optional<T> findUnknown(String jsonPath, Class<T> clazz) {
106 if (!hasUnknown() || !isJsonPath(jsonPath) || clazz == null) {
107 return Optional.empty();
108 }
109 Object value = null;
110 Map<String, Object> tmpUnknown = unknown;
111 StringTokenizer tokenizer = new StringTokenizer(jsonPath.substring(2), ".");
112 while (tokenizer.hasMoreTokens()) {
113 String token = tokenizer.nextToken();
114 value = tmpUnknown.get(token);
115 if (value == null) {
116 break;
117 }
118 if (value instanceof Map && tokenizer.hasMoreTokens()) {
119 try {
120 tmpUnknown = (Map) value;
121 } catch (Exception e) {
122 return Optional.empty();
123 }
124 }
125 }
126 if (value == null) {
127 return Optional.empty();
128 }
129 try {
130 return Optional.of(clazz.cast(value));
131 } catch (Exception e) {
132 return Optional.empty();
133 }
134 }
135
136
137
138
139
140
141
142
143
144 @SuppressWarnings({"Convert2MethodRef", "unchecked"})
145 public <E> Optional<List<E>> findUnknownList(String jsonPath, Class<E> clazz) {
146 if (clazz == null) {
147 return Optional.empty();
148 }
149 try {
150 return findUnknown(jsonPath, List.class).map(
151 list -> Collections.unmodifiableList(list));
152
153 } catch (RuntimeException ignored) {
154 return Optional.empty();
155 }
156 }
157
158
159
160
161
162
163
164
165 public Optional<Map<String, Object>> findUnknownMap(String jsonPath) {
166 try {
167
168 return findUnknown(jsonPath, Map.class)
169 .map(map -> Collections.unmodifiableMap(map));
170
171 } catch (RuntimeException ignored) {
172 return Optional.empty();
173 }
174 }
175
176 private boolean isJsonPath(String jsonPath) {
177 return jsonPath != null && jsonPath.startsWith("$.") && jsonPath.length() > 2;
178 }
179
180 }