1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.log4j.config;
21
22 import org.apache.log4j.Appender;
23 import org.apache.log4j.Level;
24 import org.apache.log4j.Priority;
25 import org.apache.log4j.spi.ErrorHandler;
26 import org.apache.log4j.spi.OptionHandler;
27 import org.apache.logging.log4j.Logger;
28 import org.apache.logging.log4j.core.util.OptionConverter;
29 import org.apache.logging.log4j.status.StatusLogger;
30
31 import java.beans.BeanInfo;
32 import java.beans.IntrospectionException;
33 import java.beans.Introspector;
34 import java.beans.PropertyDescriptor;
35 import java.io.InterruptedIOException;
36 import java.lang.reflect.InvocationTargetException;
37 import java.lang.reflect.Method;
38 import java.util.Properties;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public class PropertySetter {
59 private static Logger LOGGER = StatusLogger.getLogger();
60 protected Object obj;
61 protected PropertyDescriptor[] props;
62
63
64
65
66
67
68
69 public PropertySetter(Object obj) {
70 this.obj = obj;
71 }
72
73
74
75
76
77
78
79
80
81
82 public static void setProperties(Object obj, Properties properties, String prefix) {
83 new PropertySetter(obj).setProperties(properties, prefix);
84 }
85
86
87
88
89
90 protected void introspect() {
91 try {
92 BeanInfo bi = Introspector.getBeanInfo(obj.getClass());
93 props = bi.getPropertyDescriptors();
94 } catch (IntrospectionException ex) {
95 LOGGER.error("Failed to introspect {}: {}", obj, ex.getMessage());
96 props = new PropertyDescriptor[0];
97 }
98 }
99
100
101
102
103
104
105
106 public void setProperties(Properties properties, String prefix) {
107 int len = prefix.length();
108
109 for (String key : properties.stringPropertyNames()) {
110
111
112 if (key.startsWith(prefix)) {
113
114
115
116 if (key.indexOf('.', len + 1) > 0) {
117 continue;
118 }
119
120 String value = OptionConverter.findAndSubst(key, properties);
121 key = key.substring(len);
122 if (("layout".equals(key) || "errorhandler".equals(key)) && obj instanceof Appender) {
123 continue;
124 }
125
126
127
128 PropertyDescriptor prop = getPropertyDescriptor(Introspector.decapitalize(key));
129 if (prop != null
130 && OptionHandler.class.isAssignableFrom(prop.getPropertyType())
131 && prop.getWriteMethod() != null) {
132 OptionHandler opt = (OptionHandler)
133 OptionConverter.instantiateByKey(properties, prefix + key,
134 prop.getPropertyType(),
135 null);
136 PropertySetter setter = new PropertySetter(opt);
137 setter.setProperties(properties, prefix + key + ".");
138 try {
139 prop.getWriteMethod().invoke(this.obj, opt);
140 } catch (InvocationTargetException ex) {
141 if (ex.getTargetException() instanceof InterruptedException
142 || ex.getTargetException() instanceof InterruptedIOException) {
143 Thread.currentThread().interrupt();
144 }
145 LOGGER.warn("Failed to set property [{}] to value \"{}\".", key, value, ex);
146 } catch (IllegalAccessException | RuntimeException ex) {
147 LOGGER.warn("Failed to set property [{}] to value \"{}\".", key, value, ex);
148 }
149 continue;
150 }
151
152 setProperty(key, value);
153 }
154 }
155 activate();
156 }
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173 public void setProperty(String name, String value) {
174 if (value == null) {
175 return;
176 }
177
178 name = Introspector.decapitalize(name);
179 PropertyDescriptor prop = getPropertyDescriptor(name);
180
181
182
183 if (prop == null) {
184 LOGGER.warn("No such property [" + name + "] in " +
185 obj.getClass().getName() + ".");
186 } else {
187 try {
188 setProperty(prop, name, value);
189 } catch (PropertySetterException ex) {
190 LOGGER.warn("Failed to set property [{}] to value \"{}\".", name, value, ex.rootCause);
191 }
192 }
193 }
194
195
196
197
198
199
200
201
202
203
204 public void setProperty(PropertyDescriptor prop, String name, String value)
205 throws PropertySetterException {
206 Method setter = prop.getWriteMethod();
207 if (setter == null) {
208 throw new PropertySetterException("No setter for property [" + name + "].");
209 }
210 Class<?>[] paramTypes = setter.getParameterTypes();
211 if (paramTypes.length != 1) {
212 throw new PropertySetterException("#params for setter != 1");
213 }
214
215 Object arg;
216 try {
217 arg = convertArg(value, paramTypes[0]);
218 } catch (Throwable t) {
219 throw new PropertySetterException("Conversion to type [" + paramTypes[0] +
220 "] failed. Reason: " + t);
221 }
222 if (arg == null) {
223 throw new PropertySetterException(
224 "Conversion to type [" + paramTypes[0] + "] failed.");
225 }
226 LOGGER.debug("Setting property [" + name + "] to [" + arg + "].");
227 try {
228 setter.invoke(obj, arg);
229 } catch (InvocationTargetException ex) {
230 if (ex.getTargetException() instanceof InterruptedException
231 || ex.getTargetException() instanceof InterruptedIOException) {
232 Thread.currentThread().interrupt();
233 }
234 throw new PropertySetterException(ex);
235 } catch (IllegalAccessException | RuntimeException ex) {
236 throw new PropertySetterException(ex);
237 }
238 }
239
240
241
242
243
244
245
246
247
248 protected Object convertArg(String val, Class<?> type) {
249 if (val == null) {
250 return null;
251 }
252
253 String v = val.trim();
254 if (String.class.isAssignableFrom(type)) {
255 return val;
256 } else if (Integer.TYPE.isAssignableFrom(type)) {
257 return Integer.parseInt(v);
258 } else if (Long.TYPE.isAssignableFrom(type)) {
259 return Long.parseLong(v);
260 } else if (Boolean.TYPE.isAssignableFrom(type)) {
261 if ("true".equalsIgnoreCase(v)) {
262 return Boolean.TRUE;
263 } else if ("false".equalsIgnoreCase(v)) {
264 return Boolean.FALSE;
265 }
266 } else if (Priority.class.isAssignableFrom(type)) {
267 return org.apache.log4j.helpers.OptionConverter.toLevel(v, Level.DEBUG);
268 } else if (ErrorHandler.class.isAssignableFrom(type)) {
269 return OptionConverter.instantiateByClassName(v,
270 ErrorHandler.class, null);
271 }
272 return null;
273 }
274
275
276 protected PropertyDescriptor getPropertyDescriptor(String name) {
277 if (props == null) {
278 introspect();
279 }
280 for (PropertyDescriptor prop : props) {
281 if (name.equals(prop.getName())) {
282 return prop;
283 }
284 }
285 return null;
286 }
287
288 public void activate() {
289 if (obj instanceof OptionHandler) {
290 ((OptionHandler) obj).activateOptions();
291 }
292 }
293 }