1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.util;
18
19 import java.util.Locale;
20 import java.util.Properties;
21
22 import org.apache.logging.log4j.Logger;
23 import org.apache.logging.log4j.status.StatusLogger;
24 import org.apache.logging.log4j.util.PropertiesUtil;
25
26
27
28
29 public final class OptionConverter {
30
31 private static final Logger LOGGER = StatusLogger.getLogger();
32
33 private static final String DELIM_START = "${";
34 private static final char DELIM_STOP = '}';
35 private static final int DELIM_START_LEN = 2;
36 private static final int DELIM_STOP_LEN = 1;
37 private static final int ONE_K = 1024;
38
39
40
41
42 private OptionConverter() {
43 }
44
45 public static String[] concatenateArrays(final String[] l, final String[] r) {
46 final int len = l.length + r.length;
47 final String[] a = new String[len];
48
49 System.arraycopy(l, 0, a, 0, l.length);
50 System.arraycopy(r, 0, a, l.length, r.length);
51
52 return a;
53 }
54
55 public static String convertSpecialChars(final String s) {
56 char c;
57 final int len = s.length();
58 final StringBuilder sbuf = new StringBuilder(len);
59
60 int i = 0;
61 while (i < len) {
62 c = s.charAt(i++);
63 if (c == '\\') {
64 c = s.charAt(i++);
65 switch (c) {
66 case 'n':
67 c = '\n';
68 break;
69 case 'r':
70 c = '\r';
71 break;
72 case 't':
73 c = '\t';
74 break;
75 case 'f':
76 c = '\f';
77 break;
78 case 'b':
79 c = '\b';
80 break;
81 case '"':
82 c = '\"';
83 break;
84 case '\'':
85 c = '\'';
86 break;
87 case '\\':
88 c = '\\';
89 break;
90 default:
91
92 }
93 }
94 sbuf.append(c);
95 }
96 return sbuf.toString();
97 }
98
99 public static Object instantiateByKey(final Properties props, final String key, final Class<?> superClass,
100 final Object defaultValue) {
101
102
103 final String className = findAndSubst(key, props);
104 if (className == null) {
105 LOGGER.error("Could not find value for key {}", key);
106 return defaultValue;
107 }
108
109 return OptionConverter.instantiateByClassName(className.trim(), superClass,
110 defaultValue);
111 }
112
113
114
115
116
117
118
119
120
121
122
123
124 public static boolean toBoolean(final String value, final boolean defaultValue) {
125 if (value == null) {
126 return defaultValue;
127 }
128 final String trimmedVal = value.trim();
129 if ("true".equalsIgnoreCase(trimmedVal)) {
130 return true;
131 }
132 if ("false".equalsIgnoreCase(trimmedVal)) {
133 return false;
134 }
135 return defaultValue;
136 }
137
138
139
140
141
142
143
144 public static int toInt(final String value, final int defaultValue) {
145 if (value != null) {
146 final String s = value.trim();
147 try {
148 return Integer.parseInt(s);
149 } catch (final NumberFormatException e) {
150 LOGGER.error("[{}] is not in proper int form.", s, e);
151 }
152 }
153 return defaultValue;
154 }
155
156
157
158
159
160
161
162 public static long toFileSize(final String value, final long defaultValue) {
163 if (value == null) {
164 return defaultValue;
165 }
166
167 String str = value.trim().toUpperCase(Locale.ENGLISH);
168 long multiplier = 1;
169 int index;
170
171 if ((index = str.indexOf("KB")) != -1) {
172 multiplier = ONE_K;
173 str = str.substring(0, index);
174 } else if ((index = str.indexOf("MB")) != -1) {
175 multiplier = ONE_K * ONE_K;
176 str = str.substring(0, index);
177 } else if ((index = str.indexOf("GB")) != -1) {
178 multiplier = ONE_K * ONE_K * ONE_K;
179 str = str.substring(0, index);
180 }
181 if (str != null) {
182 try {
183 return Long.parseLong(str) * multiplier;
184 } catch (final NumberFormatException e) {
185 LOGGER.error("[{}] is not in proper int form.", str);
186 LOGGER.error("[{}] not in expected format.", value, e);
187 }
188 }
189 return defaultValue;
190 }
191
192
193
194
195
196
197
198
199
200 public static String findAndSubst(final String key, final Properties props) {
201 final String value = props.getProperty(key);
202 if (value == null) {
203 return null;
204 }
205
206 try {
207 return substVars(value, props);
208 } catch (final IllegalArgumentException e) {
209 LOGGER.error("Bad option value [{}].", value, e);
210 return value;
211 }
212 }
213
214
215
216
217
218
219
220
221
222
223
224
225 public static Object instantiateByClassName(final String className, final Class<?> superClass,
226 final Object defaultValue) {
227 if (className != null) {
228 try {
229 final Class<?> classObj = Loader.loadClass(className);
230 if (!superClass.isAssignableFrom(classObj)) {
231 LOGGER.error("A \"{}\" object is not assignable to a \"{}\" variable.", className,
232 superClass.getName());
233 LOGGER.error("The class \"{}\" was loaded by [{}] whereas object of type [{}] was loaded by [{}].",
234 superClass.getName(), superClass.getClassLoader(), classObj.getName());
235 return defaultValue;
236 }
237 return classObj.newInstance();
238 } catch (final Exception e) {
239 LOGGER.error("Could not instantiate class [{}].", className, e);
240 }
241 }
242 return defaultValue;
243 }
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282 public static String substVars(final String val, final Properties props) throws
283 IllegalArgumentException {
284
285 final StringBuilder sbuf = new StringBuilder();
286
287 int i = 0;
288 int j;
289 int k;
290
291 while (true) {
292 j = val.indexOf(DELIM_START, i);
293 if (j == -1) {
294
295 if (i == 0) {
296 return val;
297 }
298
299 sbuf.append(val.substring(i, val.length()));
300 return sbuf.toString();
301 }
302 sbuf.append(val.substring(i, j));
303 k = val.indexOf(DELIM_STOP, j);
304 if (k == -1) {
305 throw new IllegalArgumentException('"' + val +
306 "\" has no closing brace. Opening brace at position " + j
307 + '.');
308 }
309 j += DELIM_START_LEN;
310 final String key = val.substring(j, k);
311
312 String replacement = PropertiesUtil.getProperties().getStringProperty(key, null);
313
314 if (replacement == null && props != null) {
315 replacement = props.getProperty(key);
316 }
317
318 if (replacement != null) {
319
320
321
322
323
324 final String recursiveReplacement = substVars(replacement, props);
325 sbuf.append(recursiveReplacement);
326 }
327 i = k + DELIM_STOP_LEN;
328 }
329 }
330 }