1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package net.sf.aspect4log.text;
18
19 import java.lang.reflect.InvocationTargetException;
20 import java.lang.reflect.Method;
21 import java.util.Collection;
22 import java.util.Iterator;
23 import java.util.Map;
24 import java.util.Map.Entry;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
27
28 import org.apache.commons.beanutils.PropertyUtils;
29 import org.apache.commons.lang3.ArrayUtils;
30
31
32
33
34
35
36 public class LogFormatter {
37
38 private static final String ERROR_EVALUTTING_TO_STRING_SYMBOL = "☣";
39 public static final String ELEMENTS_DELITMETER = ", ";
40 public static final String MAP_KEY_VALUE_DELIMETER = "=";
41 public static final String ARRAY_BEGINS_BRACKET = "[";
42 public static final String ARRAY_ENDS_BRACKET = "]";
43
44 public static final String ITERABLE_BEGINS_BRACKET = "{";
45 public static final String ITERABLE_ENDS_BRACKET = "}";
46
47
48 private String elementsDelitmiter = ELEMENTS_DELITMETER;
49 private String mapKeyValueDelimeter = MAP_KEY_VALUE_DELIMETER;
50 private String arrayBeginsBracket = ARRAY_BEGINS_BRACKET;
51 private String arrayEndsBracket = ARRAY_ENDS_BRACKET;
52
53 private String iterableBeginsBracket = ITERABLE_BEGINS_BRACKET;
54 private String iterableEndsBracket = ITERABLE_ENDS_BRACKET;
55
56
57 private String undefindedToStringMethodSymbol;
58
59
60
61 private String errorEvaluatingToStringSymbol=ERROR_EVALUTTING_TO_STRING_SYMBOL;
62 private String nullSymbol;
63
64 public String getElementsDelitmiter() {
65 return elementsDelitmiter;
66 }
67
68 public void setElementsDelitmiter(String elementsDelitmiter) {
69 this.elementsDelitmiter = elementsDelitmiter;
70 }
71
72 public String getMapKeyValueDelimeter() {
73 return mapKeyValueDelimeter;
74 }
75
76 public void setMapKeyValueDelimeter(String mapKeyValueDelimeter) {
77 this.mapKeyValueDelimeter = mapKeyValueDelimeter;
78 }
79
80 public String getArrayBeginsBracket() {
81 return arrayBeginsBracket;
82 }
83
84 public void setArrayBeginsBracket(String arrayBeginsBracket) {
85 this.arrayBeginsBracket = arrayBeginsBracket;
86 }
87
88 public String getArrayEndsBracket() {
89 return arrayEndsBracket;
90 }
91
92 public void setArrayEndsBracket(String arrayEndsBracket) {
93 this.arrayEndsBracket = arrayEndsBracket;
94 }
95
96 public String getIterableBeginsBracket() {
97 return iterableBeginsBracket;
98 }
99
100 public void setIterableBeginsBracket(String iterableBeginsBracket) {
101 this.iterableBeginsBracket = iterableBeginsBracket;
102 }
103
104 public String getIterableEndsBracket() {
105 return iterableEndsBracket;
106 }
107
108 public void setIterableEndsBracket(String iterableEndsBracket) {
109 this.iterableEndsBracket = iterableEndsBracket;
110 }
111
112 public String getUndefindedToStringMethodSymbol() {
113 return undefindedToStringMethodSymbol;
114 }
115
116 public void setUndefindedToStringMethodSymbol(String undefindedToStringValue) {
117 this.undefindedToStringMethodSymbol = undefindedToStringValue;
118 }
119
120 public String getNullSymbol() {
121 return nullSymbol;
122 }
123
124 public void setNullSymbol(String nullValue) {
125 this.nullSymbol = nullValue;
126 }
127
128 public String getErrorEvaluatingToStringSymbol() {
129 return errorEvaluatingToStringSymbol;
130 }
131
132 public void setErrorEvaluatingToStringSymbol(String errorValue) {
133 this.errorEvaluatingToStringSymbol = errorValue;
134 }
135
136 private static Method OBJECT_EQUALS_METHOD_TMP = null;
137 static {
138 try {
139 OBJECT_EQUALS_METHOD_TMP = Object.class.getMethod("toString");
140 } catch (NoSuchMethodException e) {
141
142 throw new ExceptionInInitializerError(e);
143 } catch (SecurityException e) {
144
145 throw new ExceptionInInitializerError(e);
146 }
147 }
148 private static final Method OBJECT_EQUALS_METHOD = OBJECT_EQUALS_METHOD_TMP;
149
150 public String toString(Map<?, ?> map) {
151 StringBuilder stringBuilder = new StringBuilder();
152 for (Iterator<?> iterator = map.entrySet().iterator(); iterator.hasNext();) {
153 Entry<?, ?> entry = (Entry<?, ?>) iterator.next();
154 toString(stringBuilder, entry.getKey());
155 stringBuilder.append(mapKeyValueDelimeter);
156 toString(stringBuilder, entry.getValue());
157 if (iterator.hasNext()) {
158 stringBuilder.append(elementsDelitmiter);
159 }
160 }
161 return stringBuilder.toString();
162 }
163
164 public String toString(Iterable<?> iterable) {
165
166
167 StringBuilder stringBuilder = new StringBuilder();
168 ;
169 for (Iterator<?> iterator = iterable.iterator(); iterator.hasNext();) {
170 toString(stringBuilder, iterator.next());
171 if (iterator.hasNext()) {
172 stringBuilder.append(elementsDelitmiter);
173 }
174 }
175 return stringBuilder.toString();
176 }
177
178 public String toString(Object[] array) {
179 StringBuilder stringBuilder = new StringBuilder();
180 for (int i = 0; i < array.length; i++) {
181 toString(stringBuilder, array[i]);
182 if (i < array.length - 1) {
183 stringBuilder.append(elementsDelitmiter);
184 }
185 }
186 return stringBuilder.toString();
187 }
188
189 public StringBuilder toString(StringBuilder stringBuilder, Object o) {
190 if (o != null) {
191 if (o instanceof Object[]) {
192 addArrayBrackets(stringBuilder, toString((Object[]) o));
193 } else if (o instanceof boolean[]) {
194 addArrayBrackets(stringBuilder, toString(ArrayUtils.toObject((boolean[]) o)));
195 } else if (o instanceof char[]) {
196 addArrayBrackets(stringBuilder, toString(ArrayUtils.toObject((char[]) o)));
197 } else if (o instanceof byte[]) {
198 addArrayBrackets(stringBuilder, toString(ArrayUtils.toObject((byte[]) o)));
199 } else if (o instanceof short[]) {
200 addArrayBrackets(stringBuilder, toString(ArrayUtils.toObject((short[]) o)));
201 } else if (o instanceof int[]) {
202 addArrayBrackets(stringBuilder, toString(ArrayUtils.toObject((int[]) o)));
203 } else if (o instanceof long[]) {
204 addArrayBrackets(stringBuilder, toString(ArrayUtils.toObject((long[]) o)));
205 } else if (o instanceof float[]) {
206 addArrayBrackets(stringBuilder, toString(ArrayUtils.toObject((float[]) o)));
207 } else if (o instanceof double[]) {
208 addArrayBrackets(stringBuilder, toString(ArrayUtils.toObject((double[]) o)));
209 } else if (o instanceof Map<?, ?>) {
210 addIterrableBrackets(stringBuilder, toString((Map<?, ?>) o));
211 } else if (o instanceof Collection<?>) {
212 addIterrableBrackets(stringBuilder, toString(((Iterable<?>) o)));
213 } else {
214 if (undefindedToStringMethodSymbol==null || isToStringOverriden(o.getClass()) ) {
215 try{
216 stringBuilder.append(o);
217 }catch(RuntimeException e){
218 addExceptionOnToStringEvaluation(stringBuilder,e.toString());
219 }
220 } else {
221 stringBuilder.append(undefindedToStringMethodSymbol);
222 }
223 }
224 } else {
225 stringBuilder.append(nullSymbol);
226 }
227 return stringBuilder;
228 }
229
230 private void addBrackets(StringBuilder stringBuilder, String beginBracket, String string, String endBracket) {
231 stringBuilder.append(beginBracket);
232 stringBuilder.append(string);
233 stringBuilder.append(endBracket);
234 }
235
236 private void addArrayBrackets(StringBuilder stringBuilder, String string) {
237 addBrackets(stringBuilder, arrayBeginsBracket, string, arrayEndsBracket);
238 }
239
240 private void addIterrableBrackets(StringBuilder stringBuilder, String string) {
241 addBrackets(stringBuilder, iterableBeginsBracket, string, iterableEndsBracket);
242 }
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262 public boolean isToStringOverriden(Class<?> clazz) {
263 try {
264 return !OBJECT_EQUALS_METHOD.equals(clazz.getMethod("toString"));
265 } catch (NoSuchMethodException e) {
266
267 return false;
268 } catch (SecurityException e) {
269
270 return false;
271 }
272 }
273
274
275
276 private static final Pattern VARIABLE_SEARCH_PATTERN = Pattern.compile("(?!\\$\\{\\$\\{)\\$\\{(.*?)\\}");
277
278 public String toString(String template, Object object) {
279 if (template.isEmpty()) {
280 return "";
281 }
282 Matcher matcher = VARIABLE_SEARCH_PATTERN.matcher(template);
283 StringBuilder stringBuilder = new StringBuilder(template);
284 int shift = 0;
285 EnclosingBean bean = new EnclosingBean(object);
286 while (matcher.find()) {
287 String property = matcher.group(1);
288 String replacement = toString(bean, property);
289 int start = matcher.start();
290 int end = matcher.end();
291 stringBuilder.replace(start + shift, end + shift, replacement);
292 shift = shift + replacement.length() - end + start;
293 }
294 return stringBuilder.toString();
295 }
296
297 private String toString(Object bean, String property) {
298 StringBuilder stringBuilder = new StringBuilder();
299 try {
300 toString(stringBuilder, PropertyUtils.getProperty(bean, property));
301 } catch (IllegalAccessException e) {
302 addExceptionOnToStringEvaluation(stringBuilder, e.getCause().toString());
303 } catch (InvocationTargetException e) {
304 addExceptionOnToStringEvaluation(stringBuilder, e.getCause().toString());
305 } catch (NoSuchMethodException e) {
306 addExceptionOnToStringEvaluation(stringBuilder, e.getCause().toString());
307 } catch(Exception e){
308 addExceptionOnToStringEvaluation(stringBuilder, "#Warning!!! Template caused: " + e + " #");
309 }
310 return stringBuilder.toString();
311
312 }
313
314 private void addExceptionOnToStringEvaluation(StringBuilder stringBuilder, String errorMessage) {
315 if(errorEvaluatingToStringSymbol==null){
316 stringBuilder.append(errorMessage);
317 }else{
318 stringBuilder.append(errorEvaluatingToStringSymbol);
319 }
320 }
321
322 public static class EnclosingBean {
323 private Object object;
324
325 public EnclosingBean(Object object) {
326 this.object = object;
327 }
328
329 public EnclosingBean() {
330 }
331
332 public Object getArgs() {
333 return object;
334 }
335
336 public Object getResult() {
337 return object;
338 }
339
340 public Object getException() {
341 return object;
342 }
343 }
344
345 }