KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > filesystems > EventControl


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.openide.filesystems;
21
22 import java.io.IOException JavaDoc;
23 import java.util.LinkedList JavaDoc;
24
25 /**
26  * @author rmatous
27  */

28 class EventControl {
29     /** number of requests posted and not processed. to
30     * know what to do in sync.
31     */

32     private int requests;
33
34     /** number of priority requests (requested from priority atomic block) posted
35     * and not processed. to
36     * know what to do in sync.
37     */

38     private int priorityRequests;
39
40     /** Holds current propagation ID and link to previous*/
41     private AtomicActionLink currentAtomAction;
42
43     /** List of requests */
44     private LinkedList JavaDoc<FileSystem.EventDispatcher> requestsQueue;
45
46     /**
47      * Method that can fire events directly, postpone them, fire them in
48      * standalone thread or in RequestProcessor
49      */

50     void dispatchEvent(FileSystem.EventDispatcher dispatcher) {
51         if (postponeFiring(dispatcher)) {
52             return;
53         }
54
55         dispatcher.run();
56     }
57
58     /**
59      * Begin of priority atomic actions. Atomic actions from inside of org.openide.FileSystems
60      * are considered as priority atomic actions. From last priority atomic actions
61      * are fired events regardless if nested in any normal atomic action.
62      *
63      * Begin of block, that should be performed without firing events.
64      * Firing of events is postponed after end of block .
65      * There is strong necessity to use always both methods: beginAtomicAction
66      * and finishAtomicAction. It is recommended use it in try - finally block.
67      * @see FileSystemt#beginAtomicAction
68      * @param run Events fired from this atomic action will be marked as events
69      * that were fired from this run.
70      */

71     void beginAtomicAction(FileSystem.AtomicAction run) {
72         enterAtomicAction(run, true);
73     }
74
75     /**
76      * End of priority atomic actions. Atomic actions from inside of org.openide.FileSystems
77      * are considered as priority atomic actions. From last priority atomic actions
78      * are fired events regardless if nested in any normal atomic action.
79      *
80      * End of block, that should be performed without firing events.
81      * Firing of events is postponed after end of block .
82      * There is strong necessity to use always both methods: beginAtomicAction
83      * and finishAtomicAction. It is recommended use it in try - finally block.
84      * @see FileSystemt#finishAtomicAction
85      */

86     void finishAtomicAction() {
87         exitAtomicAction(true);
88     }
89
90     /** Executes atomic action. The atomic action represents a set of
91     * operations constituting one logical unit. It is guaranteed that during
92     * execution of such an action no events about changes in the filesystem
93     * will be fired.*/

94     void runAtomicAction(final FileSystem.AtomicAction run)
95     throws IOException JavaDoc {
96         try {
97             enterAtomicAction(run, false);
98             run.run();
99         } finally {
100             exitAtomicAction(false);
101         }
102     }
103
104     /** Enters atomic action.
105     */

106     private synchronized void enterAtomicAction(Object JavaDoc propID, boolean priority) {
107         AtomicActionLink nextPropID = new AtomicActionLink(propID);
108         nextPropID.setPreviousLink(currentAtomAction);
109         currentAtomAction = nextPropID;
110
111         if (priority) {
112             priorityRequests++;
113         }
114
115         if (requests++ == 0) {
116             requestsQueue = new LinkedList JavaDoc<FileSystem.EventDispatcher>();
117         }
118     }
119
120     /** Exits atomic action.
121     */

122     private void exitAtomicAction(boolean priority) {
123         boolean fireAll = false;
124         boolean firePriority = false;
125         LinkedList JavaDoc<FileSystem.EventDispatcher> reqQueueCopy;
126
127         synchronized (this) {
128             currentAtomAction = currentAtomAction.getPreviousLink();
129
130             requests--;
131
132             if (priority) {
133                 priorityRequests--;
134             }
135
136             if (requests == 0) {
137                 fireAll = true;
138             }
139
140             if (!fireAll && priority && (priorityRequests == 0)) {
141                 firePriority = true;
142             }
143
144             if (fireAll || firePriority) {
145                 reqQueueCopy = requestsQueue;
146                 requestsQueue = null;
147                 priorityRequests = 0;
148             } else {
149                 return;
150             }
151         }
152
153         /** firing events outside synchronized block*/
154         if (fireAll) {
155             invokeDispatchers(false, reqQueueCopy);
156
157             return;
158         }
159
160         if (firePriority) {
161             requestsQueue = new LinkedList JavaDoc<FileSystem.EventDispatcher>();
162
163             LinkedList JavaDoc<FileSystem.EventDispatcher> newReqQueue = invokeDispatchers(true, reqQueueCopy);
164
165             synchronized (this) {
166                 while ((requestsQueue != null) && !requestsQueue.isEmpty()) {
167                     FileSystem.EventDispatcher r = requestsQueue.removeFirst();
168                     newReqQueue.add(r);
169                 }
170
171                 requestsQueue = newReqQueue;
172             }
173         }
174     }
175
176     private LinkedList JavaDoc<FileSystem.EventDispatcher> invokeDispatchers(boolean priority, LinkedList JavaDoc<FileSystem.EventDispatcher> reqQueueCopy) {
177         LinkedList JavaDoc<FileSystem.EventDispatcher> newEnum = new LinkedList JavaDoc<FileSystem.EventDispatcher>();
178
179         while ((reqQueueCopy != null) && !reqQueueCopy.isEmpty()) {
180             FileSystem.EventDispatcher r = reqQueueCopy.removeFirst();
181             r.dispatch(priority);
182
183             if (priority) {
184                 newEnum.add(r);
185             }
186         }
187
188         return newEnum;
189     }
190
191     /* Adds dispatcher to queue.*/
192     private synchronized boolean postponeFiring(FileSystem.EventDispatcher disp) {
193         if (priorityRequests == 0) {
194             disp.setAtomicActionLink(currentAtomAction);
195             disp.dispatch(true);
196         }
197
198         if (requestsQueue != null) {
199             // run later
200
disp.setAtomicActionLink(currentAtomAction);
201             requestsQueue.add(disp);
202
203             return true;
204         }
205
206         return false;
207     }
208
209     /** Container that holds hierarchy of propagation IDs related to atomic actions
210      * Implemented as linked list
211      */

212     static final class AtomicActionLink {
213         private AtomicActionLink upper;
214         private Object JavaDoc propagationID;
215
216         AtomicActionLink(Object JavaDoc propagationID) {
217             this.propagationID = propagationID;
218         }
219
220         Object JavaDoc getAtomicAction() {
221             return propagationID;
222         }
223
224         void setPreviousLink(AtomicActionLink upper) {
225             this.upper = upper;
226         }
227
228         AtomicActionLink getPreviousLink() {
229             return upper;
230         }
231     }
232 }
233
Popular Tags