|
20 | 20 | import org.apache.seatunnel.shade.com.fasterxml.jackson.core.JsonProcessingException;
|
21 | 21 | import org.apache.seatunnel.shade.com.fasterxml.jackson.core.type.TypeReference;
|
22 | 22 | import org.apache.seatunnel.shade.com.fasterxml.jackson.databind.ObjectMapper;
|
23 |
| -import org.apache.seatunnel.shade.com.fasterxml.jackson.dataformat.javaprop.JavaPropsMapper; |
24 | 23 | import org.apache.seatunnel.shade.com.typesafe.config.Config;
|
25 | 24 | import org.apache.seatunnel.shade.com.typesafe.config.ConfigFactory;
|
26 | 25 |
|
27 | 26 | import org.apache.seatunnel.api.configuration.Option;
|
28 |
| -import org.apache.seatunnel.api.table.catalog.schema.TableSchemaOptions; |
29 |
| - |
30 |
| -import org.apache.commons.lang3.StringEscapeUtils; |
31 |
| -import org.apache.commons.lang3.StringUtils; |
32 | 27 |
|
33 | 28 | import lombok.extern.slf4j.Slf4j;
|
34 | 29 |
|
35 | 30 | import java.lang.reflect.ParameterizedType;
|
36 |
| -import java.util.ArrayList; |
37 | 31 | import java.util.Arrays;
|
38 |
| -import java.util.Collections; |
39 |
| -import java.util.LinkedHashMap; |
40 | 32 | import java.util.List;
|
41 | 33 | import java.util.Locale;
|
42 |
| -import java.util.Map; |
43 | 34 | import java.util.stream.Collectors;
|
44 | 35 |
|
45 | 36 | @Slf4j
|
46 | 37 | public class ConfigUtil {
|
47 |
| - private static final JavaPropsMapper PROPERTIES_MAPPER = new JavaPropsMapper(); |
48 |
| - private static final ObjectMapper JACKSON_MAPPER = new ObjectMapper(); |
49 |
| - |
50 |
| - /** |
51 |
| - * |
52 |
| - * |
53 |
| - * <pre> |
54 |
| - * poll.timeout = 1000 |
55 |
| - * ==>> poll : {timeout = 1000, interval = 500} |
56 |
| - * poll.interval = 500 |
57 |
| - * </pre> |
58 |
| - */ |
59 |
| - public static Map<String, Object> treeMap(Map<String, Object> rawMap) { |
60 |
| - try { |
61 |
| - Map<List<String>, String> properties = |
62 |
| - Arrays.stream(PROPERTIES_MAPPER.writeValueAsString(rawMap).split("\n")) |
63 |
| - .filter(StringUtils::isNoneEmpty) |
64 |
| - .map(line -> line.split("=", 2)) |
65 |
| - .collect( |
66 |
| - Collectors.toMap( |
67 |
| - kv -> Arrays.asList(kv[0].split("\\.")), |
68 |
| - kv -> kv[1], |
69 |
| - (o, n) -> o, |
70 |
| - LinkedHashMap::new)); |
71 |
| - Map<String, Object> result = loadPropertiesStyleMap(properties); |
72 |
| - // Special case, we shouldn't change key in schema config. |
73 |
| - // TODO we should not hard code it, it should be as a config. |
74 |
| - if (rawMap.containsKey(TableSchemaOptions.SCHEMA.key())) { |
75 |
| - result.put( |
76 |
| - TableSchemaOptions.SCHEMA.key(), |
77 |
| - rawMap.get(TableSchemaOptions.SCHEMA.key())); |
78 |
| - } |
79 |
| - return result; |
80 |
| - } catch (JsonProcessingException e) { |
81 |
| - throw new IllegalArgumentException("Json parsing exception."); |
82 |
| - } |
83 |
| - } |
84 | 38 |
|
85 |
| - private static Map<String, Object> loadPropertiesStyleMap( |
86 |
| - Map<List<String>, String> properties) { |
87 |
| - Map<String, Object> propertiesMap = new LinkedHashMap<>(); |
88 |
| - Map<List<String>, String> temp = new LinkedHashMap<>(); |
89 |
| - String tempPrefix = null; |
90 |
| - for (Map.Entry<List<String>, String> entry : properties.entrySet()) { |
91 |
| - String key = entry.getKey().get(0); |
92 |
| - if (!key.equals(tempPrefix)) { |
93 |
| - putKeyValueToMapCheck(propertiesMap, temp, tempPrefix); |
94 |
| - tempPrefix = key; |
95 |
| - } |
96 |
| - if (entry.getKey().size() > 1) { |
97 |
| - temp.put(entry.getKey().subList(1, entry.getKey().size()), entry.getValue()); |
98 |
| - } else if (!temp.isEmpty()) { |
99 |
| - temp.put(Collections.singletonList(""), entry.getValue()); |
100 |
| - } else { |
101 |
| - temp.put(null, entry.getValue()); |
102 |
| - } |
103 |
| - } |
104 |
| - putKeyValueToMapCheck(propertiesMap, temp, tempPrefix); |
105 |
| - return propertiesMap; |
106 |
| - } |
107 |
| - |
108 |
| - private static void putKeyValueToMapCheck( |
109 |
| - Map<String, Object> propertiesMap, Map<List<String>, String> temp, String tempPrefix) { |
110 |
| - if (!temp.isEmpty()) { |
111 |
| - if (propertiesMap.containsKey(tempPrefix)) { |
112 |
| - if (temp.containsKey(null)) { |
113 |
| - ((Map) propertiesMap.get(tempPrefix)).put("", temp.get(null)); |
114 |
| - } else if (propertiesMap.get(tempPrefix) instanceof String) { |
115 |
| - loadPropertiesStyleMap(temp).put("", propertiesMap.get(tempPrefix)); |
116 |
| - } else { |
117 |
| - mergeTwoMap((Map) propertiesMap.get(tempPrefix), loadPropertiesStyleMap(temp)); |
118 |
| - } |
119 |
| - } else { |
120 |
| - propertiesMap.put(tempPrefix, loadPropertiesStyleObject(temp)); |
121 |
| - } |
122 |
| - temp.clear(); |
123 |
| - } |
124 |
| - } |
125 |
| - |
126 |
| - private static void mergeTwoMap(Map<String, Object> base, Map<String, Object> merged) { |
127 |
| - for (Map.Entry<String, Object> entry : merged.entrySet()) { |
128 |
| - if (base.containsKey(entry.getKey())) { |
129 |
| - if (base.get(entry.getKey()) instanceof Map && entry.getValue() instanceof Map) { |
130 |
| - mergeTwoMap((Map) base.get(entry.getKey()), (Map) entry.getValue()); |
131 |
| - } else if (base.get(entry.getKey()) instanceof Map) { |
132 |
| - ((Map) base.get(entry.getKey())).put("", entry.getValue()); |
133 |
| - } else if (entry.getValue() instanceof Map) { |
134 |
| - Map<String, Object> child = new LinkedHashMap<>(); |
135 |
| - child.put("", base.get(entry.getKey())); |
136 |
| - child.putAll((Map) entry.getValue()); |
137 |
| - base.put(entry.getKey(), child); |
138 |
| - } else { |
139 |
| - throw new IllegalArgumentException( |
140 |
| - String.format( |
141 |
| - "Duplicate key '%s' in config file, value '%s' and value '%s'", |
142 |
| - entry.getKey(), base.get(entry.getKey()), entry.getValue())); |
143 |
| - } |
144 |
| - } else { |
145 |
| - base.put(entry.getKey(), entry.getValue()); |
146 |
| - } |
147 |
| - } |
148 |
| - } |
149 |
| - |
150 |
| - private static List<Object> loadPropertiesStyleList(Map<List<String>, String> properties) { |
151 |
| - List<Object> propertiesList = new ArrayList<>(); |
152 |
| - Map<List<String>, String> temp = new LinkedHashMap<>(); |
153 |
| - int tempIndex = -1; |
154 |
| - for (Map.Entry<List<String>, String> entry : properties.entrySet()) { |
155 |
| - int index = Integer.parseInt(entry.getKey().get(0)); |
156 |
| - if (index != tempIndex) { |
157 |
| - if (!temp.isEmpty()) { |
158 |
| - propertiesList.add(loadPropertiesStyleObject(temp)); |
159 |
| - temp.clear(); |
160 |
| - } |
161 |
| - tempIndex = index; |
162 |
| - } |
163 |
| - if (entry.getKey().size() == 1) { |
164 |
| - temp.put(null, entry.getValue()); |
165 |
| - } else { |
166 |
| - temp.put(entry.getKey().subList(1, entry.getKey().size()), entry.getValue()); |
167 |
| - } |
168 |
| - } |
169 |
| - if (!temp.isEmpty()) { |
170 |
| - propertiesList.add(loadPropertiesStyleObject(temp)); |
171 |
| - } |
172 |
| - return propertiesList; |
173 |
| - } |
174 |
| - |
175 |
| - private static Object loadPropertiesStyleObject(Map<List<String>, String> properties) { |
176 |
| - if (properties.containsKey(null) && properties.size() == 1) { |
177 |
| - return StringEscapeUtils.unescapeJava(properties.get(null)); |
178 |
| - } else if (properties.containsKey(null)) { |
179 |
| - if (properties.containsKey(null)) { |
180 |
| - properties.put(Collections.singletonList(""), properties.get(null)); |
181 |
| - properties.remove(null); |
182 |
| - } |
183 |
| - return loadPropertiesStyleMap(properties); |
184 |
| - } else if (properties.entrySet().stream().anyMatch(kv -> kv.getKey().get(0).equals("1"))) { |
185 |
| - return loadPropertiesStyleList(properties); |
186 |
| - } else { |
187 |
| - return loadPropertiesStyleMap(properties); |
188 |
| - } |
189 |
| - } |
190 |
| - |
191 |
| - @SuppressWarnings("unchecked") |
192 |
| - static Object flatteningMap( |
193 |
| - Object rawValue, Map<String, Object> newMap, List<String> keys, boolean nestedMap) { |
194 |
| - if (rawValue == null) { |
195 |
| - return null; |
196 |
| - } |
197 |
| - if (!(rawValue instanceof List) && !(rawValue instanceof Map)) { |
198 |
| - if (newMap == null) { |
199 |
| - return rawValue; |
200 |
| - } |
201 |
| - newMap.put(String.join(".", keys), rawValue); |
202 |
| - return newMap; |
203 |
| - } |
204 |
| - |
205 |
| - if (rawValue instanceof List) { |
206 |
| - List<Object> rawList = (List<Object>) rawValue; |
207 |
| - rawList.replaceAll(value -> flatteningMap(value, null, null, false)); |
208 |
| - if (newMap != null) { |
209 |
| - newMap.put(String.join(".", keys), rawList); |
210 |
| - return newMap; |
211 |
| - } |
212 |
| - return rawList; |
213 |
| - } else { |
214 |
| - Map<String, Object> rawMap = (Map<String, Object>) rawValue; |
215 |
| - if (!nestedMap) { |
216 |
| - keys = new ArrayList<>(); |
217 |
| - newMap = new LinkedHashMap<>(rawMap.size()); |
218 |
| - } |
219 |
| - for (Map.Entry<String, Object> entry : rawMap.entrySet()) { |
220 |
| - keys.add(entry.getKey()); |
221 |
| - flatteningMap(entry.getValue(), newMap, keys, true); |
222 |
| - keys.remove(keys.size() - 1); |
223 |
| - } |
224 |
| - return newMap; |
225 |
| - } |
226 |
| - } |
227 |
| - |
228 |
| - /** |
229 |
| - * |
230 |
| - * |
231 |
| - * <pre> |
232 |
| - * poll.timeout = 1000 |
233 |
| - * poll : {timeout = 1000, interval = 500} ==>> |
234 |
| - * poll.interval = 500 |
235 |
| - * </pre> |
236 |
| - */ |
237 |
| - @SuppressWarnings("unchecked") |
238 |
| - public static Map<String, Object> flatteningMap(Map<String, Object> treeMap) { |
239 |
| - return (Map<String, Object>) flatteningMapWithObject(treeMap); |
240 |
| - } |
241 |
| - |
242 |
| - static Object flatteningMapWithObject(Object rawValue) { |
243 |
| - return flatteningMap(rawValue, null, null, false); |
244 |
| - } |
| 39 | + private static final ObjectMapper JACKSON_MAPPER = new ObjectMapper(); |
245 | 40 |
|
246 | 41 | @SuppressWarnings("unchecked")
|
247 |
| - public static <T> T convertValue(Object rawValue, Option<T> option, boolean flatten) { |
| 42 | + public static <T> T convertValue(Object rawValue, Option<T> option) { |
248 | 43 | TypeReference<T> typeReference = option.typeReference();
|
249 |
| - rawValue = flatten ? flatteningMapWithObject(rawValue) : rawValue; |
250 | 44 | if (typeReference.getType() instanceof Class) {
|
251 | 45 | // simple type
|
252 | 46 | Class<T> clazz = (Class<T>) typeReference.getType();
|
@@ -404,6 +198,9 @@ static <E extends Enum<?>> E convertToEnum(Object o, Class<E> clazz) {
|
404 | 198 | }
|
405 | 199 |
|
406 | 200 | public static String convertToJsonString(Object o) {
|
| 201 | + if (o == null) { |
| 202 | + return null; |
| 203 | + } |
407 | 204 | if (o instanceof String) {
|
408 | 205 | return (String) o;
|
409 | 206 | }
|
|
0 commit comments