Source code: com/virtuosotechnologies/lib/propertyset/BasicPropertySet.java
1 /*
2 ================================================================================
3
4 FILE: BasicPropertySet.java
5
6 PROJECT:
7
8 Virtuoso Utilities
9
10 CONTENTS:
11
12 Basic implementation of PropertySet
13
14 PROGRAMMERS:
15
16 Daniel Azuma (DA) <dazuma@kagi.com>
17
18 COPYRIGHT:
19
20 Copyright (C) 2003 Daniel Azuma (dazuma@kagi.com)
21
22 This program is free software; you can redistribute it and/or
23 modify it under the terms of the GNU General Public License as
24 published by the Free Software Foundation; either version 2
25 of the License, or (at your option) any later version.
26
27 This program is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 GNU General Public License for more details.
31
32 You should have received a copy of the GNU General Public
33 License along with this program; if not, write to
34 Free Software Foundation, Inc.
35 59 Temple Place, Suite 330
36 Boston, MA 02111-1307 USA
37
38 ================================================================================
39 */
40
41
42 package com.virtuosotechnologies.lib.propertyset;
43
44
45 import java.util.Map;
46 import java.util.HashMap;
47
48 import com.virtuosotechnologies.lib.base.ConstrainedKey;
49 import com.virtuosotechnologies.lib.util.EventBroadcastHelper;
50 import com.virtuosotechnologies.lib.util.ObjectUtils;
51
52
53 /**
54 * A basic set of typed properties. Allows parenting of sets, so that sets
55 * can have other set define their default values.
56 */
57 public class BasicPropertySet
58 implements PropertySet
59 {
60 private EventBroadcastHelper propertyBroadcaster_;
61 private Map properties_;
62 private PropertySet parent_;
63 private PropertySetListener listener_;
64
65
66 /**
67 * Constructor
68 */
69 public BasicPropertySet()
70 {
71 this(null);
72 }
73
74
75 /**
76 * Constructor
77 */
78 public BasicPropertySet(
79 PropertySet parent)
80 {
81 parent_ = parent;
82 properties_ = new HashMap();
83 propertyBroadcaster_ = new EventBroadcastHelper(PropertySetListener.class);
84 if (parent_ != null)
85 {
86 parent_.addPropertySetListener(
87 listener_ = new PropertySetListener()
88 {
89 public void propertySetChanged(
90 PropertySetEvent ev)
91 {
92 boolean propagate;
93 synchronized (BasicPropertySet.this)
94 {
95 propagate = !properties_.containsKey(ev.getKey());
96 }
97 if (propagate)
98 {
99 firePropertySetEvent(ev.getKey(), ev.getOldValue(),
100 ev.getNewValue(), false);
101 }
102 }
103 });
104 }
105 }
106
107
108 /**
109 * Get a property.
110 *
111 * @param key key object for the property
112 * @return value for the property
113 */
114 public Object getValue(
115 ConstrainedKey key)
116 {
117 Object obj;
118 synchronized (this)
119 {
120 obj = properties_.get(key);
121 }
122 if (obj == null && parent_ != null)
123 {
124 obj = parent_.getValue(key);
125 }
126 return obj;
127 }
128
129
130 /**
131 * Get the default value for a property, or null if there is no default.
132 *
133 * @param key key object for the property
134 * @return default value for the property
135 */
136 public Object getDefaultValue(
137 ConstrainedKey key)
138 {
139 return (parent_ != null) ? parent_.getValue(key) : null;
140 }
141
142
143 /**
144 * Set a property.
145 *
146 * @param key key object for the property.
147 * @param value new value for the property.
148 */
149 public void putValue(
150 ConstrainedKey key,
151 Object value)
152 {
153 if (!key.matchesConstraint(value))
154 {
155 throw new IllegalArgumentException("ConstrainedKey mismatch");
156 }
157 Object oldValue;
158 synchronized (this)
159 {
160 oldValue = getValue(key);
161 properties_.put(key, value);
162 }
163 if (!ObjectUtils.safeEquals(oldValue, value))
164 {
165 firePropertySetEvent(key, oldValue, value, true);
166 }
167 }
168
169
170 /**
171 * Reset a property to the default. Sets it to null if there is no default.
172 *
173 * @param key key object for the property
174 */
175 public void resetValue(
176 ConstrainedKey key)
177 {
178 Object oldValue;
179 Object newValue;
180 synchronized (this)
181 {
182 oldValue = getValue(key);
183 properties_.remove(key);
184 newValue = getValue(key);
185 }
186 if (!ObjectUtils.safeEquals(oldValue, newValue))
187 {
188 firePropertySetEvent(key, oldValue, newValue, true);
189 }
190 }
191
192
193 /**
194 * Add a PropertySetListener. Listeners should be added via weak
195 * references.
196 *
197 * @param listener new listener
198 */
199 public void addPropertySetListener(
200 PropertySetListener listener)
201 {
202 propertyBroadcaster_.addListenerWeak(listener);
203 }
204
205
206 /**
207 * Remove a PropertySetListener. Does nothing if the listener is
208 * not already present.
209 *
210 * @param listener listener to remove
211 */
212 public void removePropertySetListener(
213 PropertySetListener listener)
214 {
215 propertyBroadcaster_.removeListener(listener);
216 }
217
218
219 /**
220 * Fires a property set event
221 */
222 protected void firePropertySetEvent(
223 ConstrainedKey key,
224 Object oldValue,
225 Object newValue,
226 boolean isSourceOriginal)
227 {
228 propertyBroadcaster_.fireEvent(
229 PropertySetListener.PROPERTYSET_CHANGED_METHOD,
230 new PropertySetEvent(this, isSourceOriginal, key, oldValue, newValue));
231 }
232 }