KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > ChangeFirer


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans;
21
22 import java.util.logging.Level JavaDoc;
23 import org.openide.util.Utilities;
24 import java.util.*;
25
26 /** Thread which fires changes in the modules.
27  * Used to separate property change events and
28  * lookup changes from the dynamic scope of the
29  * changes themselves. Also to batch up possible
30  * changes and avoid firing duplicates.
31  * Accepts changes at any time
32  * and fires them from within the mutex (as a reader).
33  * @author Jesse Glick
34  */

35 final class ChangeFirer {
36
37     private final ModuleManager mgr;
38     // Pending things to perform:
39
private final Set<Change> changes = new LinkedHashSet<Change>(100);
40     private final Set<Module> modulesCreated = new HashSet<Module>(100);
41     private final Set<Module> modulesDeleted = new HashSet<Module>(10);
42     
43     /** Make a new change firer.
44      * @param mgr the associated module manager
45      */

46     public ChangeFirer(ModuleManager mgr) {
47         this.mgr = mgr;
48     }
49     
50     /** Add a change to the list of pending things to be fired.
51      * @param c the change which will be fired
52      */

53     public void change(Change c) {
54         changes.add(c);
55     }
56     
57     /** Add a module creation event to the list of pending things to be fired.
58      * @param m the module whose creation event will be fired
59      */

60     public void created(Module m) {
61         modulesCreated.add(m);
62     }
63     
64     /** Add a module deletion event to the list of pending things to be fired.
65      * Note that this will cancel any pending creation event for the same module!
66      * @param m the module whose creation event will be fired
67      */

68     public void deleted(Module m) {
69         // Possible that a module was added and then removed before any change
70
// was fired; in this case skip it.
71
if (! modulesCreated.remove(m)) {
72             modulesDeleted.add(m);
73         }
74     }
75     
76     /** Fire all pending changes.
77      * While this is happening, the manager is locked in a read-only mode.
78      * Should only be called from within a write mutex!
79      */

80     public void fire() {
81         mgr.readOnly(true);
82         try {
83             for (Change c: changes) {
84                 if (c.source instanceof Module) {
85                     ((Module) c.source).firePropertyChange0(c.prop, c.old, c.nue);
86                 } else if (c.source == mgr) {
87                     mgr.firePropertyChange(c.prop, c.old, c.nue);
88                 } else {
89                     throw new IllegalStateException JavaDoc("Strange source: " + c.source); // NOI18N
90
}
91             }
92             changes.clear();
93             if (! modulesCreated.isEmpty() || ! modulesDeleted.isEmpty()) {
94                 mgr.fireModulesCreatedDeleted(modulesCreated, modulesDeleted);
95             }
96             modulesCreated.clear();
97             modulesDeleted.clear();
98         } catch (RuntimeException JavaDoc e) {
99             // Recover gracefully.
100
Util.err.log(Level.SEVERE, null, e);
101         } finally {
102             mgr.readOnly(false);
103         }
104     }
105     
106     /** Possible change event to be fired.
107      * Used instead of PropertyChangeEvent as it can be stored in a set.
108      */

109     public static final class Change {
110         public final String JavaDoc prop;
111         public final Object JavaDoc source, old, nue;
112         public Change(Object JavaDoc source, String JavaDoc prop, Object JavaDoc old, Object JavaDoc nue) {
113             this.source = source;
114             this.prop = prop;
115             this.old = old;
116             this.nue = nue;
117         }
118         // Semantic equality, to avoid duplicate changes:
119
public boolean equals(Object JavaDoc o) {
120             if (! (o instanceof Change)) return false;
121             Change c = (Change) o;
122             return Utilities.compareObjects(prop, c.prop) &&
123                    Utilities.compareObjects(source, c.source) &&
124                    Utilities.compareObjects(old, c.old) &&
125                    Utilities.compareObjects(nue, c.nue);
126         }
127         public int hashCode() {
128             return source.hashCode() ^ (prop == null ? 0 : prop.hashCode());
129         }
130         public String JavaDoc toString() {
131             return "Change[" + source + ":" + prop + ";" + old + "->" + nue + "]"; // NOI18N
132
}
133     }
134     
135 }
136
Popular Tags