001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.lang;
018:
019: import java.io.Serializable;
020:
021: /**
022: * <p>Operations on <code>Object</code>.</p>
023: *
024: * <p>This class tries to handle <code>null</code> input gracefully.
025: * An exception will generally not be thrown for a <code>null</code> input.
026: * Each method documents its behaviour in more detail.</p>
027: *
028: * @author <a href="mailto:nissim@nksystems.com">Nissim Karpenstein</a>
029: * @author <a href="mailto:janekdb@yahoo.co.uk">Janek Bogucki</a>
030: * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
031: * @author Stephen Colebourne
032: * @author Gary Gregory
033: * @author Mario Winterer
034: * @author <a href="mailto:david@davidkarlsen.com">David J. M. Karlsen</a>
035: * @since 1.0
036: * @version $Id: ObjectUtils.java 491050 2006-12-29 17:04:00Z scolebourne $
037: */
038: public class ObjectUtils {
039:
040: /**
041: * <p>Singleton used as a <code>null</code> placeholder where
042: * <code>null</code> has another meaning.</p>
043: *
044: * <p>For example, in a <code>HashMap</code> the
045: * {@link java.util.HashMap#get(java.lang.Object)} method returns
046: * <code>null</code> if the <code>Map</code> contains
047: * <code>null</code> or if there is no matching key. The
048: * <code>Null</code> placeholder can be used to distinguish between
049: * these two cases.</p>
050: *
051: * <p>Another example is <code>Hashtable</code>, where <code>null</code>
052: * cannot be stored.</p>
053: *
054: * <p>This instance is Serializable.</p>
055: */
056: public static final Null NULL = new Null();
057:
058: /**
059: * <p><code>ObjectUtils</code> instances should NOT be constructed in
060: * standard programming. Instead, the class should be used as
061: * <code>ObjectUtils.defaultIfNull("a","b");</code>.</p>
062: *
063: * <p>This constructor is public to permit tools that require a JavaBean instance
064: * to operate.</p>
065: */
066: public ObjectUtils() {
067: super ();
068: }
069:
070: // Defaulting
071: //-----------------------------------------------------------------------
072: /**
073: * <p>Returns a default value if the object passed is
074: * <code>null</code>.</p>
075: *
076: * <pre>
077: * ObjectUtils.defaultIfNull(null, null) = null
078: * ObjectUtils.defaultIfNull(null, "") = ""
079: * ObjectUtils.defaultIfNull(null, "zz") = "zz"
080: * ObjectUtils.defaultIfNull("abc", *) = "abc"
081: * ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
082: * </pre>
083: *
084: * @param object the <code>Object</code> to test, may be <code>null</code>
085: * @param defaultValue the default value to return, may be <code>null</code>
086: * @return <code>object</code> if it is not <code>null</code>, defaultValue otherwise
087: */
088: public static Object defaultIfNull(Object object,
089: Object defaultValue) {
090: return object != null ? object : defaultValue;
091: }
092:
093: /**
094: * <p>Compares two objects for equality, where either one or both
095: * objects may be <code>null</code>.</p>
096: *
097: * <pre>
098: * ObjectUtils.equals(null, null) = true
099: * ObjectUtils.equals(null, "") = false
100: * ObjectUtils.equals("", null) = false
101: * ObjectUtils.equals("", "") = true
102: * ObjectUtils.equals(Boolean.TRUE, null) = false
103: * ObjectUtils.equals(Boolean.TRUE, "true") = false
104: * ObjectUtils.equals(Boolean.TRUE, Boolean.TRUE) = true
105: * ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false
106: * </pre>
107: *
108: * @param object1 the first object, may be <code>null</code>
109: * @param object2 the second object, may be <code>null</code>
110: * @return <code>true</code> if the values of both objects are the same
111: */
112: public static boolean equals(Object object1, Object object2) {
113: if (object1 == object2) {
114: return true;
115: }
116: if ((object1 == null) || (object2 == null)) {
117: return false;
118: }
119: return object1.equals(object2);
120: }
121:
122: /**
123: * <p>Gets the hash code of an object returning zero when the
124: * object is <code>null</code>.</p>
125: *
126: * <pre>
127: * ObjectUtils.hashCode(null) = 0
128: * ObjectUtils.hashCode(obj) = obj.hashCode()
129: * </pre>
130: *
131: * @param obj the object to obtain the hash code of, may be <code>null</code>
132: * @return the hash code of the object, or zero if null
133: * @since 2.1
134: */
135: public static int hashCode(Object obj) {
136: return (obj == null) ? 0 : obj.hashCode();
137: }
138:
139: // Identity ToString
140: //-----------------------------------------------------------------------
141: /**
142: * <p>Gets the toString that would be produced by <code>Object</code>
143: * if a class did not override toString itself. <code>null</code>
144: * will return <code>null</code>.</p>
145: *
146: * <pre>
147: * ObjectUtils.identityToString(null) = null
148: * ObjectUtils.identityToString("") = "java.lang.String@1e23"
149: * ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
150: * </pre>
151: *
152: * @param object the object to create a toString for, may be
153: * <code>null</code>
154: * @return the default toString text, or <code>null</code> if
155: * <code>null</code> passed in
156: */
157: public static String identityToString(Object object) {
158: if (object == null) {
159: return null;
160: }
161: return appendIdentityToString(null, object).toString();
162: }
163:
164: /**
165: * <p>Appends the toString that would be produced by <code>Object</code>
166: * if a class did not override toString itself. <code>null</code>
167: * will return <code>null</code>.</p>
168: *
169: * <pre>
170: * ObjectUtils.appendIdentityToString(*, null) = null
171: * ObjectUtils.appendIdentityToString(null, "") = "java.lang.String@1e23"
172: * ObjectUtils.appendIdentityToString(null, Boolean.TRUE) = "java.lang.Boolean@7fa"
173: * ObjectUtils.appendIdentityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa")
174: * </pre>
175: *
176: * @param buffer the buffer to append to, may be <code>null</code>
177: * @param object the object to create a toString for, may be <code>null</code>
178: * @return the default toString text, or <code>null</code> if
179: * <code>null</code> passed in
180: * @since 2.0
181: */
182: public static StringBuffer appendIdentityToString(
183: StringBuffer buffer, Object object) {
184: if (object == null) {
185: return null;
186: }
187: if (buffer == null) {
188: buffer = new StringBuffer();
189: }
190: return buffer.append(object.getClass().getName()).append('@')
191: .append(
192: Integer.toHexString(System
193: .identityHashCode(object)));
194: }
195:
196: // ToString
197: //-----------------------------------------------------------------------
198: /**
199: * <p>Gets the <code>toString</code> of an <code>Object</code> returning
200: * an empty string ("") if <code>null</code> input.</p>
201: *
202: * <pre>
203: * ObjectUtils.toString(null) = ""
204: * ObjectUtils.toString("") = ""
205: * ObjectUtils.toString("bat") = "bat"
206: * ObjectUtils.toString(Boolean.TRUE) = "true"
207: * </pre>
208: *
209: * @see StringUtils#defaultString(String)
210: * @see String#valueOf(Object)
211: * @param obj the Object to <code>toString</code>, may be null
212: * @return the passed in Object's toString, or nullStr if <code>null</code> input
213: * @since 2.0
214: */
215: public static String toString(Object obj) {
216: return obj == null ? "" : obj.toString();
217: }
218:
219: /**
220: * <p>Gets the <code>toString</code> of an <code>Object</code> returning
221: * a specified text if <code>null</code> input.</p>
222: *
223: * <pre>
224: * ObjectUtils.toString(null, null) = null
225: * ObjectUtils.toString(null, "null") = "null"
226: * ObjectUtils.toString("", "null") = ""
227: * ObjectUtils.toString("bat", "null") = "bat"
228: * ObjectUtils.toString(Boolean.TRUE, "null") = "true"
229: * </pre>
230: *
231: * @see StringUtils#defaultString(String,String)
232: * @see String#valueOf(Object)
233: * @param obj the Object to <code>toString</code>, may be null
234: * @param nullStr the String to return if <code>null</code> input, may be null
235: * @return the passed in Object's toString, or nullStr if <code>null</code> input
236: * @since 2.0
237: */
238: public static String toString(Object obj, String nullStr) {
239: return obj == null ? nullStr : obj.toString();
240: }
241:
242: // Min/Max
243: //-----------------------------------------------------------------------
244: /**
245: * Null safe comparison of Comparables.
246: *
247: * @param c1 the first comparable, may be null
248: * @param c2 the second comparable, may be null
249: * @return
250: * <ul>
251: * <li>If both objects are non-null and unequal, the lesser object.
252: * <li>If both objects are non-null and equal, c1.
253: * <li>If one of the comparables is null, the non-null object.
254: * <li>If both the comparables are null, null is returned.
255: * </ul>
256: */
257: public static Object min(Comparable c1, Comparable c2) {
258: if (c1 != null && c2 != null) {
259: return c1.compareTo(c2) < 1 ? c1 : c2;
260: } else {
261: return c1 != null ? c1 : c2;
262: }
263: }
264:
265: /**
266: * Null safe comparison of Comparables.
267: *
268: * @param c1 the first comparable, may be null
269: * @param c2 the second comparable, may be null
270: * @return
271: * <ul>
272: * <li>If both objects are non-null and unequal, the greater object.
273: * <li>If both objects are non-null and equal, c1.
274: * <li>If one of the comparables is null, the non-null object.
275: * <li>If both the comparables are null, null is returned.
276: * </ul>
277: */
278: public static Object max(Comparable c1, Comparable c2) {
279: if (c1 != null && c2 != null) {
280: return c1.compareTo(c2) >= 0 ? c1 : c2;
281: } else {
282: return c1 != null ? c1 : c2;
283: }
284: }
285:
286: // Null
287: //-----------------------------------------------------------------------
288: /**
289: * <p>Class used as a null placeholder where <code>null</code>
290: * has another meaning.</p>
291: *
292: * <p>For example, in a <code>HashMap</code> the
293: * {@link java.util.HashMap#get(java.lang.Object)} method returns
294: * <code>null</code> if the <code>Map</code> contains
295: * <code>null</code> or if there is no matching key. The
296: * <code>Null</code> placeholder can be used to distinguish between
297: * these two cases.</p>
298: *
299: * <p>Another example is <code>Hashtable</code>, where <code>null</code>
300: * cannot be stored.</p>
301: */
302: public static class Null implements Serializable {
303: /**
304: * Required for serialization support. Declare serialization compatibility with Commons Lang 1.0
305: *
306: * @see java.io.Serializable
307: */
308: private static final long serialVersionUID = 7092611880189329093L;
309:
310: /**
311: * Restricted constructor - singleton.
312: */
313: Null() {
314: super ();
315: }
316:
317: /**
318: * <p>Ensure singleton.</p>
319: *
320: * @return the singleton value
321: */
322: private Object readResolve() {
323: return ObjectUtils.NULL;
324: }
325: }
326:
327: }
|