1 17 18 package EDU.oswego.cs.dl.util.concurrent; 19 20 import java.beans.VetoableChangeListener ; 21 import java.beans.PropertyChangeEvent ; 22 import java.beans.PropertyVetoException ; 23 import java.util.HashMap ; 24 import java.io.Serializable ; 25 import java.io.ObjectOutputStream ; 26 import java.io.ObjectInputStream ; 27 import java.io.IOException ; 28 29 108 109 public class VetoableChangeMulticaster implements Serializable { 110 111 115 118 119 protected transient VetoableChangeListener [] listeners = new VetoableChangeListener [0]; 120 121 122 126 protected final Object source; 127 128 133 protected HashMap children; 134 135 138 139 protected synchronized VetoableChangeMulticaster getChild(String propertyName) { 140 return (children == null)? null : 141 ((VetoableChangeMulticaster)children.get(propertyName)); 142 } 143 144 145 151 152 public VetoableChangeMulticaster(Object sourceBean) { 153 if (sourceBean == null) { 154 throw new NullPointerException (); 155 } 156 157 source = sourceBean; 158 } 159 160 168 169 public synchronized void addVetoableChangeListener(VetoableChangeListener listener) { 170 171 if (listener == null) throw new NullPointerException (); 172 173 int len = listeners.length; 174 VetoableChangeListener [] newArray = new VetoableChangeListener [len + 1]; 175 if (len > 0) 176 System.arraycopy(listeners, 0, newArray, 0, len); 177 newArray[len] = listener; 178 listeners = newArray; 179 } 180 181 191 192 public synchronized void addVetoableChangeListenerIfAbsent(VetoableChangeListener listener) { 193 194 if (listener == null) throw new NullPointerException (); 195 196 int len = listeners.length; 198 VetoableChangeListener [] newArray = new VetoableChangeListener [len + 1]; 199 for (int i = 0; i < len; ++i) { 200 newArray[i] = listeners[i]; 201 if (listener.equals(listeners[i])) 202 return; } 204 newArray[len] = listener; 205 listeners = newArray; 206 } 207 208 209 220 221 public synchronized void removeVetoableChangeListener(VetoableChangeListener listener) { 222 223 int newlen = listeners.length-1; 224 if (newlen < 0 || listener == null) return; 225 226 228 VetoableChangeListener [] newArray = new VetoableChangeListener [newlen]; 229 230 for (int i = 0; i < newlen; ++i) { 231 if (listener.equals(listeners[i])) { 232 for (int k = i + 1; k <= newlen; ++k) newArray[k-1] = listeners[k]; 234 listeners = newArray; 235 return; 236 } 237 else 238 newArray[i] = listeners[i]; 239 } 240 241 if (listener.equals(listeners[newlen])) 243 listeners = newArray; 244 245 } 246 247 258 259 public void addVetoableChangeListener(String propertyName, 260 VetoableChangeListener listener) { 261 262 if (listener == null) throw new NullPointerException (); 263 264 VetoableChangeMulticaster child = null; 265 266 synchronized(this) { 267 if (children == null) 268 children = new HashMap (); 269 else 270 child = (VetoableChangeMulticaster)children.get(propertyName); 271 272 if (child == null) { 273 child = new VetoableChangeMulticaster(source); 274 children.put(propertyName, child); 275 } 276 } 277 278 child.addVetoableChangeListener(listener); 279 } 280 281 291 292 public void addVetoableChangeListenerIfAbsent(String propertyName, 293 VetoableChangeListener listener) { 294 295 if (listener == null) throw new NullPointerException (); 296 297 VetoableChangeMulticaster child = null; 298 299 synchronized(this) { 300 if (children == null) 301 children = new HashMap (); 302 else 303 child = (VetoableChangeMulticaster)children.get(propertyName); 304 305 if (child == null) { 306 child = new VetoableChangeMulticaster(source); 307 children.put(propertyName, child); 308 } 309 } 310 311 child.addVetoableChangeListenerIfAbsent(listener); 312 } 313 314 315 324 325 public void removeVetoableChangeListener(String propertyName, 326 VetoableChangeListener listener) { 327 328 VetoableChangeMulticaster child = getChild(propertyName); 329 if (child != null) 330 child.removeVetoableChangeListener(listener); 331 } 332 333 334 338 339 protected void multicast(PropertyChangeEvent evt) throws PropertyVetoException { 340 341 VetoableChangeListener [] array; VetoableChangeMulticaster child = null; 343 344 synchronized (this) { 345 array = listeners; 346 347 if (children != null && evt.getPropertyName() != null) 348 child = (VetoableChangeMulticaster)children.get(evt.getPropertyName()); 349 } 350 351 353 int i = 0; 355 try { 356 for (i = 0; i < array.length; ++i) 357 array[i].vetoableChange(evt); 358 359 if (child != null) 360 child.multicast(evt); 361 } 362 363 catch (PropertyVetoException veto) { 364 365 367 PropertyChangeEvent revert = 368 new PropertyChangeEvent (evt.getSource(), 369 evt.getPropertyName(), 370 evt.getNewValue(), 371 evt.getOldValue()); 372 373 int lastNotified = (i < array.length)? i : (array.length-1); 374 375 for (int k = 0; k <= lastNotified; ++k) { 376 try { 377 array[k].vetoableChange(revert); 378 } 379 catch (PropertyVetoException ignore) { 380 } 382 } 383 384 throw veto; 386 } 387 } 388 389 390 410 public void fireVetoableChange(String propertyName, 411 Object oldValue, Object newValue) throws PropertyVetoException { 412 413 if (oldValue == null || newValue == null || !oldValue.equals(newValue)) { 414 multicast(new PropertyChangeEvent (source, 415 propertyName, 416 oldValue, 417 newValue)); 418 } 419 420 } 421 422 445 public void fireVetoableChange(String propertyName, 446 int oldValue, int newValue) throws PropertyVetoException { 447 if (oldValue != newValue) { 448 multicast(new PropertyChangeEvent (source, 449 propertyName, 450 new Integer (oldValue), 451 new Integer (newValue))); 452 } 453 } 454 455 456 479 public void fireVetoableChange(String propertyName, 480 boolean oldValue, boolean newValue) throws PropertyVetoException { 481 if (oldValue != newValue) { 482 multicast(new PropertyChangeEvent (source, 483 propertyName, 484 new Boolean (oldValue), 485 new Boolean (newValue))); 486 } 487 } 488 489 507 public void fireVetoableChange(PropertyChangeEvent evt) throws PropertyVetoException { 508 Object oldValue = evt.getOldValue(); 509 Object newValue = evt.getNewValue(); 510 if (oldValue == null || newValue == null || !oldValue.equals(newValue)) 511 multicast(evt); 512 } 513 514 522 public boolean hasListeners(String propertyName) { 523 524 VetoableChangeMulticaster child; 525 526 synchronized (this) { 527 if (listeners.length > 0) 528 return true; 529 else if (propertyName == null || children == null) 530 return false; 531 else { 532 child = (VetoableChangeMulticaster)children.get(propertyName); 533 if (child == null) 534 return false; 535 } 536 } 537 538 return child.hasListeners(null); 539 } 540 541 542 549 private synchronized void writeObject(ObjectOutputStream s) throws IOException { 550 s.defaultWriteObject(); 551 552 for (int i = 0; i < listeners.length; i++) { 553 VetoableChangeListener l = listeners[i]; 554 if (listeners[i] instanceof Serializable ) { 555 s.writeObject(listeners[i]); 556 } 557 } 558 s.writeObject(null); 559 } 560 561 562 private void readObject(ObjectInputStream s) throws ClassNotFoundException , IOException { 563 listeners = new VetoableChangeListener [0]; s.defaultReadObject(); 565 566 Object listenerOrNull; 567 while (null != (listenerOrNull = s.readObject())) { 568 addVetoableChangeListener((VetoableChangeListener )listenerOrNull); 569 } 570 } 571 572 } 573 | Popular Tags |