Source Code Cross Referenced for VetoableChangeSupport.java in  » 6.0-JDK-Core » beans » java » beans » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » beans » java.beans 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025
026        package java.beans;
027
028        import java.io.Serializable;
029        import java.io.ObjectOutputStream;
030        import java.io.ObjectInputStream;
031        import java.io.IOException;
032        import java.util.Arrays;
033        import java.util.ArrayList;
034        import java.util.Iterator;
035        import java.util.List;
036
037        /**
038         * This is a utility class that can be used by beans that support constrained
039         * properties.  You can use an instance of this class as a member field
040         * of your bean and delegate various work to it.
041         *
042         * This class is serializable.  When it is serialized it will save
043         * (and restore) any listeners that are themselves serializable.  Any
044         * non-serializable listeners will be skipped during serialization.
045         */
046
047        public class VetoableChangeSupport implements  java.io.Serializable {
048
049            /**
050             * Constructs a <code>VetoableChangeSupport</code> object.
051             *
052             * @param sourceBean  The bean to be given as the source for any events.
053             */
054
055            public VetoableChangeSupport(Object sourceBean) {
056                if (sourceBean == null) {
057                    throw new NullPointerException();
058                }
059                source = sourceBean;
060            }
061
062            /**
063             * Add a VetoableListener to the listener list.
064             * The listener is registered for all properties.
065             * The same listener object may be added more than once, and will be called
066             * as many times as it is added.
067             * If <code>listener</code> is null, no exception is thrown and no action
068             * is taken.
069             *
070             * @param listener  The VetoableChangeListener to be added
071             */
072
073            public synchronized void addVetoableChangeListener(
074                    VetoableChangeListener listener) {
075                if (listener == null) {
076                    return;
077                }
078                if (listener instanceof  VetoableChangeListenerProxy) {
079                    VetoableChangeListenerProxy proxy = (VetoableChangeListenerProxy) listener;
080                    // Call two argument add method.
081                    addVetoableChangeListener(proxy.getPropertyName(),
082                            (VetoableChangeListener) proxy.getListener());
083                } else {
084                    if (listeners == null) {
085                        listeners = new java.util.Vector();
086                    }
087                    listeners.addElement(listener);
088                }
089            }
090
091            /**
092             * Remove a VetoableChangeListener from the listener list.
093             * This removes a VetoableChangeListener that was registered
094             * for all properties.
095             * If <code>listener</code> was added more than once to the same event
096             * source, it will be notified one less time after being removed.
097             * If <code>listener</code> is null, or was never added, no exception is
098             * thrown and no action is taken.
099             *
100             * @param listener  The VetoableChangeListener to be removed
101             */
102            public synchronized void removeVetoableChangeListener(
103                    VetoableChangeListener listener) {
104                if (listener == null) {
105                    return;
106                }
107                if (listener instanceof  VetoableChangeListenerProxy) {
108                    VetoableChangeListenerProxy proxy = (VetoableChangeListenerProxy) listener;
109                    // Call two argument remove method.
110                    removeVetoableChangeListener(proxy.getPropertyName(),
111                            (VetoableChangeListener) proxy.getListener());
112                } else {
113                    if (listeners == null) {
114                        return;
115                    }
116                    listeners.removeElement(listener);
117                }
118            }
119
120            /**
121             * Returns the list of VetoableChangeListeners. If named vetoable change listeners
122             * were added, then VetoableChangeListenerProxy wrappers will returned
123             * <p>
124             * @return List of VetoableChangeListeners and VetoableChangeListenerProxys
125             *         if named property change listeners were added.
126             * @since 1.4
127             */
128            public synchronized VetoableChangeListener[] getVetoableChangeListeners() {
129                List returnList = new ArrayList();
130
131                // Add all the VetoableChangeListeners
132                if (listeners != null) {
133                    returnList.addAll(listeners);
134                }
135
136                // Add all the VetoableChangeListenerProxys
137                if (children != null) {
138                    Iterator iterator = children.keySet().iterator();
139                    while (iterator.hasNext()) {
140                        String key = (String) iterator.next();
141                        VetoableChangeSupport child = (VetoableChangeSupport) children
142                                .get(key);
143                        VetoableChangeListener[] childListeners = child
144                                .getVetoableChangeListeners();
145                        for (int index = childListeners.length - 1; index >= 0; index--) {
146                            returnList.add(new VetoableChangeListenerProxy(key,
147                                    childListeners[index]));
148                        }
149                    }
150                }
151                return (VetoableChangeListener[]) (returnList
152                        .toArray(new VetoableChangeListener[0]));
153            }
154
155            /**
156             * Add a VetoableChangeListener for a specific property.  The listener
157             * will be invoked only when a call on fireVetoableChange names that
158             * specific property.
159             * The same listener object may be added more than once.  For each
160             * property,  the listener will be invoked the number of times it was added
161             * for that property.
162             * If <code>propertyName</code> or <code>listener</code> is null, no
163             * exception is thrown and no action is taken.
164             *
165             * @param propertyName  The name of the property to listen on.
166             * @param listener  The VetoableChangeListener to be added
167             */
168
169            public synchronized void addVetoableChangeListener(
170                    String propertyName, VetoableChangeListener listener) {
171                if (listener == null || propertyName == null) {
172                    return;
173                }
174                if (children == null) {
175                    children = new java.util.Hashtable();
176                }
177                VetoableChangeSupport child = (VetoableChangeSupport) children
178                        .get(propertyName);
179                if (child == null) {
180                    child = new VetoableChangeSupport(source);
181                    children.put(propertyName, child);
182                }
183                child.addVetoableChangeListener(listener);
184            }
185
186            /**
187             * Remove a VetoableChangeListener for a specific property.
188             * If <code>listener</code> was added more than once to the same event
189             * source for the specified property, it will be notified one less time
190             * after being removed.
191             * If <code>propertyName</code> is null, no exception is thrown and no
192             * action is taken.
193             * If <code>listener</code> is null, or was never added for the specified
194             * property, no exception is thrown and no action is taken.
195             *
196             * @param propertyName  The name of the property that was listened on.
197             * @param listener  The VetoableChangeListener to be removed
198             */
199
200            public synchronized void removeVetoableChangeListener(
201                    String propertyName, VetoableChangeListener listener) {
202                if (listener == null || propertyName == null) {
203                    return;
204                }
205                if (children == null) {
206                    return;
207                }
208                VetoableChangeSupport child = (VetoableChangeSupport) children
209                        .get(propertyName);
210                if (child == null) {
211                    return;
212                }
213                child.removeVetoableChangeListener(listener);
214            }
215
216            /**
217             * Returns an array of all the listeners which have been associated 
218             * with the named property.
219             *
220             * @param propertyName  The name of the property being listened to
221             * @return all the <code>VetoableChangeListeners</code> associated with
222             *         the named property.  If no such listeners have been added,
223             *         or if <code>propertyName</code> is null, an empty array is
224             *         returned.
225             * @since 1.4
226             */
227            public synchronized VetoableChangeListener[] getVetoableChangeListeners(
228                    String propertyName) {
229                List returnList = new ArrayList();
230
231                if (children != null && propertyName != null) {
232                    VetoableChangeSupport support = (VetoableChangeSupport) children
233                            .get(propertyName);
234                    if (support != null) {
235                        returnList.addAll(Arrays.asList(support
236                                .getVetoableChangeListeners()));
237                    }
238                }
239                return (VetoableChangeListener[]) (returnList
240                        .toArray(new VetoableChangeListener[0]));
241            }
242
243            /**
244             * Report a vetoable property update to any registered listeners.  If
245             * anyone vetos the change, then fire a new event reverting everyone to 
246             * the old value and then rethrow the PropertyVetoException.
247             * <p>
248             * No event is fired if old and new are equal and non-null.
249             *
250             * @param propertyName  The programmatic name of the property
251             *		that is about to change..
252             * @param oldValue  The old value of the property.
253             * @param newValue  The new value of the property.
254             * @exception PropertyVetoException if the recipient wishes the property
255             *              change to be rolled back.
256             */
257            public void fireVetoableChange(String propertyName,
258                    Object oldValue, Object newValue)
259                    throws PropertyVetoException {
260                if (listeners == null && children == null) {
261                    return;
262                }
263
264                PropertyChangeEvent evt = new PropertyChangeEvent(source,
265                        propertyName, oldValue, newValue);
266                fireVetoableChange(evt);
267            }
268
269            /**
270             * Report a int vetoable property update to any registered listeners.
271             * No event is fired if old and new are equal.
272             * <p>
273             * This is merely a convenience wrapper around the more general
274             * fireVetoableChange method that takes Object values.
275             *
276             * @param propertyName  The programmatic name of the property
277             *		that is about to change.
278             * @param oldValue  The old value of the property.
279             * @param newValue  The new value of the property.
280             */
281            public void fireVetoableChange(String propertyName, int oldValue,
282                    int newValue) throws PropertyVetoException {
283                if (oldValue == newValue) {
284                    return;
285                }
286                fireVetoableChange(propertyName, new Integer(oldValue),
287                        new Integer(newValue));
288            }
289
290            /**
291             * Report a boolean vetoable property update to any registered listeners.
292             * No event is fired if old and new are equal.
293             * <p>
294             * This is merely a convenience wrapper around the more general
295             * fireVetoableChange method that takes Object values.
296             *
297             * @param propertyName  The programmatic name of the property
298             *		that is about to change.
299             * @param oldValue  The old value of the property.
300             * @param newValue  The new value of the property.
301             */
302            public void fireVetoableChange(String propertyName,
303                    boolean oldValue, boolean newValue)
304                    throws PropertyVetoException {
305                if (oldValue == newValue) {
306                    return;
307                }
308                fireVetoableChange(propertyName, Boolean.valueOf(oldValue),
309                        Boolean.valueOf(newValue));
310            }
311
312            /**
313             * Fire a vetoable property update to any registered listeners.  If
314             * anyone vetos the change, then fire a new event reverting everyone to 
315             * the old value and then rethrow the PropertyVetoException.
316             * <p>
317             * No event is fired if old and new are equal and non-null.
318             *
319             * @param evt  The PropertyChangeEvent to be fired.
320             * @exception PropertyVetoException if the recipient wishes the property
321             *              change to be rolled back.
322             */
323            public void fireVetoableChange(PropertyChangeEvent evt)
324                    throws PropertyVetoException {
325
326                Object oldValue = evt.getOldValue();
327                Object newValue = evt.getNewValue();
328                String propertyName = evt.getPropertyName();
329                if (oldValue != null && newValue != null
330                        && oldValue.equals(newValue)) {
331                    return;
332                }
333
334                java.util.Vector targets = null;
335                VetoableChangeSupport child = null;
336                synchronized (this ) {
337                    if (listeners != null) {
338                        targets = (java.util.Vector) listeners.clone();
339                    }
340                    if (children != null && propertyName != null) {
341                        child = (VetoableChangeSupport) children
342                                .get(propertyName);
343                    }
344                }
345
346                if (listeners != null) {
347                    try {
348                        for (int i = 0; i < targets.size(); i++) {
349                            VetoableChangeListener target = (VetoableChangeListener) targets
350                                    .elementAt(i);
351                            target.vetoableChange(evt);
352                        }
353                    } catch (PropertyVetoException veto) {
354                        // Create an event to revert everyone to the old value.
355                        evt = new PropertyChangeEvent(source, propertyName,
356                                newValue, oldValue);
357                        for (int i = 0; i < targets.size(); i++) {
358                            try {
359                                VetoableChangeListener target = (VetoableChangeListener) targets
360                                        .elementAt(i);
361                                target.vetoableChange(evt);
362                            } catch (PropertyVetoException ex) {
363                                // We just ignore exceptions that occur during reversions.
364                            }
365                        }
366                        // And now rethrow the PropertyVetoException.
367                        throw veto;
368                    }
369                }
370
371                if (child != null) {
372                    child.fireVetoableChange(evt);
373                }
374            }
375
376            /**
377             * Check if there are any listeners for a specific property, including
378             * those registered on all properties.  If <code>propertyName</code>
379             * is null, only check for listeners registered on all properties.
380             *
381             * @param propertyName  the property name.
382             * @return true if there are one or more listeners for the given property
383             */
384            public synchronized boolean hasListeners(String propertyName) {
385                if (listeners != null && !listeners.isEmpty()) {
386                    // there is a generic listener
387                    return true;
388                }
389                if (children != null && propertyName != null) {
390                    VetoableChangeSupport child = (VetoableChangeSupport) children
391                            .get(propertyName);
392                    if (child != null && child.listeners != null) {
393                        return !child.listeners.isEmpty();
394                    }
395                }
396                return false;
397            }
398
399            /**
400             * @serialData Null terminated list of <code>VetoableChangeListeners</code>.
401             * <p>
402             * At serialization time we skip non-serializable listeners and
403             * only serialize the serializable listeners.
404             *
405             */
406
407            private void writeObject(ObjectOutputStream s) throws IOException {
408                s.defaultWriteObject();
409
410                java.util.Vector v = null;
411                synchronized (this ) {
412                    if (listeners != null) {
413                        v = (java.util.Vector) listeners.clone();
414                    }
415                }
416
417                if (v != null) {
418                    for (int i = 0; i < v.size(); i++) {
419                        VetoableChangeListener l = (VetoableChangeListener) v
420                                .elementAt(i);
421                        if (l instanceof  Serializable) {
422                            s.writeObject(l);
423                        }
424                    }
425                }
426                s.writeObject(null);
427            }
428
429            private void readObject(ObjectInputStream s)
430                    throws ClassNotFoundException, IOException {
431                s.defaultReadObject();
432
433                Object listenerOrNull;
434                while (null != (listenerOrNull = s.readObject())) {
435                    addVetoableChangeListener((VetoableChangeListener) listenerOrNull);
436                }
437            }
438
439            /**
440             * "listeners" lists all the generic listeners.
441             *
442             *  This is transient - its state is written in the writeObject method.
443             */
444            transient private java.util.Vector listeners;
445
446            /** 
447             * Hashtable for managing listeners for specific properties.
448             * Maps property names to VetoableChangeSupport objects.
449             * @serial 
450             * @since 1.2
451             */
452            private java.util.Hashtable children;
453
454            /** 
455             * The object to be provided as the "source" for any generated events.
456             * @serial
457             */
458            private Object source;
459
460            /**
461             * Internal version number
462             * @serial
463             */
464            private int vetoableChangeSupportSerializedDataVersion = 2;
465
466            /**
467             * Serialization version ID, so we're compatible with JDK 1.1
468             */
469            static final long serialVersionUID = -5090210921595982017L;
470        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.