001/** 002 * Copyright 2010-2014 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.common.util; 017 018import static com.google.common.base.Preconditions.checkNotNull; 019import static com.google.common.base.Preconditions.checkState; 020 021import java.util.Objects; 022 023import org.kuali.common.util.equality.Equatable; 024 025public class ObjectUtils { 026 027 /** 028 * <p> 029 * This method returns <code>true</code> if the <code>toString()</code> methods on both objects return matching strings AND both objects are the exact same runtime type. 030 * </p> 031 * 032 * <p> 033 * Returns <code>true</code> immediately if <code>reference == other</code> (ie they are the same object). 034 * </p> 035 * 036 * <p> 037 * Returns <code>false</code> immediately if <code>other==null</code> or is a different runtime type than <code>reference</code>. 038 * </p> 039 * 040 * <p> 041 * If neither one is <code>null</code>, and both are the exact same runtime type, then compare the <code>toString()</code> methods 042 * </p> 043 * 044 * @param reference 045 * The object <code>other</code> is being compared to. 046 * @param other 047 * The object being examined for equality with <code>reference</code>. 048 * 049 * @throws NullPointerException 050 * If <code>reference</cod> is <code>null</code> or <code>reference.toString()</code> returns <code>null</code> 051 */ 052 public static boolean equalByToString(Object reference, Object other) { 053 checkNotNull(reference); 054 055 // They are the same object 056 if (reference == other) { 057 return true; 058 } 059 060 if (notEqual(reference, other)) { 061 return false; // Don't bother comparing the toString() methods 062 } else { 063 return reference.toString().equals(other.toString()); 064 } 065 } 066 067 /** 068 * Return true if {@code reference} and {@code object} are not null, the exact same runtime type, and {@code reference.compareTo(object) == 0} 069 * 070 * @throws NullPointerException 071 * If {@code reference} is {@code null} 072 */ 073 public static <T extends Comparable<? super T>> boolean equalByComparison(T reference, Object object) { 074 if (notEqual(reference, object)) { 075 return false; 076 } else { 077 // notEqual() guarantees that reference and object are the exact same runtime type 078 @SuppressWarnings("unchecked") 079 T other = (T) object; 080 return reference.compareTo(other) == 0; 081 } 082 083 } 084 085 /** 086 * <p> 087 * Return true if <code>reference</code> is definitely not equal to <code>other</code>. 088 * </p> 089 * 090 * <p> 091 * If <code>other</code> is null <b>OR</b> a different runtime type than <code>reference</code>, return true 092 * </p> 093 * 094 * @param reference 095 * The object <code>other</code> is being compared to. 096 * @param other 097 * The object being examined for equality with <code>reference</code>. 098 * 099 * @throws NullPointerException 100 * If <code>reference</cod> is <code>null</code> 101 */ 102 public static boolean notEqual(Object reference, Object other) { 103 checkNotNull(reference); 104 if (other == null) { 105 return true; 106 } else { 107 return !reference.getClass().equals(other.getClass()); 108 } 109 } 110 111 public static <T extends Equatable> boolean equal(T reference, Object other) { 112 checkNotNull(reference); 113 if (reference == other) { 114 return true; 115 } else if (notEqual(reference, other)) { 116 return false; 117 } else { 118 return equal(reference, (Equatable) other); 119 } 120 } 121 122 private static boolean equal(Equatable reference, Equatable other) { 123 Object[] values1 = reference.getEqualityValues(); 124 Object[] values2 = other.getEqualityValues(); 125 checkState(values1.length == values2.length, "value arrays must be the same. values1.length=%s values2.length=%s", values1.length, values2.length); 126 for (int i = 0; i < values1.length; i++) { 127 if (!Objects.equals(values1[i], values2[i])) { 128 return false; 129 } 130 } 131 return true; 132 } 133 134 /** 135 * @deprecated Use equalByToString() instead 136 */ 137 @Deprecated 138 public static boolean equalsByToString(Object reference, Object other) { 139 return equalByToString(reference, other); 140 } 141 142}