1 package org.yajul.util;
2
3
4 import org.slf4j.Logger;
5 import org.slf4j.LoggerFactory;
6
7 import java.lang.reflect.Field;
8 import java.lang.reflect.InvocationTargetException;
9 import java.lang.reflect.Method;
10 import java.text.DateFormat;
11 import java.text.SimpleDateFormat;
12 import java.util.TimeZone;
13
14 /***
15 * Prints the fields of an object into a string buffer.
16 * <br>
17 * User: jdavis
18 * Date: Oct 21, 2003
19 * Time: 7:46:24 PM
20 *
21 * @author jdavis
22 */
23 public class FieldPrinter {
24 /***
25 * The logger for this class.
26 */
27 private static Logger log = LoggerFactory.getLogger(FieldPrinter.class);
28
29 private static Class[] NO_PARAMETERS = new Class[0];
30 private static Object[] NO_ARGUMENTS = new Object[0];
31
32 private StringBuilder sb;
33 private DateFormat df;
34
35 public FieldPrinter() {
36 this(new StringBuilder());
37 }
38
39 /***
40 * Creates a new object field printer, that will append
41 * to the supplied string builder.
42 *
43 * @param sb The StringBuilder to append to.
44 */
45 public FieldPrinter(StringBuilder sb) {
46 this.sb = sb;
47 df = new SimpleDateFormat("yyyyMMMdd HH:mm:ss zz");
48 df.setTimeZone(TimeZone.getDefault());
49 }
50
51 /***
52 * Appends all of the fields of the object to the string buffer.
53 *
54 * @param o - The object to print.
55 */
56 public void append(Object o) {
57 if (o == null) {
58 sb.append("null");
59 return;
60 }
61
62
63 Class c = o.getClass();
64 sb.append(c.getName());
65 sb.append("[");
66
67 Field[] fields = c.getFields();
68 Method[] methods = c.getMethods();
69
70
71 boolean usingFields = true;
72 int length = fields.length;
73
74
75 if (length == 0) {
76 length = methods.length;
77 usingFields = false;
78 }
79
80
81 int validMethodCount = 0;
82
83 boolean validAttribute;
84
85
86 for (int i = 0; i < length; i++) {
87 Class attributeType = null;
88 Object attributeValue = null;
89
90 try {
91
92 if (usingFields) {
93
94 validAttribute = true;
95 if (i > 0)
96 sb.append(", ");
97 sb.append(fields[i].getName());
98 sb.append("=");
99
100 attributeType = fields[i].getType();
101 attributeValue = fields[i].get(o);
102 }
103
104 else {
105
106 validAttribute = false;
107
108 if (ReflectionUtil.isPropertyGetter(methods[i])) {
109 validAttribute = true;
110 if (validMethodCount > 0)
111 sb.append(", ");
112 validMethodCount++;
113 sb.append(methods[i].getName());
114 sb.append("=");
115
116 attributeType = methods[i].getReturnType();
117 attributeValue = methods[i].invoke(o);
118 }
119 }
120
121
122 if (validAttribute) {
123 appendField(attributeValue, attributeType);
124 }
125 }
126 catch (IllegalAccessException e) {
127 log.warn("Unexpected: " + e.getMessage(), e);
128 sb.append("<error!>");
129 }
130 catch (InvocationTargetException e) {
131 log.warn("Unexpected: " + e.getMessage(), e);
132 sb.append("<error!>");
133 }
134 }
135 sb.append("]");
136 }
137
138 public static String toString(Object o) {
139 FieldPrinter fp = new FieldPrinter();
140 fp.append(o);
141 return fp.toString();
142 }
143
144 public String toString() {
145 return sb.toString();
146 }
147
148 private void appendField(Object attributeValue, Class attributeType) throws IllegalAccessException {
149
150 if (attributeValue == null)
151 sb.append("null");
152
153 else if (attributeType.isPrimitive() || Number.class.isAssignableFrom(attributeType))
154 sb.append(attributeValue);
155
156 else if (java.util.Date.class.isAssignableFrom(attributeType))
157 sb.append(df.format((java.util.Date) attributeValue));
158
159 else if (String.class.isAssignableFrom(attributeType))
160 appendValue(attributeValue, "'", "'", sb);
161
162 else if (attributeType.isArray())
163 appendValue(attributeValue, "{", "}", sb);
164
165 else
166 appendNestedObject(attributeType, attributeValue);
167 }
168
169 private void appendNestedObject(Class attributeType, Object attributeValue) throws IllegalAccessException {
170 String stringValue = null;
171
172 Method m = null;
173
174 try {
175 m = attributeType.getDeclaredMethod("toString", NO_PARAMETERS);
176 }
177 catch (NoSuchMethodException ignore) {
178 }
179 if (m != null) {
180 try {
181 stringValue = (String) m.invoke(attributeValue, NO_ARGUMENTS);
182 }
183 catch (InvocationTargetException ite) {
184 log.warn("Unexpected: " + ite.getMessage(), ite);
185 stringValue = null;
186 }
187 }
188 if (stringValue != null)
189 appendValue(stringValue, "#", "#", sb);
190
191 else {
192 sb.append("|");
193 append(attributeValue);
194 sb.append("|");
195 }
196 }
197
198 private static void appendValue(Object fieldValue, String startDelim, String endDelim, StringBuilder sb) {
199 sb.append(startDelim);
200 sb.append(fieldValue);
201 sb.append(endDelim);
202 }
203 }
204