1 19 20 package org.openide.filesystems; 21 22 import java.io.IOException ; 23 import java.util.LinkedList ; 24 25 28 class EventControl { 29 32 private int requests; 33 34 38 private int priorityRequests; 39 40 41 private AtomicActionLink currentAtomAction; 42 43 44 private LinkedList <FileSystem.EventDispatcher> requestsQueue; 45 46 50 void dispatchEvent(FileSystem.EventDispatcher dispatcher) { 51 if (postponeFiring(dispatcher)) { 52 return; 53 } 54 55 dispatcher.run(); 56 } 57 58 71 void beginAtomicAction(FileSystem.AtomicAction run) { 72 enterAtomicAction(run, true); 73 } 74 75 86 void finishAtomicAction() { 87 exitAtomicAction(true); 88 } 89 90 94 void runAtomicAction(final FileSystem.AtomicAction run) 95 throws IOException { 96 try { 97 enterAtomicAction(run, false); 98 run.run(); 99 } finally { 100 exitAtomicAction(false); 101 } 102 } 103 104 106 private synchronized void enterAtomicAction(Object 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 <FileSystem.EventDispatcher>(); 117 } 118 } 119 120 122 private void exitAtomicAction(boolean priority) { 123 boolean fireAll = false; 124 boolean firePriority = false; 125 LinkedList <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 154 if (fireAll) { 155 invokeDispatchers(false, reqQueueCopy); 156 157 return; 158 } 159 160 if (firePriority) { 161 requestsQueue = new LinkedList <FileSystem.EventDispatcher>(); 162 163 LinkedList <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 <FileSystem.EventDispatcher> invokeDispatchers(boolean priority, LinkedList <FileSystem.EventDispatcher> reqQueueCopy) { 177 LinkedList <FileSystem.EventDispatcher> newEnum = new LinkedList <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 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 disp.setAtomicActionLink(currentAtomAction); 201 requestsQueue.add(disp); 202 203 return true; 204 } 205 206 return false; 207 } 208 209 212 static final class AtomicActionLink { 213 private AtomicActionLink upper; 214 private Object propagationID; 215 216 AtomicActionLink(Object propagationID) { 217 this.propagationID = propagationID; 218 } 219 220 Object 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 |