1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.composite.util;
17
18 import java.lang.reflect.Array;
19 import java.util.ArrayList;
20 import java.util.Calendar;
21 import java.util.Collection;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Stack;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 /***
30 * @author Matt Sgarlata
31 * @since Mar 11, 2005
32 */
33 public class ObjectUtils {
34
35 private static final Log log = LogFactory.getLog(ObjectUtils.class);
36
37 private static ThreadLocal objectsBeingDescribed = new ThreadLocal() {
38 protected Object initialValue() {
39 return new IdentityStack();
40 }
41 };
42
43 public static String getObjectDescription(Object object) {
44 if (object == null) {
45 return "null";
46 }
47
48 try {
49
50
51 if (object instanceof Calendar) {
52 return ((Calendar) object).getTime().toString() + " (class " + object.getClass() + ")";
53 }
54 if (object instanceof Class && ((Class) object).isArray()) {
55 return "(array of " + getObjectDescription(ClassUtils.getContainedClass((Class) object)) + ")";
56 }
57 if (object instanceof Class) {
58 return "(" + object.toString() + ")";
59 }
60 if (object.getClass().isArray()) {
61 return getArrayDescription(object)
62 + " "
63 + getObjectDescription(object.getClass());
64 }
65
66 Stack stack = (Stack) objectsBeingDescribed.get();
67 if (stack.contains(object)) {
68
69 return getDelimiter(object) + "Nested" + object.getClass().getName();
70 }
71
72 stack.push(object);
73 String result;
74 try {
75 result = getDelimiter(object) + object + getDelimiter(object) + " (class " + object.getClass().getName() + ")";
76 } finally {
77 if (object != stack.pop()) {
78 throw new IllegalStateException("Unexpected " + object.getClass().getName());
79 }
80 }
81 return result;
82 }
83 catch (Throwable t) {
84
85 String message = "Could not construct String representation of instance of '"
86 + object.getClass().getName() + "'";
87 if (log.isErrorEnabled()) {
88 log.error(message, t);
89 }
90 return "[ERROR: " + message + "'. Exception message was '"
91 + t.getMessage() + "']";
92 }
93 }
94
95 private static String getArrayDescription(Object array) {
96 List toJoin = new ArrayList();
97 for (int i=0; i<Array.getLength(array); i++) {
98 Object value = Array.get(array, i);
99 if (value != null && value.getClass().isArray()) {
100 toJoin.add(getArrayDescription(value));
101 }
102 else {
103 toJoin.add(value);
104 }
105 }
106 return "[" + StringUtils.join(toJoin, ", ") + "]";
107 }
108
109 private static String getDelimiter(Object object) {
110 return object instanceof Character ? "'" : object instanceof String ? "\"" : "";
111 }
112
113 public static boolean isEmpty(Object object) {
114 return object == null || "".equals(object)
115 || object.getClass().isArray() && Array.getLength(object) == 0
116 || object instanceof Collection && ((Collection) object).isEmpty()
117 || object instanceof Map && ((Map) object).isEmpty()
118 || object instanceof StringBuffer && ((StringBuffer) object).length() == 0;
119 }
120
121 /***
122 * Compares two objects for equality. This method is safe to use when
123 * dealing with the standard Java notion of equality that involves only
124 * {@link Object#equals(java.lang.Object)}.
125 *
126 * @param object1 the first object
127 * @param object2 the second object
128 * @return <code>true</code> if (A) <code>object1</code> and
129 * <code>object2</code> are both <code>null</code> or (B)
130 * <code>object1</code> and <code>object2</code> are both are
131 * both non- <code>null</code> and equal to each other as defined
132 * by {@link Object#equals(java.lang.Object)} or (C) the objects are
133 * <code>BigDecimal</code> s that contain identical values or <br>
134 * <code>false</code>, otherwise
135 */
136 public static boolean equals(Object object1, Object object2) {
137 return object1 == object2 || (object1 != null && object1.equals(object2));
138 }
139
140 }