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