Source Code Cross Referenced for VetoableChangeMulticaster.java in  » Ajax » Laszlo-4.0.10 » EDU » oswego » cs » dl » util » concurrent » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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 geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Ajax » Laszlo 4.0.10 » EDU.oswego.cs.dl.util.concurrent 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:          File: ProperyChangeMulticaster.java
003:
004:          Originally written by Doug Lea and released into the public domain.
005:          This may be used for any purposes whatsoever without acknowledgment.
006:          Thanks for the assistance and support of Sun Microsystems Labs,
007:          and everyone contributing, testing, and using this code.
008:
009:          This class is based on Sun JDK java.beans.VetoableChangeSupport,
010:          which is copyrighted by Sun. (It shares practically no code, but for 
011:          consistency, the documentation was lifted and adapted here.)
012:
013:          History:
014:          Date       Who                What
015:          14Mar1999   dl                 first release
016:         */
017:
018:        package EDU.oswego.cs.dl.util.concurrent;
019:
020:        import java.beans.VetoableChangeListener;
021:        import java.beans.PropertyChangeEvent;
022:        import java.beans.PropertyVetoException;
023:        import java.util.HashMap;
024:        import java.io.Serializable;
025:        import java.io.ObjectOutputStream;
026:        import java.io.ObjectInputStream;
027:        import java.io.IOException;
028:
029:        /**
030:         * This class is interoperable with java.beans.VetoableChangeSupport,
031:         * but relies on a streamlined copy-on-write scheme similar to
032:         * that used in CopyOnWriteArrayList. It also adheres to clarified
033:         * semantics of add, remove, and fireVetoableChange operations.
034:         * <p>
035:         * <b>Sample usage.</b>
036:         * 
037:         * <pre>
038:         * class Thing {
039:         *   protected Color myColor = Color.red; // an example property
040:         *   protected boolean changePending; // track whether in midst of change
041:         *
042:         *   // vetoable listeners:
043:         *   protected VetoableChangeMulticaster vetoers =
044:         *     new VetoableChangeMulticaster(this);
045:         *
046:         *   // Possibly also some ordinary listeners:
047:         *   protected PropertyChangeMulticaster listeners =
048:         *     new PropertyChangeMulticaster(this);
049:         *
050:         *   // registration methods, including:
051:         *   void addVetoer(VetoableChangeListener l) {
052:         *     // Use the `ifAbsent' version to avoid duplicate notifications
053:         *     vetoers.addVetoableChangeListenerIfAbsent(l);
054:         *   }
055:         *   
056:         *   public synchronized Color getColor() { // accessor
057:         *     return myColor;
058:         *   }
059:         *
060:         *   // Simple transactional control for vetos
061:         *
062:         *   public void setColor(int newColor) throws PropertyVetoException {
063:         *     Color oldColor = prepareSetColor(newColor);
064:         *    
065:         *     try {
066:         *       vetoers.fireVetoableChange("color", oldColor, newColor);
067:         *       commitColor(newColor);
068:         *       listeners.firePropertyChange("color", oldColor, newColor);
069:         *     }
070:         *     catch(PropertyVetoException ex) {
071:         *       abortSetColor();
072:         *       throw ex;
073:         *     }
074:         *   }
075:         *
076:         *   // Called on entry to proposed vetoable change from setColor.
077:         *   // Throws exception if there is already another change in progress.
078:         *   // Returns current color
079:         *   synchronized int prepareSetColor(Color c) throws PropertyVetoException {
080:         *     // only support one transaction at a time
081:         *     if (changePending) 
082:         *       throw new PropertyVetoException("Concurrent modification");
083:         *       // (Could alternatively wait out other transactions via
084:         *       // a wait/notify construction based on changePending.)
085:         *
086:         *     // perhaps some other screenings, like:
087:         *     else if (c == null) 
088:         *       throw new PropertyVetoException("Cannot change color to Null");
089:         *     else {
090:         *       changePending = true;
091:         *       return myColor;
092:         *     }
093:         *   }
094:         *
095:         *   synchronized void commitColor(Color newColor) { 
096:         *     myColor = newColor;
097:         *     changePending = false;
098:         *   }
099:         *
100:         *   synchronized void abortSetColor() {
101:         *     changePending = false;
102:         *   }
103:         *
104:         * }
105:         * </pre>   
106:         * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
107:         **/
108:
109:        public class VetoableChangeMulticaster implements  Serializable {
110:
111:            // This code is 90% identical with PropertyChangeMulticaster,
112:            // but there is no good way to unify the code while maintaining
113:            // interoperability with beans versions.
114:
115:            /**
116:             * The array of listeners. Copied on each update
117:             **/
118:
119:            protected transient VetoableChangeListener[] listeners = new VetoableChangeListener[0];
120:
121:            /** 
122:             * The object to be provided as the "source" for any generated events.
123:             * @serial
124:             */
125:            protected final Object source;
126:
127:            /** 
128:             * HashMap for managing listeners for specific properties.
129:             * Maps property names to VetoableChangeMulticaster objects.
130:             * @serial
131:             */
132:            protected HashMap children;
133:
134:            /**
135:             * Return the child associated with property, or null if no such
136:             **/
137:
138:            protected synchronized VetoableChangeMulticaster getChild(
139:                    String propertyName) {
140:                return (children == null) ? null
141:                        : ((VetoableChangeMulticaster) children
142:                                .get(propertyName));
143:            }
144:
145:            /**
146:             * Constructs a <code>VetoableChangeMulticaster</code> object.
147:             *
148:             * @param sourceBean  The bean to be given as the source for any events.
149:             * @exception NullPointerException if sourceBean is null
150:             */
151:
152:            public VetoableChangeMulticaster(Object sourceBean) {
153:                if (sourceBean == null) {
154:                    throw new NullPointerException();
155:                }
156:
157:                source = sourceBean;
158:            }
159:
160:            /**
161:             * Add a VetoableChangeListener to the listener list.
162:             * The listener is registered for all properties.
163:             * If the listener is added multiple times, it will
164:             * receive multiple change notifications upon any fireVetoableChange.
165:             *
166:             * @param listener  The VetoableChangeListener to be added
167:             */
168:
169:            public synchronized void addVetoableChangeListener(
170:                    VetoableChangeListener listener) {
171:
172:                if (listener == null)
173:                    throw new NullPointerException();
174:
175:                int len = listeners.length;
176:                VetoableChangeListener[] newArray = new VetoableChangeListener[len + 1];
177:                if (len > 0)
178:                    System.arraycopy(listeners, 0, newArray, 0, len);
179:                newArray[len] = listener;
180:                listeners = newArray;
181:            }
182:
183:            /**
184:             * Add a PropertyChangeListener to the listener list if it is 
185:             * not already present.
186:             * The listener is registered for all properties.
187:             * The operation maintains Set semantics: If the listener is already 
188:             * registered, the operation has no effect.
189:             *
190:             * @param listener  The PropertyChangeListener to be added
191:             * @exception NullPointerException If listener is null
192:             */
193:
194:            public synchronized void addVetoableChangeListenerIfAbsent(
195:                    VetoableChangeListener listener) {
196:
197:                if (listener == null)
198:                    throw new NullPointerException();
199:
200:                // Copy while checking if already present.
201:                int len = listeners.length;
202:                VetoableChangeListener[] newArray = new VetoableChangeListener[len + 1];
203:                for (int i = 0; i < len; ++i) {
204:                    newArray[i] = listeners[i];
205:                    if (listener.equals(listeners[i]))
206:                        return; // already present -- throw away copy
207:                }
208:                newArray[len] = listener;
209:                listeners = newArray;
210:            }
211:
212:            /**
213:             * Remove an occurrence of a VetoableChangeListener from the listener list.
214:             * It removes at most one occurrence of the given listener.
215:             * If the listener was added multiple times it must be removed
216:             * mulitple times.
217:             * This removes a VetoableChangeListener that was registered
218:             * for all properties, and has no effect if registered for only
219:             * one or more specified properties.
220:             *
221:             * @param listener  The VetoableChangeListener to be removed
222:             */
223:
224:            public synchronized void removeVetoableChangeListener(
225:                    VetoableChangeListener listener) {
226:
227:                int newlen = listeners.length - 1;
228:                if (newlen < 0 || listener == null)
229:                    return;
230:
231:                // Copy while searching for element to remove
232:
233:                VetoableChangeListener[] newArray = new VetoableChangeListener[newlen];
234:
235:                for (int i = 0; i < newlen; ++i) {
236:                    if (listener.equals(listeners[i])) {
237:                        //  copy remaining and exit
238:                        for (int k = i + 1; k <= newlen; ++k)
239:                            newArray[k - 1] = listeners[k];
240:                        listeners = newArray;
241:                        return;
242:                    } else
243:                        newArray[i] = listeners[i];
244:                }
245:
246:                // special-case last cell
247:                if (listener.equals(listeners[newlen]))
248:                    listeners = newArray;
249:
250:            }
251:
252:            /**
253:             * Add a VetoableChangeListener for a specific property.  The listener
254:             * will be invoked only when a call on fireVetoableChange names that
255:             * specific property. However, if a listener is registered both for all
256:             * properties and a specific property, it will receive multiple 
257:             * notifications upon changes to that property.
258:             *
259:             * @param propertyName  The name of the property to listen on.
260:             * @param listener  The VetoableChangeListener to be added
261:             * @exception NullPointerException If listener is null
262:             */
263:
264:            public void addVetoableChangeListener(String propertyName,
265:                    VetoableChangeListener listener) {
266:
267:                if (listener == null)
268:                    throw new NullPointerException();
269:
270:                VetoableChangeMulticaster child = null;
271:
272:                synchronized (this ) {
273:                    if (children == null)
274:                        children = new HashMap();
275:                    else
276:                        child = (VetoableChangeMulticaster) children
277:                                .get(propertyName);
278:
279:                    if (child == null) {
280:                        child = new VetoableChangeMulticaster(source);
281:                        children.put(propertyName, child);
282:                    }
283:                }
284:
285:                child.addVetoableChangeListener(listener);
286:            }
287:
288:            /**
289:             * Add a VetoableChangeListener for a specific property, if it is not
290:             * already registered.  The listener
291:             * will be invoked only when a call on fireVetoableChange names that
292:             * specific property. 
293:             *
294:             * @param propertyName  The name of the property to listen on.
295:             * @param listener  The VetoableChangeListener to be added
296:             * @exception NullPointerException If listener is null
297:             */
298:
299:            public void addVetoableChangeListenerIfAbsent(String propertyName,
300:                    VetoableChangeListener listener) {
301:
302:                if (listener == null)
303:                    throw new NullPointerException();
304:
305:                VetoableChangeMulticaster child = null;
306:
307:                synchronized (this ) {
308:                    if (children == null)
309:                        children = new HashMap();
310:                    else
311:                        child = (VetoableChangeMulticaster) children
312:                                .get(propertyName);
313:
314:                    if (child == null) {
315:                        child = new VetoableChangeMulticaster(source);
316:                        children.put(propertyName, child);
317:                    }
318:                }
319:
320:                child.addVetoableChangeListenerIfAbsent(listener);
321:            }
322:
323:            /**
324:             * Remove a VetoableChangeListener for a specific property.
325:             * Affects only the given property. 
326:             * If the listener is also registered for all properties,
327:             * then it will continue to be registered for them.
328:             *
329:             * @param propertyName  The name of the property that was listened on.
330:             * @param listener  The VetoableChangeListener to be removed
331:             */
332:
333:            public void removeVetoableChangeListener(String propertyName,
334:                    VetoableChangeListener listener) {
335:
336:                VetoableChangeMulticaster child = getChild(propertyName);
337:                if (child != null)
338:                    child.removeVetoableChangeListener(listener);
339:            }
340:
341:            /**
342:             * Helper method to relay evt to all listeners. 
343:             * Called by all public fireVetoableChange methods.
344:             **/
345:
346:            protected void multicast(PropertyChangeEvent evt)
347:                    throws PropertyVetoException {
348:
349:                VetoableChangeListener[] array; // bind in synch block below
350:                VetoableChangeMulticaster child = null;
351:
352:                synchronized (this ) {
353:                    array = listeners;
354:
355:                    if (children != null && evt.getPropertyName() != null)
356:                        child = (VetoableChangeMulticaster) children.get(evt
357:                                .getPropertyName());
358:                }
359:
360:                // Loop through array, and then cascade to child.
361:
362:                int i = 0; // make visible to catch clause
363:
364:                try {
365:                    for (i = 0; i < array.length; ++i)
366:                        array[i].vetoableChange(evt);
367:
368:                    if (child != null)
369:                        child.multicast(evt);
370:                }
371:
372:                catch (PropertyVetoException veto) {
373:
374:                    // Revert all that have been notified
375:
376:                    PropertyChangeEvent revert = new PropertyChangeEvent(evt
377:                            .getSource(), evt.getPropertyName(), evt
378:                            .getNewValue(), evt.getOldValue());
379:
380:                    int lastNotified = (i < array.length) ? i
381:                            : (array.length - 1);
382:
383:                    for (int k = 0; k <= lastNotified; ++k) {
384:                        try {
385:                            array[k].vetoableChange(revert);
386:                        } catch (PropertyVetoException ignore) {
387:                            // Cannot veto a reversion
388:                        }
389:                    }
390:
391:                    //  Rethrow the PropertyVetoException.
392:                    throw veto;
393:                }
394:            }
395:
396:            /**
397:             * Report a vetoable property update to any registered listeners. 
398:             * Notifications are sent serially (although in no particular order)
399:             * to the list of listeners,
400:             * aborting if one throws PropertyVetoException. Upon this exception,
401:             * fire a new event reverting this
402:             * change to all listeners that have already been notified
403:             * (ignoring any further vetos), 
404:             * suppress notifications to all other listeners, and
405:             * then rethrow the PropertyVetoException.
406:             * <p>
407:             * No event is fired if old and new are equal non-null.
408:             *
409:             * @param propertyName  The programmatic name of the property
410:             *                      that was changed.
411:             * @param oldValue  The old value of the property.
412:             * @param newValue  The new value of the property.
413:             * @exception PropertyVetoException if a recipient wishes the property
414:             *              change to be rolled back.
415:             */
416:            public void fireVetoableChange(String propertyName,
417:                    Object oldValue, Object newValue)
418:                    throws PropertyVetoException {
419:
420:                if (oldValue == null || newValue == null
421:                        || !oldValue.equals(newValue)) {
422:                    multicast(new PropertyChangeEvent(source, propertyName,
423:                            oldValue, newValue));
424:                }
425:
426:            }
427:
428:            /**
429:             * Report a vetoable property update to any registered listeners. 
430:             * Notifications are sent serially (although in no particular order)
431:             * to the list of listeners,
432:             * aborting if one throws PropertyVetoException. Upon this exception,
433:             * fire a new event reverting this
434:             * change to all listeners that have already been notified
435:             * (ignoring any further vetos), 
436:             * suppress notifications to all other listeners, and
437:             * then rethrow the PropertyVetoException.
438:             * <p>
439:             * No event is fired if old and new are equal.
440:             * <p>
441:             * This is merely a convenience wrapper around the more general
442:             * fireVetoableChange method that takes Object values.
443:             *
444:             * @param propertyName  The programmatic name of the property
445:             *                      that was changed.
446:             * @param oldValue  The old value of the property.
447:             * @param newValue  The new value of the property.
448:             * @exception PropertyVetoException if the recipient wishes the property
449:             *              change to be rolled back.
450:             */
451:            public void fireVetoableChange(String propertyName, int oldValue,
452:                    int newValue) throws PropertyVetoException {
453:                if (oldValue != newValue) {
454:                    multicast(new PropertyChangeEvent(source, propertyName,
455:                            new Integer(oldValue), new Integer(newValue)));
456:                }
457:            }
458:
459:            /**
460:             * Report a vetoable property update to any registered listeners. 
461:             * Notifications are sent serially (although in no particular order)
462:             * to the list of listeners,
463:             * aborting if one throws PropertyVetoException. Upon this exception,
464:             * fire a new event reverting this
465:             * change to all listeners that have already been notified
466:             * (ignoring any further vetos), 
467:             * suppress notifications to all other listeners, and
468:             * then rethrow the PropertyVetoException.
469:             * <p>
470:             * No event is fired if old and new are equal.
471:             * <p>
472:             * This is merely a convenience wrapper around the more general
473:             * fireVetoableChange method that takes Object values.
474:             *
475:             * @param propertyName  The programmatic name of the property
476:             *                      that was changed.
477:             * @param oldValue  The old value of the property.
478:             * @param newValue  The new value of the property.
479:             * @exception PropertyVetoException if the recipient wishes the property
480:             *              change to be rolled back.
481:             */
482:            public void fireVetoableChange(String propertyName,
483:                    boolean oldValue, boolean newValue)
484:                    throws PropertyVetoException {
485:                if (oldValue != newValue) {
486:                    multicast(new PropertyChangeEvent(source, propertyName,
487:                            new Boolean(oldValue), new Boolean(newValue)));
488:                }
489:            }
490:
491:            /**
492:             * Report a vetoable property update to any registered listeners. 
493:             * Notifications are sent serially (although in no particular order)
494:             * to the list of listeners,
495:             * aborting if one throws PropertyVetoException. Upon this exception,
496:             * fire a new event reverting this
497:             * change to all listeners that have already been notified
498:             * (ignoring any further vetos), 
499:             * suppress notifications to all other listeners, and
500:             * then rethrow the PropertyVetoException.
501:             * <p>
502:             * No event is fired if old and new are equal and non-null.
503:             *
504:             * equal and non-null.
505:             * @param evt  The PropertyChangeEvent object.
506:             * @exception PropertyVetoException if the recipient wishes the property
507:             *              change to be rolled back.
508:             */
509:            public void fireVetoableChange(PropertyChangeEvent evt)
510:                    throws PropertyVetoException {
511:                Object oldValue = evt.getOldValue();
512:                Object newValue = evt.getNewValue();
513:                if (oldValue == null || newValue == null
514:                        || !oldValue.equals(newValue))
515:                    multicast(evt);
516:            }
517:
518:            /**
519:             * Check if there are any listeners for a specific property.
520:             * If propertyName is null, return whether there are any listeners at all.
521:             *
522:             * @param propertyName  the property name.
523:             * @return true if there are one or more listeners for the given property
524:             * 
525:             */
526:            public boolean hasListeners(String propertyName) {
527:
528:                VetoableChangeMulticaster child;
529:
530:                synchronized (this ) {
531:                    if (listeners.length > 0)
532:                        return true;
533:                    else if (propertyName == null || children == null)
534:                        return false;
535:                    else {
536:                        child = (VetoableChangeMulticaster) children
537:                                .get(propertyName);
538:                        if (child == null)
539:                            return false;
540:                    }
541:                }
542:
543:                return child.hasListeners(null);
544:            }
545:
546:            /**
547:             * @serialData Null terminated list of <code>VetoableChangeListeners</code>.
548:             * <p>
549:             * At serialization time we skip non-serializable listeners and
550:             * only serialize the serializable listeners.
551:             *
552:             */
553:            private synchronized void writeObject(ObjectOutputStream s)
554:                    throws IOException {
555:                s.defaultWriteObject();
556:
557:                for (int i = 0; i < listeners.length; i++) {
558:                    VetoableChangeListener l = listeners[i];
559:                    if (listeners[i] instanceof  Serializable) {
560:                        s.writeObject(listeners[i]);
561:                    }
562:                }
563:                s.writeObject(null);
564:            }
565:
566:            private void readObject(ObjectInputStream s)
567:                    throws ClassNotFoundException, IOException {
568:                listeners = new VetoableChangeListener[0]; // paranoically reset
569:                s.defaultReadObject();
570:
571:                Object listenerOrNull;
572:                while (null != (listenerOrNull = s.readObject())) {
573:                    addVetoableChangeListener((VetoableChangeListener) listenerOrNull);
574:                }
575:            }
576:
577:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.