3333import java .util .concurrent .ConcurrentHashMap ;
3434import java .util .concurrent .Executor ;
3535import java .util .function .BiConsumer ;
36+ import java .util .function .Consumer ;
3637import java .util .function .Function ;
3738
3839import org .apache .logging .log4j .LogManager ;
@@ -107,33 +108,42 @@ private class ChildWatchesUpdater implements BiConsumer<EventHandlingWatch, Watc
107108 public void accept (EventHandlingWatch watch , WatchEvent event ) {
108109 switch (event .getKind ()) {
109110 case OVERFLOW : acceptOverflow (); break ;
110- case CREATED : acceptCreated (event . calculateFullPath () ); break ;
111- case DELETED : acceptDeleted (event . calculateFullPath () ); break ;
111+ case CREATED : getFileNameAndThen (event , this :: acceptCreated ); break ;
112+ case DELETED : getFileNameAndThen (event , this :: acceptDeleted ); break ;
112113 case MODIFIED : break ;
113114 }
114115 }
115116
117+ private void getFileNameAndThen (WatchEvent event , Consumer <Path > consumer ) {
118+ var child = event .getFileName ();
119+ if (child != null ) {
120+ consumer .accept (child );
121+ } else {
122+ logger .error ("Could not get file name of event: {}" , event );
123+ }
124+ }
125+
116126 private void acceptOverflow () {
117127 for (var childWatch : childWatches .values ()) {
118128 reportOverflowTo (childWatch );
119129 }
120130 }
121131
122- private void acceptCreated (Path fullPath ) {
123- if (Files .isDirectory (fullPath )) {
124- var childWatch = openChildWatch (fullPath );
132+ private void acceptCreated (Path child ) {
133+ if (Files .isDirectory (path . resolve ( child ) )) {
134+ var childWatch = openChildWatch (child );
125135 // Events in the newly created directory might have been missed
126136 // between its creation and setting up its watch. So, generate
127137 // an `OVERFLOW` event for the watch.
128138 reportOverflowTo (childWatch );
129139 }
130140 }
131141
132- private void acceptDeleted (Path fullPath ) {
142+ private void acceptDeleted (Path child ) {
133143 try {
134- closeChildWatch (fullPath );
144+ closeChildWatch (child );
135145 } catch (IOException e ) {
136- logger .error ("Could not close (nested) file tree watch for: {} ({})" , fullPath , e );
146+ logger .error ("Could not close (nested) file tree watch for: {} ({})" , path . resolve ( child ) , e );
137147 }
138148 }
139149
@@ -145,9 +155,10 @@ private void reportOverflowTo(JDKFileTreeWatch childWatch) {
145155 }
146156
147157 private JDKFileTreeWatch openChildWatch (Path child ) {
148- Function <Path , JDKFileTreeWatch > newChildWatch = p -> new JDKFileTreeWatch (
149- rootPath , rootPath .relativize (child ), exec , eventHandler );
158+ assert !child .isAbsolute ();
150159
160+ Function <Path , JDKFileTreeWatch > newChildWatch = p -> new JDKFileTreeWatch (
161+ rootPath , relativePathParent .resolve (child ), exec , eventHandler );
151162 var childWatch = childWatches .computeIfAbsent (child , newChildWatch );
152163 try {
153164 childWatch .startIfFirstTime ();
@@ -158,6 +169,8 @@ private JDKFileTreeWatch openChildWatch(Path child) {
158169 }
159170
160171 private void closeChildWatch (Path child ) throws IOException {
172+ assert !child .isAbsolute ();
173+
161174 var childWatch = childWatches .remove (child );
162175 if (childWatch != null ) {
163176 childWatch .close ();
@@ -212,7 +225,14 @@ public synchronized void close() throws IOException {
212225 protected synchronized void start () throws IOException {
213226 internal .open ();
214227 try (var children = Files .find (path , 1 , (p , attrs ) -> p != path && attrs .isDirectory ())) {
215- children .forEach (this ::openChildWatch );
228+ children .forEach (p -> {
229+ var child = p .getFileName ();
230+ if (child != null ) {
231+ openChildWatch (child );
232+ } else {
233+ logger .error ("File tree watch (for: {}) could not open a child watch for: {}" , path , p );
234+ }
235+ });
216236 } catch (IOException e ) {
217237 logger .error ("File tree watch (for: {}) could not iterate over its children ({})" , path , e );
218238 }
0 commit comments