001package com.hfg.util.collection; 002 003import java.util.HashSet; 004import java.util.Map; 005import java.util.Properties; 006 007 008//------------------------------------------------------------------------------ 009/** 010 * Properties that keeps a dirty flag. 011 * @author J. Alex Taylor, hairyfatguy.com 012 */ 013//------------------------------------------------------------------------------ 014// com.hfg Library 015// 016// This library is free software; you can redistribute it and/or 017// modify it under the terms of the GNU Lesser General Public 018// License as published by the Free Software Foundation; either 019// version 2.1 of the License, or (at your option) any later version. 020// 021// This library is distributed in the hope that it will be useful, 022// but WITHOUT ANY WARRANTY; without even the implied warranty of 023// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 024// Lesser General Public License for more details. 025// 026// You should have received a copy of the GNU Lesser General Public 027// License along with this library; if not, write to the Free Software 028// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 029// 030// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 031// jataylor@hairyfatguy.com 032//------------------------------------------------------------------------------ 033 034public class DirtyProperties extends Properties 035{ 036 private boolean mIsDirty; 037 038 private HashSet<Object> mDirtyProperties = new HashSet<>(25); 039 040 //########################################################################## 041 // CONSTRUCTORS 042 //########################################################################## 043 044 //-------------------------------------------------------------------------- 045 public DirtyProperties() 046 { 047 super(); 048 } 049 050 //-------------------------------------------------------------------------- 051 /** 052 Creates an empty property list with the specified defaults. 053 @param inDefaults the defaults. 054 */ 055 public DirtyProperties(Properties inDefaults) 056 { 057 super(inDefaults); 058 } 059 060 061 //########################################################################## 062 // PUBLIC METHODS 063 //########################################################################## 064 065 //-------------------------------------------------------------------------- 066 /** 067 * Flags all properties as not being dirty. 068 */ 069 public void bless() 070 { 071 mIsDirty = false; 072 mDirtyProperties.clear(); 073 } 074 075 //-------------------------------------------------------------------------- 076 /** 077 * Returns whether or not the properties set as a whole is dirty (has been changed). 078 * @return whether or not the properties set as a whole is dirty. 079 */ 080 public boolean isDirty() 081 { 082 return mIsDirty; 083 } 084 085 //-------------------------------------------------------------------------- 086 /** 087 * Returns whether or not the value for the specified key is dirty (has been changed). 088 * @param inKey the specified key to check 089 * @return whether or not the value for the specified key is dirty. 090 */ 091 public boolean isDirty(String inKey) 092 { 093 return mDirtyProperties.contains(inKey); 094 } 095 096 //-------------------------------------------------------------------------- 097 @Override 098 public void clear() 099 { 100 if (size() > 0) 101 { 102 mIsDirty = true; 103 mDirtyProperties.clear(); 104 super.clear(); 105 } 106 } 107 108 //-------------------------------------------------------------------------- 109 @Override 110 public synchronized Object setProperty(String inKey, String inValue) 111 { 112 return put(inKey, inValue); 113 } 114 115 //-------------------------------------------------------------------------- 116 @Override 117 public Object put(Object inKey, Object inValue) 118 { 119 boolean valueChanged = valueChanged(inKey, inValue); 120 121 if (! isDirty()) 122 { 123 mIsDirty = valueChanged; 124 } 125 126 if (valueChanged) 127 { 128 mDirtyProperties.add(inKey); 129 } 130 131 return super.put(inKey, inValue); 132 } 133 134 //-------------------------------------------------------------------------- 135 @Override 136 public void putAll(Map<? extends Object,? extends Object> m) 137 { 138 for (Object key : m.keySet()) 139 { 140 put(key, m.get(key)); 141 } 142 } 143 144 //-------------------------------------------------------------------------- 145 @Override 146 public Object remove(Object inKey) 147 { 148 if (! isDirty() 149 && containsKey(inKey)) 150 { 151 mIsDirty = true; 152 mDirtyProperties.remove(inKey); 153 } 154 155 return super.remove(inKey); 156 } 157 158 //-------------------------------------------------------------------------- 159 private boolean valueChanged(Object inKey, Object inNewValue) 160 { 161 Object currentValue = get(inKey); 162 return ((null == currentValue 163 && inNewValue != null) 164 || (currentValue != null 165 && ! currentValue.equals(inNewValue))); 166 } 167 168}