--- /dev/null
+// JdbcPropertyChangeSupport.java\r
+// $Id: JdbcPropertyChangeSupport.java,v 1.1 2010/06/15 12:27:31 smhuang Exp $\r
+// (c) COPYRIGHT MIT, INRIA and Keio, 2000.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.tools.jdbc;\r
+\r
+import java.beans.PropertyChangeEvent;\r
+import java.beans.PropertyChangeListener;\r
+import java.beans.PropertyChangeSupport;\r
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+\r
+/**\r
+ * This subclass of java.beans.PropertyChangeSupport is identical\r
+ * in functionality except that it fire a PropertyChangeEvent even if the\r
+ * old value and the new value are identicals.\r
+ * @version $Revision: 1.1 $\r
+ * @author Benoît Mahé (bmahe@w3.org)\r
+ */\r
+public class JdbcPropertyChangeSupport extends PropertyChangeSupport {\r
+\r
+ /**\r
+ * Our listeners\r
+ */\r
+ private Vector listeners = null;\r
+\r
+ /**\r
+ * Our listeners for specific properties\r
+ */\r
+ private Hashtable children = null;\r
+\r
+ /**\r
+ * Our Bean\r
+ */\r
+ private Object source = null;\r
+\r
+ /**\r
+ * Add a PropertyChangeListener to the listener list.\r
+ * The listener is registered for all properties.\r
+ * @param listener The PropertyChangeListener to be added\r
+ */\r
+ public synchronized void \r
+ addPropertyChangeListener(PropertyChangeListener listener) \r
+ {\r
+ if (listeners == null) {\r
+ listeners = new Vector();\r
+ }\r
+ listeners.addElement(listener);\r
+ }\r
+\r
+ /**\r
+ * Remove a PropertyChangeListener from the listener list.\r
+ * This removes a PropertyChangeListener that was registered\r
+ * for all properties.\r
+ * @param listener The PropertyChangeListener to be removed\r
+ */\r
+ public synchronized void \r
+ removePropertyChangeListener(PropertyChangeListener listener) \r
+ {\r
+ if (listeners == null) {\r
+ return;\r
+ }\r
+ listeners.removeElement(listener);\r
+ }\r
+\r
+ /**\r
+ * Add a PropertyChangeListener for a specific property. The listener\r
+ * will be invoked only when a call on firePropertyChange names that\r
+ * specific property.\r
+ * @param propertyName The name of the property to listen on.\r
+ * @param listener The PropertyChangeListener to be added\r
+ */\r
+ public synchronized void \r
+ addPropertyChangeListener(String propertyName,\r
+ PropertyChangeListener listener) \r
+ {\r
+ if (children == null) {\r
+ children = new Hashtable();\r
+ }\r
+ JdbcPropertyChangeSupport child = \r
+ (JdbcPropertyChangeSupport)children.get(propertyName);\r
+ if (child == null) {\r
+ child = new JdbcPropertyChangeSupport(source);\r
+ children.put(propertyName, child);\r
+ }\r
+ child.addPropertyChangeListener(listener);\r
+ }\r
+\r
+ /**\r
+ * Remove a PropertyChangeListener for a specific property.\r
+ * @param propertyName The name of the property that was listened on.\r
+ * @param listener The PropertyChangeListener to be removed\r
+ */\r
+ public synchronized void \r
+ removePropertyChangeListener(String propertyName,\r
+ PropertyChangeListener listener) \r
+ {\r
+ if (children == null) {\r
+ return;\r
+ }\r
+ JdbcPropertyChangeSupport child = \r
+ (JdbcPropertyChangeSupport)children.get(propertyName);\r
+ if (child == null) {\r
+ return;\r
+ }\r
+ child.removePropertyChangeListener(listener);\r
+ }\r
+\r
+ /**\r
+ * Report a bound property update to any registered listeners.\r
+ * No event is fired if old and new are equal and non-null.\r
+ * @param propertyName The programmatic name of the property\r
+ * that was changed.\r
+ * @param oldValue The old value of the property.\r
+ * @param newValue The new value of the property.\r
+ */\r
+ public void firePropertyChange(String propertyName, \r
+ Object oldValue, \r
+ Object newValue) \r
+ {\r
+ Vector targets = null;\r
+ JdbcPropertyChangeSupport child = null;\r
+ synchronized (this) {\r
+ if (listeners != null) {\r
+ targets = (Vector) listeners.clone();\r
+ }\r
+ if (children != null && propertyName != null) {\r
+ child = (JdbcPropertyChangeSupport)children.get(propertyName);\r
+ }\r
+ }\r
+\r
+ PropertyChangeEvent evt = \r
+ new PropertyChangeEvent(source, propertyName, oldValue, newValue);\r
+\r
+ if (targets != null) {\r
+ for (int i = 0; i < targets.size(); i++) {\r
+ PropertyChangeListener target = \r
+ (PropertyChangeListener)targets.elementAt(i);\r
+ target.propertyChange(evt);\r
+ }\r
+ }\r
+\r
+ if (child != null) {\r
+ child.firePropertyChange(evt);\r
+ } \r
+ }\r
+\r
+ /**\r
+ * Report an int bound property update to any registered listeners.\r
+ * No event is fired if old and new are equal and non-null.\r
+ * <p>\r
+ * This is merely a convenience wrapper around the more general\r
+ * firePropertyChange method that takes Object values.\r
+ * @param propertyName The programmatic name of the property\r
+ * that was changed.\r
+ * @param oldValue The old value of the property.\r
+ * @param newValue The new value of the property.\r
+ */\r
+ public void firePropertyChange(String propertyName, \r
+ int oldValue,\r
+ int newValue) \r
+ {\r
+ firePropertyChange(propertyName, \r
+ new Integer(oldValue), \r
+ new Integer(newValue));\r
+ }\r
+\r
+\r
+ /**\r
+ * Report a boolean bound property update to any registered listeners.\r
+ * No event is fired if old and new are equal and non-null.\r
+ * <p>\r
+ * This is merely a convenience wrapper around the more general\r
+ * firePropertyChange method that takes Object values.\r
+ * @param propertyName The programmatic name of the property\r
+ * that was changed.\r
+ * @param oldValue The old value of the property.\r
+ * @param newValue The new value of the property.\r
+ */\r
+ public void firePropertyChange(String propertyName, \r
+ boolean oldValue,\r
+ boolean newValue) \r
+ {\r
+ firePropertyChange(propertyName, \r
+ new Boolean(oldValue), \r
+ new Boolean(newValue));\r
+ }\r
+\r
+ /**\r
+ * Fire an existing PropertyChangeEvent to any registered listeners.\r
+ * No event is fired if the given event's old and new values are\r
+ * equal and non-null.\r
+ * @param evt The PropertyChangeEvent object.\r
+ */\r
+ public void firePropertyChange(PropertyChangeEvent evt) {\r
+ String propertyName = evt.getPropertyName();\r
+ Vector targets = null;\r
+ JdbcPropertyChangeSupport child = null;\r
+ synchronized (this) {\r
+ if (listeners != null) {\r
+ targets = (Vector) listeners.clone();\r
+ }\r
+ if (children != null && propertyName != null) {\r
+ child = (JdbcPropertyChangeSupport)children.get(propertyName);\r
+ }\r
+ }\r
+\r
+ if (targets != null) {\r
+ for (int i = 0; i < targets.size(); i++) {\r
+ PropertyChangeListener target = \r
+ (PropertyChangeListener)targets.elementAt(i);\r
+ target.propertyChange(evt);\r
+ }\r
+ }\r
+ if (child != null) {\r
+ child.firePropertyChange(evt);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Check if there are any listeners for a specific property.\r
+ * @param propertyName the property name.\r
+ * @return true if there are ore or more listeners for the given property\r
+ */\r
+ public synchronized boolean hasListeners(String propertyName) {\r
+ if (listeners != null && !listeners.isEmpty()) {\r
+ return true;\r
+ }\r
+ if (children != null) {\r
+ JdbcPropertyChangeSupport child = \r
+ (JdbcPropertyChangeSupport)children.get(propertyName);\r
+ if (child != null && child.listeners != null) {\r
+ return !child.listeners.isEmpty();\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Constructor\r
+ * @param sourceBean our bean\r
+ */\r
+ public JdbcPropertyChangeSupport(Object sourceBean) {\r
+ super(sourceBean);\r
+ this.source = sourceBean;\r
+ }\r
+\r
+}\r