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.lang3;
018    
019    import java.io.Serializable;
020    import java.lang.reflect.Array;
021    import java.lang.reflect.InvocationTargetException;
022    import java.lang.reflect.Method;
023    
024    import org.apache.commons.lang3.exception.CloneFailedException;
025    
026    /**
027     * <p>Operations on <code>Object</code>.</p>
028     * 
029     * <p>This class tries to handle <code>null</code> input gracefully.
030     * An exception will generally not be thrown for a <code>null</code> input.
031     * Each method documents its behaviour in more detail.</p>
032     *
033     * <p>#ThreadSafe#</p>
034     * @author Apache Software Foundation
035     * @author <a href="mailto:nissim@nksystems.com">Nissim Karpenstein</a>
036     * @author <a href="mailto:janekdb@yahoo.co.uk">Janek Bogucki</a>
037     * @author Daniel L. Rall
038     * @author Gary Gregory
039     * @author Mario Winterer
040     * @author <a href="mailto:david@davidkarlsen.com">David J. M. Karlsen</a>
041     * @since 1.0
042     * @version $Id: ObjectUtils.java 960138 2010-07-03 00:30:46Z joehni $
043     */
044    //@Immutable
045    public class ObjectUtils {
046    
047        /**
048         * <p>Singleton used as a <code>null</code> placeholder where
049         * <code>null</code> has another meaning.</p>
050         *
051         * <p>For example, in a <code>HashMap</code> the
052         * {@link java.util.HashMap#get(java.lang.Object)} method returns
053         * <code>null</code> if the <code>Map</code> contains
054         * <code>null</code> or if there is no matching key. The
055         * <code>Null</code> placeholder can be used to distinguish between
056         * these two cases.</p>
057         *
058         * <p>Another example is <code>Hashtable</code>, where <code>null</code>
059         * cannot be stored.</p>
060         *
061         * <p>This instance is Serializable.</p>
062         */
063        public static final Null NULL = new Null();
064        
065        /**
066         * <p><code>ObjectUtils</code> instances should NOT be constructed in
067         * standard programming. Instead, the class should be used as
068         * <code>ObjectUtils.defaultIfNull("a","b");</code>.</p>
069         *
070         * <p>This constructor is public to permit tools that require a JavaBean instance
071         * to operate.</p>
072         */
073        public ObjectUtils() {
074            super();
075        }
076    
077        // Defaulting
078        //-----------------------------------------------------------------------
079        /**
080         * <p>Returns a default value if the object passed is
081         * <code>null</code>.</p>
082         * 
083         * <pre>
084         * ObjectUtils.defaultIfNull(null, null)      = null
085         * ObjectUtils.defaultIfNull(null, "")        = ""
086         * ObjectUtils.defaultIfNull(null, "zz")      = "zz"
087         * ObjectUtils.defaultIfNull("abc", *)        = "abc"
088         * ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
089         * </pre>
090         *
091         * @param object  the <code>Object</code> to test, may be <code>null</code>
092         * @param defaultValue  the default value to return, may be <code>null</code>
093         * @return <code>object</code> if it is not <code>null</code>, defaultValue otherwise
094         */
095        public static Object defaultIfNull(Object object, Object defaultValue) {
096            return object != null ? object : defaultValue;
097        }
098    
099        /**
100         * <p>Returns the first value in the array which is not <code>null</code>.
101         * If all the values are <code>null</code> or the array is <code>null</code>
102         * or empty then <code>null</code> is returned.</p>
103         * 
104         * <pre>
105         * ObjectUtils.firstNonNull(null, null)      = null
106         * ObjectUtils.firstNonNull(null, "")        = ""
107         * ObjectUtils.firstNonNull(null, null, "")  = ""
108         * ObjectUtils.firstNonNull(null, "zz")      = "zz"
109         * ObjectUtils.firstNonNull("abc", *)        = "abc"
110         * ObjectUtils.firstNonNull(null, "xyz", *)  = "xyz"
111         * ObjectUtils.firstNonNull(Boolean.TRUE, *) = Boolean.TRUE
112         * ObjectUtils.firstNonNull()                = null
113         * </pre>
114         *
115         * @param values  the values to test, may be <code>null</code> or empty
116         * @return the first value from <code>values</code> which is not <code>null</code>,
117         *  or <code>null</code> if there are no non-null values
118         */
119        public static <T> T firstNonNull(T... values) {
120            if (values != null) {
121                for (T val : values) {
122                    if (val != null) {
123                        return val;
124                    }
125                }
126            }
127            return null;
128        }
129    
130        // Null-safe equals/hashCode
131        //-----------------------------------------------------------------------
132        /**
133         * <p>Compares two objects for equality, where either one or both
134         * objects may be <code>null</code>.</p>
135         *
136         * <pre>
137         * ObjectUtils.equals(null, null)                  = true
138         * ObjectUtils.equals(null, "")                    = false
139         * ObjectUtils.equals("", null)                    = false
140         * ObjectUtils.equals("", "")                      = true
141         * ObjectUtils.equals(Boolean.TRUE, null)          = false
142         * ObjectUtils.equals(Boolean.TRUE, "true")        = false
143         * ObjectUtils.equals(Boolean.TRUE, Boolean.TRUE)  = true
144         * ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false
145         * </pre>
146         *
147         * @param object1  the first object, may be <code>null</code>
148         * @param object2  the second object, may be <code>null</code>
149         * @return <code>true</code> if the values of both objects are the same
150         */
151        public static boolean equals(Object object1, Object object2) {
152            if (object1 == object2) {
153                return true;
154            }
155            if ((object1 == null) || (object2 == null)) {
156                return false;
157            }
158            return object1.equals(object2);
159        }
160    
161        /**
162         * <p>Gets the hash code of an object returning zero when the
163         * object is <code>null</code>.</p>
164         *
165         * <pre>
166         * ObjectUtils.hashCode(null)   = 0
167         * ObjectUtils.hashCode(obj)    = obj.hashCode()
168         * </pre>
169         *
170         * @param obj  the object to obtain the hash code of, may be <code>null</code>
171         * @return the hash code of the object, or zero if null
172         * @since 2.1
173         */
174        public static int hashCode(Object obj) {
175            return (obj == null) ? 0 : obj.hashCode();
176        }
177    
178        // Identity ToString
179        //-----------------------------------------------------------------------
180        /**
181         * <p>Gets the toString that would be produced by <code>Object</code>
182         * if a class did not override toString itself. <code>null</code>
183         * will return <code>null</code>.</p>
184         *
185         * <pre>
186         * ObjectUtils.identityToString(null)         = null
187         * ObjectUtils.identityToString("")           = "java.lang.String@1e23"
188         * ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
189         * </pre>
190         *
191         * @param object  the object to create a toString for, may be
192         *  <code>null</code>
193         * @return the default toString text, or <code>null</code> if
194         *  <code>null</code> passed in
195         */
196        public static String identityToString(Object object) {
197            if (object == null) {
198                return null;
199            }
200            StringBuffer buffer = new StringBuffer();
201            identityToString(buffer, object);
202            return buffer.toString();
203        }
204    
205        /**
206         * <p>Appends the toString that would be produced by <code>Object</code>
207         * if a class did not override toString itself. <code>null</code>
208         * will throw a NullPointerException for either of the two parameters. </p>
209         *
210         * <pre>
211         * ObjectUtils.identityToString(buf, "")            = buf.append("java.lang.String@1e23"
212         * ObjectUtils.identityToString(buf, Boolean.TRUE)  = buf.append("java.lang.Boolean@7fa"
213         * ObjectUtils.identityToString(buf, Boolean.TRUE)  = buf.append("java.lang.Boolean@7fa")
214         * </pre>
215         *
216         * @param buffer  the buffer to append to
217         * @param object  the object to create a toString for
218         * @since 2.4
219         */
220        public static void identityToString(StringBuffer buffer, Object object) {
221            if (object == null) {
222                throw new NullPointerException("Cannot get the toString of a null identity");
223            }
224            buffer.append(object.getClass().getName())
225                  .append('@')
226                  .append(Integer.toHexString(System.identityHashCode(object)));
227        }
228    
229        // ToString
230        //-----------------------------------------------------------------------
231        /**
232         * <p>Gets the <code>toString</code> of an <code>Object</code> returning
233         * an empty string ("") if <code>null</code> input.</p>
234         * 
235         * <pre>
236         * ObjectUtils.toString(null)         = ""
237         * ObjectUtils.toString("")           = ""
238         * ObjectUtils.toString("bat")        = "bat"
239         * ObjectUtils.toString(Boolean.TRUE) = "true"
240         * </pre>
241         * 
242         * @see StringUtils#defaultString(String)
243         * @see String#valueOf(Object)
244         * @param obj  the Object to <code>toString</code>, may be null
245         * @return the passed in Object's toString, or nullStr if <code>null</code> input
246         * @since 2.0
247         */
248        public static String toString(Object obj) {
249            return obj == null ? "" : obj.toString();
250        }
251    
252        /**
253         * <p>Gets the <code>toString</code> of an <code>Object</code> returning
254         * a specified text if <code>null</code> input.</p>
255         * 
256         * <pre>
257         * ObjectUtils.toString(null, null)           = null
258         * ObjectUtils.toString(null, "null")         = "null"
259         * ObjectUtils.toString("", "null")           = ""
260         * ObjectUtils.toString("bat", "null")        = "bat"
261         * ObjectUtils.toString(Boolean.TRUE, "null") = "true"
262         * </pre>
263         * 
264         * @see StringUtils#defaultString(String,String)
265         * @see String#valueOf(Object)
266         * @param obj  the Object to <code>toString</code>, may be null
267         * @param nullStr  the String to return if <code>null</code> input, may be null
268         * @return the passed in Object's toString, or nullStr if <code>null</code> input
269         * @since 2.0
270         */
271        public static String toString(Object obj, String nullStr) {
272            return obj == null ? nullStr : obj.toString();
273        }
274    
275        // Min/Max
276        //-----------------------------------------------------------------------
277        /**
278         * Null safe comparison of Comparables.
279         * 
280         * @param c1  the first comparable, may be null
281         * @param c2  the second comparable, may be null
282         * @return
283         *  <ul>
284         *   <li>If both objects are non-null and unequal, the lesser object.
285         *   <li>If both objects are non-null and equal, c1.
286         *   <li>If one of the comparables is null, the non-null object.
287         *   <li>If both the comparables are null, null is returned.
288         *  </ul>
289         */
290        public static <T extends Comparable<? super T>> T min(T c1, T c2) {
291            if (c1 != null && c2 != null) {
292                return c1.compareTo(c2) < 1 ? c1 : c2;
293            } else {
294                return c1 != null ? c1 : c2;
295            }                              
296        }
297    
298        /**
299         * Null safe comparison of Comparables.
300         * 
301         * @param c1  the first comparable, may be null
302         * @param c2  the second comparable, may be null
303         * @return
304         *  <ul>
305         *   <li>If both objects are non-null and unequal, the greater object.
306         *   <li>If both objects are non-null and equal, c1.
307         *   <li>If one of the comparables is null, the non-null object.
308         *   <li>If both the comparables are null, null is returned.
309         *  </ul>
310         */
311        public static <T extends Comparable<? super T>> T max(T c1, T c2) {
312            if (c1 != null && c2 != null) {
313                return c1.compareTo(c2) >= 0 ? c1 : c2;
314            } else {
315                return c1 != null ? c1 : c2;
316            }
317        }
318        
319        /**
320         * Clone an object.
321         * 
322         * @param <T> the type of the object
323         * @param o the object to clone
324         * @return the clone if the object implements {@link Cloneable} otherwise <code>null</code>
325         * @throws CloneFailedException if the object is cloneable and the clone operation fails
326         * @since 3.0
327         */
328        public static <T> T clone(final T o) {
329            if (o instanceof Cloneable) {
330                final Object result;
331                if (o.getClass().isArray()) {
332                    final Class<?> componentType = o.getClass().getComponentType();
333                    if (!componentType.isPrimitive()) {
334                        result = ((Object[])o).clone();
335                    } else {
336                        int length = Array.getLength(o);
337                        result = Array.newInstance(componentType, length);
338                        while (length-- > 0) {
339                            Array.set(result, length, Array.get(o, length));
340                        }
341                    }
342                } else {
343                    try {
344                        final Method clone = o.getClass().getMethod("clone");
345                        result = clone.invoke(o);
346                    } catch (final NoSuchMethodException e) {
347                        throw new CloneFailedException("Cloneable type "
348                            + o.getClass().getName()
349                            + " has no clone method", e);
350                    } catch (final IllegalAccessException e) {
351                        throw new CloneFailedException("Cannot clone Cloneable type "
352                            + o.getClass().getName(), e);
353                    } catch (final InvocationTargetException e) {
354                        throw new CloneFailedException("Exception cloning Cloneable type "
355                            + o.getClass().getName(), e.getCause());
356                    }
357                }
358                @SuppressWarnings("unchecked")
359                final T checked = (T)result;
360                return checked;
361            }
362    
363            return null;
364        }
365    
366        /**
367         * Clone an object if possible. This method is similar to {@link #clone(Object)}, but will
368         * return the provided instance as the return value instead of <code>null</code> if the instance
369         * is not cloneable. This is more convenient if the caller uses different
370         * implementations (e.g. of a service) and some of the implementations do not allow concurrent
371         * processing or have state. In such cases the implementation can simply provide a proper
372         * clone implementation and the caller's code does not have to change.
373         * 
374         * @param <T> the type of the object
375         * @param o the object to clone
376         * @return the clone if the object implements {@link Cloneable} otherwise the object itself
377         * @throws CloneFailedException if the object is cloneable and the clone operation fails
378         * @since 3.0
379         */
380        public static <T> T cloneIfPossible(final T o) {
381            final T clone = clone(o);
382            return clone == null ? o : clone;
383        }
384    
385        // Null
386        //-----------------------------------------------------------------------
387        /**
388         * <p>Class used as a null placeholder where <code>null</code>
389         * has another meaning.</p>
390         *
391         * <p>For example, in a <code>HashMap</code> the
392         * {@link java.util.HashMap#get(java.lang.Object)} method returns
393         * <code>null</code> if the <code>Map</code> contains
394         * <code>null</code> or if there is no matching key. The
395         * <code>Null</code> placeholder can be used to distinguish between
396         * these two cases.</p>
397         *
398         * <p>Another example is <code>Hashtable</code>, where <code>null</code>
399         * cannot be stored.</p>
400         */
401        public static class Null implements Serializable {
402            /**
403             * Required for serialization support. Declare serialization compatibility with Commons Lang 1.0
404             * 
405             * @see java.io.Serializable
406             */
407            private static final long serialVersionUID = 7092611880189329093L;
408            
409            /**
410             * Restricted constructor - singleton.
411             */
412            Null() {
413                super();
414            }
415            
416            /**
417             * <p>Ensure singleton.</p>
418             * 
419             * @return the singleton value
420             */
421            private Object readResolve() {
422                return ObjectUtils.NULL;
423            }
424        }
425    
426    }