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