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