001 /** 002 * Copyright 2002-2005 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 005 * use this file except in compliance with the License. You may obtain a copy of 006 * the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 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, WITHOUT 012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 013 * License for the specific language governing permissions and limitations under 014 * the License. 015 */ 016 package org.springframework.binding.value.support; 017 018 import java.math.BigDecimal; 019 import java.math.BigInteger; 020 import java.util.Arrays; 021 import java.util.Calendar; 022 import java.util.Collection; 023 import java.util.Date; 024 import java.util.HashSet; 025 import java.util.List; 026 import java.util.Set; 027 028 import org.springframework.binding.value.ValueChangeDetector; 029 030 /** 031 * Implementation of ValueChangeDetector that maintains a set of classes for which it is 032 * "safe" to use <code>equals()</code> for detecting a change in value (those classes 033 * that have immutable values). For all objects of a type in this set, the value 034 * comparison will be done using equals. For all other types, object equivalence (the == 035 * operator) will be used. 036 * <p> 037 * This is the default value change detector handed out by the Application Services. 038 * 039 * @author Larry Streepy 040 * 041 */ 042 public class DefaultValueChangeDetector implements ValueChangeDetector { 043 044 /* 045 * All the classes that are known to have a safe implementation of equals. 046 */ 047 protected final Set classesWithSafeEquals = new HashSet( Arrays.asList( new Class[] { Boolean.class, Byte.class, 048 Short.class, Integer.class, Long.class, Float.class, Double.class, String.class, Character.class, 049 BigDecimal.class, BigInteger.class, Date.class, Calendar.class } ) ); 050 051 /** 052 * Determines if there has been a change in value between the provided arguments. As 053 * many objects do not implement #equals in a manner that is strict enough for the 054 * requirements of this class, difference is determined using <code>!=</code>, 055 * however, to improve accuracy #equals will be used when this is definitely safe e.g. 056 * for Strings, Booleans, Numbers, Dates. 057 * 058 * @param oldValue Original object value 059 * @param newValue New object value 060 * @return true if the objects are different enough to indicate a change in the value 061 * model 062 */ 063 public boolean hasValueChanged(Object oldValue, Object newValue) { 064 if( oldValue != null && classesWithSafeEquals.contains( oldValue.getClass() ) ) 065 return !oldValue.equals( newValue ); 066 067 return oldValue != newValue; 068 } 069 070 /** 071 * Specify the set of classes that have an equals method that is safe to use for 072 * determining a value change. 073 * 074 * @param classes with safe equals methods 075 */ 076 public void setClassesWithSafeEquals(Collection classes) { 077 classesWithSafeEquals.clear(); 078 classesWithSafeEquals.addAll( classes ); 079 } 080 081 /** 082 * Get the set of classes that have an equals method that is safe to use for 083 * determining a value change. 084 * @return Collection of classes with safe equals methods 085 */ 086 public Collection getClassesWithSafeEquals() { 087 return classesWithSafeEquals; 088 } 089 }