1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package com.tomgibara.pronto.util;
19
20 import java.lang.reflect.InvocationTargetException;
21 import java.lang.reflect.Method;
22 import java.util.Arrays;
23
24 /**
25 * A collection of static utility methods which help with the methods declared
26 * by the Object class.
27 *
28 * @author Tom Gibara
29 */
30
31 public final class Objects {
32
33 /**
34 * Tests whether two objects, both of which may be null, are equal. If both
35 * arguments are null, the result is true. If one argument is null the
36 * result is false. If neither argument is null then the equals method on
37 * the first argument is used to determine equality.
38 *
39 * @param a
40 * the first object to be tested for equality
41 * @param b
42 * the second object to be tested for equality
43 * @return true if the objects are equal, false otherwise
44 */
45
46 public static boolean equal(final Object a, final Object b) {
47 if (a == b) return true;
48 if (a == null) return false;
49 if (b == null) return false;
50 return a.equals(b);
51 }
52
53 /**
54 * Tests whether two objects, both of which may be null, are equal. If both
55 * arguments are null, the result is false. If one argument is null the
56 * result is true. If neither argument is null then the equals method on the
57 * first argument is used to determine inequality.
58 *
59 * @param a
60 * the first object to be tested for inequality
61 * @param b
62 * the second object to be tested for inequality
63 * @return true if the objects are unequal, false otherwise
64 */
65
66 public static boolean notEqual(final Object a, final Object b) {
67 if (a == b) return false;
68 if (a == null) return true;
69 if (b == null) return true;
70 return !a.equals(b);
71 }
72
73 /**
74 * The hash code of the object or zero for null.
75 *
76 * @param object
77 * any object, or null
78 * @return the hashcode of the object or zero for null
79 */
80
81 public static int hashCode(final Object object) {
82 return object == null ? 0 : object.hashCode();
83 }
84
85 /**
86 * The object as a string (using toString) or null if the supplied object is
87 * null.
88 *
89 * @param object
90 * any object, or null
91 * @return the String representation of the object or null
92 */
93
94 public static String toString(final Object object) {
95 return object == null ? null : object.toString();
96 }
97
98 /**
99 * <p>
100 * Attempts to provide a meaningful string representation of any object by
101 * reflecting on the available getter methods. The string representation
102 * includes the class of the value and the names and values of properties.
103 * </p>
104 *
105 * <p>
106 * This method is not efficient and should not be used in instances where
107 * speed of execution is important. It is intended to provide a convenient
108 * way of adding a toString() method to simple POJOs.
109 * </p>
110 *
111 * <p>
112 * The string "null" is returned if null is supplied to the method.
113 * </p>
114 *
115 * @param object
116 * any object or null
117 * @return a string representation of the object.
118 */
119
120
121 public static String autoToString(final Object object) {
122 if (object == null) return "null";
123 Class clss = object.getClass();
124 Method[] getters = Reflect.getters(clss.getMethods());
125 StringBuilder sb = new StringBuilder();
126 sb.append('[').append(clss.getName()).append(' ');
127 Object[] noArgs = new Object[0];
128 for (int i = 0; i < getters.length; i++) {
129 if (i != 0) sb.append(", ");
130 Method method = getters[i];
131 sb.append(Reflect.propertyName(method.getName())).append('=');
132 Object value;
133 try {
134 value = method.invoke(object, noArgs);
135 if (value != null && value.getClass().isArray()) {
136 Class type = value.getClass().getComponentType();
137 if (type.isPrimitive()) {
138 if (type == boolean.class) value = Arrays.toString((boolean[]) value);
139 else if (type == byte.class) value = Arrays.toString((byte[]) value);
140 else if (type == char.class) value = Arrays.toString((char[]) value);
141 else if (type == double.class) value = Arrays.toString((double[]) value);
142 else if (type == float.class) value = Arrays.toString((float[]) value);
143 else if (type == int.class) value = Arrays.toString((int[]) value);
144 else if (type == long.class) value = Arrays.toString((long[]) value);
145 else if (type == short.class) value = Arrays.toString((short[]) value);
146 else { throw new IllegalStateException("Unknown primitive array"); }
147 } else {
148
149
150 value = Arrays.toString((Object[]) value);
151 }
152 }
153 } catch (IllegalArgumentException e) {
154 e.printStackTrace();
155 value = e.getMessage();
156 } catch (IllegalAccessException e) {
157 e.printStackTrace();
158 value = e.getMessage();
159 } catch (InvocationTargetException e) {
160 e.printStackTrace();
161 value = e.getMessage();
162 }
163 sb.append(value);
164 }
165 sb.append(']');
166 return sb.toString();
167 }
168
169 private Objects() { }
170
171 }