53 // reference to watcher 54 private final AbstractWatchService watcher; 55 56 // reference to the original directory 57 private final Path dir; 58 59 // key state 60 private State state; 61 62 // pending events 63 private List<WatchEvent<?>> events; 64 65 // maps a context to the last event for the context (iff the last queued 66 // event for the context is an ENTRY_MODIFY event). 67 private Map<Object,WatchEvent<?>> lastModifyEvents; 68 69 protected AbstractWatchKey(Path dir, AbstractWatchService watcher) { 70 this.watcher = watcher; 71 this.dir = dir; 72 this.state = State.READY; 73 this.events = new ArrayList<WatchEvent<?>>(); 74 this.lastModifyEvents = new HashMap<Object,WatchEvent<?>>(); 75 } 76 77 final AbstractWatchService watcher() { 78 return watcher; 79 } 80 81 /** 82 * Return the original watchable (Path) 83 */ 84 @Override 85 public Path watchable() { 86 return dir; 87 } 88 89 /** 90 * Enqueues this key to the watch service 91 */ 92 final void signal() { 93 synchronized (this) { 94 if (state == State.READY) { 129 return; 130 } 131 } else { 132 // not a modify event so remove from the map as the 133 // last event will no longer be a modify event. 134 lastModifyEvents.remove(context); 135 } 136 } 137 138 // if the list has reached the limit then drop pending events 139 // and queue an OVERFLOW event 140 if (size >= MAX_EVENT_LIST_SIZE) { 141 kind = StandardWatchEventKinds.OVERFLOW; 142 isModify = false; 143 context = null; 144 } 145 } 146 147 // non-repeated event 148 Event<Object> ev = 149 new Event<Object>((WatchEvent.Kind<Object>)kind, context); 150 if (isModify) { 151 lastModifyEvents.put(context, ev); 152 } else if (kind == StandardWatchEventKinds.OVERFLOW) { 153 // drop all pending events 154 events.clear(); 155 lastModifyEvents.clear(); 156 } 157 events.add(ev); 158 signal(); 159 } 160 } 161 162 @Override 163 public final List<WatchEvent<?>> pollEvents() { 164 synchronized (this) { 165 List<WatchEvent<?>> result = events; 166 events = new ArrayList<WatchEvent<?>>(); 167 lastModifyEvents.clear(); 168 return result; 169 } 170 } 171 172 @Override 173 public final boolean reset() { 174 synchronized (this) { 175 if (state == State.SIGNALLED && isValid()) { 176 if (events.isEmpty()) { 177 state = State.READY; 178 } else { 179 // pending events so re-queue key 180 watcher.enqueueKey(this); 181 } 182 } 183 return isValid(); 184 } 185 } 186 | 53 // reference to watcher 54 private final AbstractWatchService watcher; 55 56 // reference to the original directory 57 private final Path dir; 58 59 // key state 60 private State state; 61 62 // pending events 63 private List<WatchEvent<?>> events; 64 65 // maps a context to the last event for the context (iff the last queued 66 // event for the context is an ENTRY_MODIFY event). 67 private Map<Object,WatchEvent<?>> lastModifyEvents; 68 69 protected AbstractWatchKey(Path dir, AbstractWatchService watcher) { 70 this.watcher = watcher; 71 this.dir = dir; 72 this.state = State.READY; 73 this.events = new ArrayList<>(); 74 this.lastModifyEvents = new HashMap<>(); 75 } 76 77 final AbstractWatchService watcher() { 78 return watcher; 79 } 80 81 /** 82 * Return the original watchable (Path) 83 */ 84 @Override 85 public Path watchable() { 86 return dir; 87 } 88 89 /** 90 * Enqueues this key to the watch service 91 */ 92 final void signal() { 93 synchronized (this) { 94 if (state == State.READY) { 129 return; 130 } 131 } else { 132 // not a modify event so remove from the map as the 133 // last event will no longer be a modify event. 134 lastModifyEvents.remove(context); 135 } 136 } 137 138 // if the list has reached the limit then drop pending events 139 // and queue an OVERFLOW event 140 if (size >= MAX_EVENT_LIST_SIZE) { 141 kind = StandardWatchEventKinds.OVERFLOW; 142 isModify = false; 143 context = null; 144 } 145 } 146 147 // non-repeated event 148 Event<Object> ev = 149 new Event<>((WatchEvent.Kind<Object>)kind, context); 150 if (isModify) { 151 lastModifyEvents.put(context, ev); 152 } else if (kind == StandardWatchEventKinds.OVERFLOW) { 153 // drop all pending events 154 events.clear(); 155 lastModifyEvents.clear(); 156 } 157 events.add(ev); 158 signal(); 159 } 160 } 161 162 @Override 163 public final List<WatchEvent<?>> pollEvents() { 164 synchronized (this) { 165 List<WatchEvent<?>> result = events; 166 events = new ArrayList<>(); 167 lastModifyEvents.clear(); 168 return result; 169 } 170 } 171 172 @Override 173 public final boolean reset() { 174 synchronized (this) { 175 if (state == State.SIGNALLED && isValid()) { 176 if (events.isEmpty()) { 177 state = State.READY; 178 } else { 179 // pending events so re-queue key 180 watcher.enqueueKey(this); 181 } 182 } 183 return isValid(); 184 } 185 } 186 |