1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j.helpers;
19
20 import org.apache.log4j.Level;
21 import org.apache.logging.log4j.LogManager;
22 import org.apache.logging.log4j.Logger;
23 import org.apache.logging.log4j.util.LoaderUtil;
24
25 import java.io.InterruptedIOException;
26 import java.lang.reflect.InvocationTargetException;
27 import java.util.Properties;
28
29
30
31
32 public class OptionConverter {
33
34 static String DELIM_START = "${";
35 static char DELIM_STOP = '}';
36 static int DELIM_START_LEN = 2;
37 static int DELIM_STOP_LEN = 1;
38 private static final Logger LOGGER = LogManager.getLogger(OptionConverter.class);
39 private static final CharMap[] charMap = new CharMap[] {
40 new CharMap('n', '\n'),
41 new CharMap('r', '\r'),
42 new CharMap('t', '\t'),
43 new CharMap('f', '\f'),
44 new CharMap('\b', '\b'),
45 new CharMap('\"', '\"'),
46 new CharMap('\'', '\''),
47 new CharMap('\\', '\\')
48 };
49
50
51
52
53 private OptionConverter() {
54 }
55
56 public static String[] concatanateArrays(String[] l, String[] r) {
57 int len = l.length + r.length;
58 String[] a = new String[len];
59
60 System.arraycopy(l, 0, a, 0, l.length);
61 System.arraycopy(r, 0, a, l.length, r.length);
62
63 return a;
64 }
65
66 public static String convertSpecialChars(String s) {
67 char c;
68 int len = s.length();
69 StringBuilder sbuf = new StringBuilder(len);
70
71 int i = 0;
72 while (i < len) {
73 c = s.charAt(i++);
74 if (c == '\\') {
75 c = s.charAt(i++);
76 for (CharMap entry : charMap) {
77 if (entry.key == c) {
78 c = entry.replacement;
79 }
80 }
81 }
82 sbuf.append(c);
83 }
84 return sbuf.toString();
85 }
86
87
88
89
90
91
92
93
94
95
96
97
98 public static String getSystemProperty(String key, String def) {
99 try {
100 return System.getProperty(key, def);
101 } catch (Throwable e) {
102 LOGGER.debug("Was not allowed to read system property \"{}\".", key);
103 return def;
104 }
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118 public static boolean toBoolean(String value, boolean dEfault) {
119 if (value == null) {
120 return dEfault;
121 }
122 String trimmedVal = value.trim();
123 if ("true".equalsIgnoreCase(trimmedVal)) {
124 return true;
125 }
126 if ("false".equalsIgnoreCase(trimmedVal)) {
127 return false;
128 }
129 return dEfault;
130 }
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156 public static Level toLevel(String value, Level defaultValue) {
157 if (value == null) {
158 return defaultValue;
159 }
160
161 value = value.trim();
162
163 int hashIndex = value.indexOf('#');
164 if (hashIndex == -1) {
165 if ("NULL".equalsIgnoreCase(value)) {
166 return null;
167 } else {
168
169 return Level.toLevel(value, defaultValue);
170 }
171 }
172
173 Level result = defaultValue;
174
175 String clazz = value.substring(hashIndex + 1);
176 String levelName = value.substring(0, hashIndex);
177
178
179 if ("NULL".equalsIgnoreCase(levelName)) {
180 return null;
181 }
182
183 LOGGER.debug("toLevel" + ":class=[" + clazz + "]"
184 + ":pri=[" + levelName + "]");
185
186 try {
187 Class customLevel = LoaderUtil.loadClass(clazz);
188
189
190
191 Class[] paramTypes = new Class[]{String.class,
192 org.apache.log4j.Level.class
193 };
194 java.lang.reflect.Method toLevelMethod =
195 customLevel.getMethod("toLevel", paramTypes);
196
197
198 Object[] params = new Object[]{levelName, defaultValue};
199 Object o = toLevelMethod.invoke(null, params);
200
201 result = (Level) o;
202 } catch (ClassNotFoundException e) {
203 LOGGER.warn("custom level class [" + clazz + "] not found.");
204 } catch (NoSuchMethodException e) {
205 LOGGER.warn("custom level class [" + clazz + "]"
206 + " does not have a class function toLevel(String, Level)", e);
207 } catch (java.lang.reflect.InvocationTargetException e) {
208 if (e.getTargetException() instanceof InterruptedException
209 || e.getTargetException() instanceof InterruptedIOException) {
210 Thread.currentThread().interrupt();
211 }
212 LOGGER.warn("custom level class [" + clazz + "]"
213 + " could not be instantiated", e);
214 } catch (ClassCastException e) {
215 LOGGER.warn("class [" + clazz
216 + "] is not a subclass of org.apache.log4j.Level", e);
217 } catch (IllegalAccessException e) {
218 LOGGER.warn("class [" + clazz +
219 "] cannot be instantiated due to access restrictions", e);
220 } catch (RuntimeException e) {
221 LOGGER.warn("class [" + clazz + "], level [" + levelName +
222 "] conversion failed.", e);
223 }
224 return result;
225 }
226
227
228
229
230
231
232
233
234
235
236
237
238 public static Object instantiateByClassName(String className, Class<?> superClass,
239 Object defaultValue) {
240 if (className != null) {
241 try {
242 Object obj = LoaderUtil.newInstanceOf(className);
243 if (!superClass.isAssignableFrom(obj.getClass())) {
244 LOGGER.error("A \"{}\" object is not assignable to a \"{}\" variable", className,
245 superClass.getName());
246 return defaultValue;
247 }
248 return obj;
249 } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
250 | InstantiationException | InvocationTargetException e) {
251 LOGGER.error("Could not instantiate class [" + className + "].", e);
252 }
253 }
254 return defaultValue;
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
283
284
285
286
287
288
289
290
291
292
293
294
295 public static String substVars(String val, Properties props) throws IllegalArgumentException {
296
297 StringBuilder sbuf = new StringBuilder();
298
299 int i = 0;
300 int j, k;
301
302 while (true) {
303 j = val.indexOf(DELIM_START, i);
304 if (j == -1) {
305
306 if (i == 0) {
307 return val;
308 } else {
309 sbuf.append(val.substring(i, val.length()));
310 return sbuf.toString();
311 }
312 } else {
313 sbuf.append(val.substring(i, j));
314 k = val.indexOf(DELIM_STOP, j);
315 if (k == -1) {
316 throw new IllegalArgumentException('"' + val +
317 "\" has no closing brace. Opening brace at position " + j
318 + '.');
319 } else {
320 j += DELIM_START_LEN;
321 String key = val.substring(j, k);
322
323 String replacement = getSystemProperty(key, null);
324
325 if (replacement == null && props != null) {
326 replacement = props.getProperty(key);
327 }
328
329 if (replacement != null) {
330
331
332
333
334
335 String recursiveReplacement = substVars(replacement, props);
336 sbuf.append(recursiveReplacement);
337 }
338 i = k + DELIM_STOP_LEN;
339 }
340 }
341 }
342 }
343
344 public static org.apache.logging.log4j.Level convertLevel(String level,
345 org.apache.logging.log4j.Level defaultLevel) {
346 Level l = toLevel(level, null);
347 return l != null ? convertLevel(l) : defaultLevel;
348 }
349
350 public static org.apache.logging.log4j.Level convertLevel(Level level) {
351 if (level == null) {
352 return org.apache.logging.log4j.Level.ERROR;
353 }
354 if (level.isGreaterOrEqual(Level.FATAL)) {
355 return org.apache.logging.log4j.Level.FATAL;
356 } else if (level.isGreaterOrEqual(Level.ERROR)) {
357 return org.apache.logging.log4j.Level.ERROR;
358 } else if (level.isGreaterOrEqual(Level.WARN)) {
359 return org.apache.logging.log4j.Level.WARN;
360 } else if (level.isGreaterOrEqual(Level.INFO)) {
361 return org.apache.logging.log4j.Level.INFO;
362 } else if (level.isGreaterOrEqual(Level.DEBUG)) {
363 return org.apache.logging.log4j.Level.DEBUG;
364 } else if (level.isGreaterOrEqual(Level.TRACE)) {
365 return org.apache.logging.log4j.Level.TRACE;
366 }
367 return org.apache.logging.log4j.Level.ALL;
368 }
369
370 public static Level convertLevel(org.apache.logging.log4j.Level level) {
371 if (level == null) {
372 return Level.ERROR;
373 }
374 switch (level.getStandardLevel()) {
375 case FATAL:
376 return Level.FATAL;
377 case WARN:
378 return Level.WARN;
379 case INFO:
380 return Level.INFO;
381 case DEBUG:
382 return Level.DEBUG;
383 case TRACE:
384 return Level.TRACE;
385 case ALL:
386 return Level.ALL;
387 case OFF:
388 return Level.OFF;
389 default:
390 return Level.ERROR;
391 }
392 }
393
394
395
396
397
398
399
400
401
402 public static String findAndSubst(String key, Properties props) {
403 String value = props.getProperty(key);
404 if (value == null) {
405 return null;
406 }
407
408 try {
409 return substVars(value, props);
410 } catch (IllegalArgumentException e) {
411 LOGGER.error("Bad option value [{}].", value, e);
412 return value;
413 }
414 }
415
416 private static class CharMap {
417 final char key;
418 final char replacement;
419
420 public CharMap(char key, char replacement) {
421 this.key = key;
422 this.replacement = replacement;
423 }
424 }
425 }