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 try {
182 return Long.parseLong(str) * multiplier;
183 } catch (final NumberFormatException e) {
184 LOGGER.error("[{}] is not in proper int form.", str);
185 LOGGER.error("[{}] not in expected format.", value, e);
186 }
187 return defaultValue;
188 }
189
190
191
192
193
194
195
196
197
198 public static String findAndSubst(final String key, final Properties props) {
199 final String value = props.getProperty(key);
200 if (value == null) {
201 return null;
202 }
203
204 try {
205 return substVars(value, props);
206 } catch (final IllegalArgumentException e) {
207 LOGGER.error("Bad option value [{}].", value, e);
208 return value;
209 }
210 }
211
212
213
214
215
216
217
218
219
220
221
222
223 public static Object instantiateByClassName(final String className, final Class<?> superClass,
224 final Object defaultValue) {
225 if (className != null) {
226 try {
227 final Class<?> classObj = Loader.loadClass(className);
228 if (!superClass.isAssignableFrom(classObj)) {
229 LOGGER.error("A \"{}\" object is not assignable to a \"{}\" variable.", className,
230 superClass.getName());
231 LOGGER.error("The class \"{}\" was loaded by [{}] whereas object of type [{}] was loaded by [{}].",
232 superClass.getName(), superClass.getClassLoader(), classObj.getName());
233 return defaultValue;
234 }
235 return classObj.newInstance();
236 } catch (final Exception e) {
237 LOGGER.error("Could not instantiate class [{}].", className, e);
238 }
239 }
240 return defaultValue;
241 }
242
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 public static String substVars(final String val, final Properties props) throws
281 IllegalArgumentException {
282
283 final StringBuilder sbuf = new StringBuilder();
284
285 int i = 0;
286 int j;
287 int k;
288
289 while (true) {
290 j = val.indexOf(DELIM_START, i);
291 if (j == -1) {
292
293 if (i == 0) {
294 return val;
295 }
296
297 sbuf.append(val.substring(i, val.length()));
298 return sbuf.toString();
299 }
300 sbuf.append(val.substring(i, j));
301 k = val.indexOf(DELIM_STOP, j);
302 if (k == -1) {
303 throw new IllegalArgumentException('"' + val +
304 "\" has no closing brace. Opening brace at position " + j
305 + '.');
306 }
307 j += DELIM_START_LEN;
308 final String key = val.substring(j, k);
309
310 String replacement = PropertiesUtil.getProperties().getStringProperty(key, null);
311
312 if (replacement == null && props != null) {
313 replacement = props.getProperty(key);
314 }
315
316 if (replacement != null) {
317
318
319
320
321
322 final String recursiveReplacement = substVars(replacement, props);
323 sbuf.append(recursiveReplacement);
324 }
325 i = k + DELIM_STOP_LEN;
326 }
327 }
328 }