This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 207189
Collapse All | Expand All

(-)a/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObjectKeeper.java (-3 / +13 lines)
Lines 43-48 Link Here
43
package org.netbeans.modules.masterfs.filebasedfs.fileobjects;
43
package org.netbeans.modules.masterfs.filebasedfs.fileobjects;
44
44
45
import java.io.File;
45
import java.io.File;
46
import java.io.FileFilter;
46
import java.io.IOException;
47
import java.io.IOException;
47
import java.util.Collection;
48
import java.util.Collection;
48
import java.util.HashSet;
49
import java.util.HashSet;
Lines 86-95 Link Here
86
        LOG.log(Level.FINEST, "addRecursiveListener for {0} isEmpty: {1}", new Object[]{root, listeners.isEmpty()});
87
        LOG.log(Level.FINEST, "addRecursiveListener for {0} isEmpty: {1}", new Object[]{root, listeners.isEmpty()});
87
        if (listeners.isEmpty()) {
88
        if (listeners.isEmpty()) {
88
            Callable<?> stop = null;
89
            Callable<?> stop = null;
89
            if (fcl instanceof Callable && fcl.getClass().getName().equals("org.openide.filesystems.DeepListener")) { // NOI18N
90
            final boolean deepClass = fcl.getClass().getName().equals("org.openide.filesystems.DeepListener"); // NOI18N
91
            if (fcl instanceof Callable && deepClass) {
90
                stop = (Callable<?>)fcl;
92
                stop = (Callable<?>)fcl;
91
            }
93
            }
92
            listenToAll(stop);
94
            FileFilter filter = null;
95
            if (fcl instanceof FileFilter && deepClass) {
96
                filter = (FileFilter)fcl;
97
            }
98
            
99
            listenToAll(stop, filter);
93
        }
100
        }
94
        listeners.add(fcl);
101
        listeners.add(fcl);
95
    }
102
    }
Lines 180-186 Link Here
180
        }
187
        }
181
    }
188
    }
182
189
183
    private void listenToAll(Callable<?> stop) {
190
    private void listenToAll(Callable<?> stop, FileFilter filter) {
184
        assert Thread.holdsLock(this);
191
        assert Thread.holdsLock(this);
185
        assert kept == null : "Already listening to " + kept + " now requested for " + root;
192
        assert kept == null : "Already listening to " + kept + " now requested for " + root;
186
        kept = new HashSet<FolderObj>();
193
        kept = new HashSet<FolderObj>();
Lines 200-205 Link Here
200
            LOG.log(Level.FINEST, "listenToAll, check {0} for stop {1}", new Object[] { fo, stop });
207
            LOG.log(Level.FINEST, "listenToAll, check {0} for stop {1}", new Object[] { fo, stop });
201
            if (fo instanceof FolderObj) {
208
            if (fo instanceof FolderObj) {
202
                FolderObj obj = (FolderObj) fo;
209
                FolderObj obj = (FolderObj) fo;
210
                if (filter != null && !filter.accept(obj.getFileName().getFile())) {
211
                    continue;
212
                }
203
                Object shallStop = null;
213
                Object shallStop = null;
204
                if (stop != null) {
214
                if (stop != null) {
205
                    try {
215
                    try {
(-)e1eef78d4555 (+165 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2010 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.masterfs.filebasedfs;
44
45
import java.io.File;
46
import java.io.FileFilter;
47
import java.io.IOException;
48
import java.util.ArrayList;
49
import java.util.List;
50
import java.util.concurrent.Callable;
51
import java.util.logging.Level;
52
import java.util.logging.Logger;
53
import org.netbeans.junit.NbTestCase;
54
import org.openide.filesystems.FileAttributeEvent;
55
import org.openide.filesystems.FileChangeListener;
56
import org.openide.filesystems.FileEvent;
57
import org.openide.filesystems.FileObject;
58
import org.openide.filesystems.FileRenameEvent;
59
import org.openide.filesystems.FileUtil;
60
61
/**
62
 *
63
 * @author Jaroslav Tulach <jtulach@netbeans.org>
64
 */
65
public class FileUtilAddRecursiveListenerFilterTest extends NbTestCase
66
implements FileChangeListener {
67
    private FileObject root;
68
    private List<FileEvent> events = new ArrayList<FileEvent>();
69
    @SuppressWarnings("NonConstantLogger")
70
    private Logger LOG;
71
72
    public FileUtilAddRecursiveListenerFilterTest(String n) {
73
        super(n);
74
    }
75
76
    @Override
77
    protected Level logLevel() {
78
        return Level.FINEST;
79
    }
80
81
    @Override
82
    protected void setUp() throws Exception {
83
        clearWorkDir();
84
        
85
        LOG = Logger.getLogger("test." + getName());
86
        
87
        root = FileUtil.toFileObject(getWorkDir());
88
        assertNotNull("Root found", root);
89
90
        for (int i = 0; i < 10; i++) {
91
            if (i % 2 == 0) {
92
                root.createData("" + i, "txt");
93
            } else {
94
                root.createFolder("" + i);
95
            }
96
        }
97
    }
98
99
    public void testAddListenerGetsFiveCallbacks() throws IOException {
100
        class AtMostFive implements FileFilter {
101
            @Override
102
            public boolean accept(File pathname) {
103
                assertTrue("It is folder", pathname.isDirectory());
104
                int number = Integer.parseInt(pathname.getName());
105
                return number <= 5;
106
            }
107
            
108
        }
109
        
110
        FileUtil.addRecursiveListener(this, getWorkDir(), new AtMostFive(), null);
111
112
        File fifthChild = new File(new File(getWorkDir(), "5"), "new.5.txt");
113
        assertTrue(fifthChild.createNewFile());
114
        FileUtil.refreshFor(getWorkDir());
115
        assertEquals("One event delivered: " + events, 1, events.size());
116
        
117
        File seventhChild = new File(new File(getWorkDir(), "7"), "new.7.txt");
118
        assertTrue(seventhChild.createNewFile());
119
        FileUtil.refreshFor(getWorkDir());
120
        assertEquals("No other even delivered: " + events, 1, events.size());
121
    }
122
123
    @Override
124
    public void fileFolderCreated(FileEvent fe) {
125
        LOG.log(Level.INFO, "fileFolderCreated: {0}", fe.getFile());
126
        LOG.log(Level.INFO, "Thread dump", new Exception());
127
        events.add(fe);
128
    }
129
130
    @Override
131
    public void fileDataCreated(FileEvent fe) {
132
        LOG.log(Level.INFO, "fileDataCreated: {0}", fe.getFile());
133
        LOG.log(Level.INFO, "Thread dump", new Exception());
134
        events.add(fe);
135
    }
136
137
    @Override
138
    public void fileChanged(FileEvent fe) {
139
        LOG.log(Level.INFO, "fileChanged: {0}", fe.getFile());
140
        LOG.log(Level.INFO, "Thread dump", new Exception());
141
        events.add(fe);
142
    }
143
144
    @Override
145
    public void fileDeleted(FileEvent fe) {
146
        LOG.log(Level.INFO, "fileDeleted: {0}", fe.getFile());
147
        LOG.log(Level.INFO, "Thread dump", new Exception());
148
        events.add(fe);
149
    }
150
151
    @Override
152
    public void fileRenamed(FileRenameEvent fe) {
153
        LOG.log(Level.INFO, "fileRenamed: {0}", fe.getFile());
154
        LOG.log(Level.INFO, "Thread dump", new Exception());
155
        events.add(fe);
156
    }
157
158
    @Override
159
    public void fileAttributeChanged(FileAttributeEvent fe) {
160
        LOG.log(Level.INFO, "fileAttributeChanged: {0}", fe.getFile());
161
        LOG.log(Level.INFO, "Thread dump", new Exception());
162
        events.add(fe);
163
    }
164
165
}
(-)a/openide.filesystems/src/org/openide/filesystems/DeepListener.java (-2 / +10 lines)
Lines 43-48 Link Here
43
package org.openide.filesystems;
43
package org.openide.filesystems;
44
44
45
import java.io.File;
45
import java.io.File;
46
import java.io.FileFilter;
46
import java.lang.ref.WeakReference;
47
import java.lang.ref.WeakReference;
47
import java.util.ArrayList;
48
import java.util.ArrayList;
48
import java.util.Collections;
49
import java.util.Collections;
Lines 59-76 Link Here
59
 * @author Jaroslav Tulach <jtulach@netbeans.org>
60
 * @author Jaroslav Tulach <jtulach@netbeans.org>
60
 */
61
 */
61
final class DeepListener extends WeakReference<FileChangeListener>
62
final class DeepListener extends WeakReference<FileChangeListener>
62
implements FileChangeListener, Runnable, Callable<Boolean> {
63
implements FileChangeListener, Runnable, Callable<Boolean>, FileFilter {
63
    private static final Logger LOG = Logger.getLogger(DeepListener.class.getName());
64
    private static final Logger LOG = Logger.getLogger(DeepListener.class.getName());
64
    private final File path;
65
    private final File path;
65
    private FileObject watching;
66
    private FileObject watching;
66
    private boolean removed;
67
    private boolean removed;
67
    private final Callable<Boolean> stop;
68
    private final Callable<Boolean> stop;
69
    private final FileFilter filter;
68
    private static List<DeepListener> keep = new ArrayList<DeepListener>();
70
    private static List<DeepListener> keep = new ArrayList<DeepListener>();
69
71
70
    DeepListener(FileChangeListener listener, File path, Callable<Boolean> stop) {
72
    DeepListener(FileChangeListener listener, File path, FileFilter ff, Callable<Boolean> stop) {
71
        super(listener, Utilities.activeReferenceQueue());
73
        super(listener, Utilities.activeReferenceQueue());
72
        this.path = path;
74
        this.path = path;
73
        this.stop = stop;
75
        this.stop = stop;
76
        this.filter = ff;
74
        keep.add(this);
77
        keep.add(this);
75
    }
78
    }
76
    
79
    
Lines 227-230 Link Here
227
    public Boolean call() throws Exception {
230
    public Boolean call() throws Exception {
228
        return stop != null ? stop.call() : null;
231
        return stop != null ? stop.call() : null;
229
    }
232
    }
233
234
    @Override
235
    public boolean accept(File pathname) {
236
        return filter == null || filter.accept(pathname);
237
    }
230
}
238
}
(-)a/openide.filesystems/src/org/openide/filesystems/FileUtil.java (-5 / +13 lines)
Lines 331-339 Link Here
331
     * @since org.openide.filesystems 7.28
331
     * @since org.openide.filesystems 7.28
332
     */
332
     */
333
    public static void addRecursiveListener(FileChangeListener listener, File path) {
333
    public static void addRecursiveListener(FileChangeListener listener, File path) {
334
        final DeepListener deep = new DeepListener(listener, path, null);
334
        addRecursiveListener(listener, path, null, null);
335
        deep.init();
336
        addFileChangeListener(deep, path);
337
    }
335
    }
338
336
339
    /**
337
    /**
Lines 380-386 Link Here
380
     * @since org.openide.filesystems 7.37
378
     * @since org.openide.filesystems 7.37
381
     */
379
     */
382
    public static void addRecursiveListener(FileChangeListener listener, File path, Callable<Boolean> stop) {
380
    public static void addRecursiveListener(FileChangeListener listener, File path, Callable<Boolean> stop) {
383
        final DeepListener deep = new DeepListener(listener, path, stop);
381
        addRecursiveListener(listener, path, null, stop);
382
    }
383
384
    /** XXX: Only for java.io.File, but that is probably OK for NetBeans IDE 7.2
385
     * XXX: Copy javadoc
386
     * 
387
     * @param recurseInto a file filter that may return <code>false</code> when
388
     *   a folder should not be traversed into and external changes in it ignored
389
     */
390
    public static void addRecursiveListener(FileChangeListener listener, File path, FileFilter recurseInto, Callable<Boolean> stop) {
391
        final DeepListener deep = new DeepListener(listener, path, recurseInto, stop);
384
        deep.init();
392
        deep.init();
385
        addFileChangeListener(deep, path);
393
        addFileChangeListener(deep, path);
386
    }
394
    }
Lines 395-401 Link Here
395
     * @since org.openide.filesystems 7.28
403
     * @since org.openide.filesystems 7.28
396
     */
404
     */
397
    public static void removeRecursiveListener(FileChangeListener listener, File path) {
405
    public static void removeRecursiveListener(FileChangeListener listener, File path) {
398
        final DeepListener deep = new DeepListener(listener, path, null);
406
        final DeepListener deep = new DeepListener(listener, path, null, null);
399
        // no need to deep.init()
407
        // no need to deep.init()
400
        DeepListener dl = (DeepListener)removeFileChangeListenerImpl(deep, path);
408
        DeepListener dl = (DeepListener)removeFileChangeListenerImpl(deep, path);
401
        dl.run();
409
        dl.run();

Return to bug 207189