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 134805
Collapse All | Expand All

(-)a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/FileEventLog.java (+140 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of either the GNU
7
 * General Public License Version 2 only ("GPL") or the Common
8
 * Development and Distribution License("CDDL") (collectively, the
9
 * "License"). You may not use this file except in compliance with the
10
 * License. You can obtain a copy of the License at
11
 * http://www.netbeans.org/cddl-gplv2.html
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
 * specific language governing permissions and limitations under the
14
 * License.  When distributing the software, include this License Header
15
 * Notice in each file and include the License file at
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
17
 * particular file as subject to the "Classpath" exception as provided
18
 * by Sun in the GPL Version 2 section of the License file that
19
 * accompanied this code. If applicable, add the following below the
20
 * License Header, with the fields enclosed by brackets [] replaced by
21
 * your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.parsing.impl.indexing;
41
42
import java.net.URL;
43
import java.util.HashMap;
44
import java.util.IdentityHashMap;
45
import java.util.LinkedList;
46
import java.util.List;
47
import java.util.Map;
48
import java.util.logging.Logger;
49
import org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater.Work;
50
import org.openide.filesystems.FileEvent;
51
import org.openide.filesystems.FileStateInvalidException;
52
53
/**
54
 *
55
 * @author Tomas Zezula
56
 */
57
class FileEventLog implements Runnable {
58
59
    private static final Logger LOG = Logger.getLogger(FileEventLog.class.getName());
60
61
    public static enum FileOp {
62
       DELETE,
63
       CREATE
64
    };
65
66
    private final Map<URL,Map<URL,Pair<FileEventLog.FileOp,Work>>> changes;
67
68
    public FileEventLog() {
69
        this.changes = new HashMap<URL, Map<URL,Pair<FileEventLog.FileOp,Work>>>();
70
    }
71
72
73
    public void record (final FileOp operation, final URL root, final FileEvent event, final Work work) {
74
            assert operation != null;
75
            assert root != null;
76
            assert event != null;
77
            assert root != null;
78
            try {
79
                record(operation, root, event.getFile().getURL(), event, work);
80
            } catch (FileStateInvalidException e) {
81
                e.printStackTrace();
82
            }
83
        }
84
85
    public void record (final FileOp operation, final URL root, final URL fileURL, FileEvent event, final Work work) {
86
            assert operation != null;
87
            assert root != null;
88
            assert fileURL != null;
89
            assert root != null;
90
            Map<URL,Pair<FileOp,Work>> rootSlot = changes.get(root);
91
            if (rootSlot == null) {
92
                rootSlot = new HashMap<URL,Pair<FileOp,Work>>();
93
                changes.put(root, rootSlot);
94
            }
95
            rootSlot.put(fileURL, Pair.<FileOp,Work>of(operation,work));
96
            event.runWhenDeliveryOver(this);
97
        }
98
99
        public void run () {
100
            try {
101
                commit();
102
            } finally {
103
                cleanUp();
104
            }
105
        }
106
107
        private void commit () {
108
            final List<Work> first = new LinkedList<Work>();
109
            final List<Work> rest = new LinkedList<Work>();
110
            final IdentityHashMap<Work,Work> seenDelete = new IdentityHashMap<Work, Work>();
111
            for (Map<URL,Pair<FileOp,Work>> changesInRoot : changes.values()) {
112
                for (Pair<FileOp,Work> desc : changesInRoot.values()) {
113
                    if (desc.first == FileOp.DELETE) {
114
                        if (!seenDelete.containsKey(desc.second)) {
115
                            first.add(desc.second);
116
                            seenDelete.put(desc.second, desc.second);
117
                        }
118
                    }
119
                    else {
120
                        rest.add(desc.second);
121
                    }
122
                }
123
            }
124
            final RepositoryUpdater ru = RepositoryUpdater.getDefault();
125
            for (Work wrk : first) {
126
                LOG.finer("SCHEDULING: " + wrk);    //NOI18N
127
                ru.scheduleWork(wrk, false);
128
            }
129
            for (Work wrk : rest) {
130
                LOG.finer("SCHEDULING: " + wrk);    //NOI18N
131
                ru.scheduleWork(wrk, false);
132
            }
133
        }
134
135
        private void cleanUp() {
136
            this.changes.clear();
137
        }
138
139
140
}
(-)a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/Pair.java (+84 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of either the GNU
7
 * General Public License Version 2 only ("GPL") or the Common
8
 * Development and Distribution License("CDDL") (collectively, the
9
 * "License"). You may not use this file except in compliance with the
10
 * License. You can obtain a copy of the License at
11
 * http://www.netbeans.org/cddl-gplv2.html
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
 * specific language governing permissions and limitations under the
14
 * License.  When distributing the software, include this License Header
15
 * Notice in each file and include the License file at
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
17
 * particular file as subject to the "Classpath" exception as provided
18
 * by Sun in the GPL Version 2 section of the License file that
19
 * accompanied this code. If applicable, add the following below the
20
 * License Header, with the fields enclosed by brackets [] replaced by
21
 * your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.parsing.impl.indexing;
41
42
/**
43
 *
44
 * @author Tomas Zezula
45
 */
46
final class Pair<P,K> {
47
48
    public final P first;
49
    public final K second;
50
51
    private Pair (P first, K second) {
52
        this.first = first;
53
        this.second = second;
54
    }
55
56
57
    public static <P,K> Pair<P,K> of (P first, K second) {
58
        return new Pair<P,K> (first,second);
59
    }
60
61
62
    @Override
63
    public int hashCode () {
64
        int hashCode  = 0;
65
        hashCode ^= first == null ? 0 : first.hashCode();
66
        hashCode ^= second == null ? 0: second.hashCode();
67
        return hashCode;
68
    }
69
70
    @Override
71
    public boolean equals (final Object other) {
72
        if (other instanceof Pair) {
73
            Pair otherPair = (Pair) other;
74
            return (this.first == null ? otherPair.first == null : this.first.equals(otherPair.first)) &&
75
                   (this.second == null ? otherPair.second == null : this.second.equals(otherPair.second));
76
        }
77
        return false;
78
    }
79
80
    @Override
81
    public String toString () {
82
        return String.format("Pair[%s,%s]", first,second);
83
    }
84
}
(-)a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/RepositoryUpdater.java (-18 / +35 lines)
Lines 119-124 Link Here
119
import org.openide.filesystems.FileStateInvalidException;
119
import org.openide.filesystems.FileStateInvalidException;
120
import org.openide.filesystems.FileUtil;
120
import org.openide.filesystems.FileUtil;
121
import org.openide.filesystems.URLMapper;
121
import org.openide.filesystems.URLMapper;
122
import org.openide.util.Exceptions;
122
import org.openide.util.Lookup;
123
import org.openide.util.Lookup;
123
import org.openide.util.NbBundle;
124
import org.openide.util.NbBundle;
124
import org.openide.util.Parameters;
125
import org.openide.util.Parameters;
Lines 350-355 Link Here
350
    // -----------------------------------------------------------------------
351
    // -----------------------------------------------------------------------
351
    // FileChangeListener implementation
352
    // FileChangeListener implementation
352
    // -----------------------------------------------------------------------
353
    // -----------------------------------------------------------------------
354
    
355
    final FileEventLog eventQueue = new FileEventLog();
353
356
354
    public void fileFolderCreated(FileEvent fe) {
357
    public void fileFolderCreated(FileEvent fe) {
355
        if (!authorize(fe)) {
358
        if (!authorize(fe)) {
Lines 369-381 Link Here
369
                boolean sourcForBinaryRoot = sourcesForBinaryRoots.contains(root);
372
                boolean sourcForBinaryRoot = sourcesForBinaryRoots.contains(root);
370
                ClassPath.Entry entry = sourcForBinaryRoot ? null : getClassPathEntry(URLMapper.findFileObject(root));
373
                ClassPath.Entry entry = sourcForBinaryRoot ? null : getClassPathEntry(URLMapper.findFileObject(root));
371
                if (entry == null || entry.includes(fo)) {
374
                if (entry == null || entry.includes(fo)) {
372
                    scheduleWork(new FileListWork(scannedRoots2Dependencies, root, Collections.singleton(fo), false, false, true, sourcForBinaryRoot), false);
375
                    final Work wrk = new FileListWork(scannedRoots2Dependencies, root, Collections.singleton(fo), false, false, true, sourcForBinaryRoot);
376
                    eventQueue.record(FileEventLog.FileOp.CREATE, root, fe, wrk);
373
                    processed = true;
377
                    processed = true;
374
                }
378
                }
375
            } else {
379
            } else {
376
                root = getOwningBinaryRoot(fo);
380
                root = getOwningBinaryRoot(fo);
377
                if (root != null) {
381
                if (root != null) {
378
                    scheduleWork(new BinaryWork(root), false);
382
                    final Work wrk = new BinaryWork(root);
383
                    eventQueue.record(FileEventLog.FileOp.CREATE, root, root, fe, wrk);
379
                    processed = true;
384
                    processed = true;
380
                }
385
                }
381
            }
386
            }
Lines 406-418 Link Here
406
                boolean sourceForBinaryRoot = sourcesForBinaryRoots.contains(root);
411
                boolean sourceForBinaryRoot = sourcesForBinaryRoots.contains(root);
407
                ClassPath.Entry entry = sourceForBinaryRoot ? null : getClassPathEntry(URLMapper.findFileObject(root));
412
                ClassPath.Entry entry = sourceForBinaryRoot ? null : getClassPathEntry(URLMapper.findFileObject(root));
408
                if (entry == null || entry.includes(fo)) {
413
                if (entry == null || entry.includes(fo)) {
409
                    scheduleWork(new FileListWork(scannedRoots2Dependencies, root, Collections.singleton(fo), false, false, true, sourceForBinaryRoot), false);
414
                    final Work wrk = new FileListWork(scannedRoots2Dependencies, root, Collections.singleton(fo), false, false, true, sourceForBinaryRoot);
415
                    eventQueue.record(FileEventLog.FileOp.CREATE, root, fe, wrk);
410
                    processed = true;
416
                    processed = true;
411
                }
417
                }
412
            } else {
418
            } else {
413
                root = getOwningBinaryRoot(fo);
419
                root = getOwningBinaryRoot(fo);
414
                if (root != null) {
420
                if (root != null) {
415
                    scheduleWork(new BinaryWork(root), false);
421
                    final Work wrk = new BinaryWork(root);
422
                    eventQueue.record(FileEventLog.FileOp.CREATE, root, root, fe, wrk);
416
                    processed = true;
423
                    processed = true;
417
                }
424
                }
418
            }
425
            }
Lines 439-451 Link Here
439
                if (fo.isData() /*&& FileUtil.getMIMEType(fo, recognizers.getMimeTypes())!=null*/) {
446
                if (fo.isData() /*&& FileUtil.getMIMEType(fo, recognizers.getMimeTypes())!=null*/) {
440
                    String relativePath = FileUtil.getRelativePath(URLMapper.findFileObject(root), fo);
447
                    String relativePath = FileUtil.getRelativePath(URLMapper.findFileObject(root), fo);
441
                    assert relativePath != null : "FileObject not under root: f=" + fo + ", root=" + root; //NOI18N
448
                    assert relativePath != null : "FileObject not under root: f=" + fo + ", root=" + root; //NOI18N
442
                    scheduleWork(new DeleteWork(root, Collections.singleton(relativePath)), false);
449
                    final Work wrk = new DeleteWork(root, Collections.singleton(relativePath));
450
                    eventQueue.record(FileEventLog.FileOp.DELETE, root, fe, wrk);
443
                    processed = true;
451
                    processed = true;
444
                }
452
                }
445
            } else {
453
            } else {
446
                root = getOwningBinaryRoot(fo);
454
                root = getOwningBinaryRoot(fo);
447
                if (root != null) {
455
                if (root != null) {
448
                    scheduleWork(new BinaryWork(root), false);
456
                    final Work wrk = new BinaryWork(root);
457
                    eventQueue.record(FileEventLog.FileOp.DELETE, root, root, fe, wrk);
449
                    processed = true;
458
                    processed = true;
450
                }
459
                }
451
            }
460
            }
Lines 472-497 Link Here
472
            if (root != null) {
481
            if (root != null) {
473
                FileObject rootFo = URLMapper.findFileObject(root);
482
                FileObject rootFo = URLMapper.findFileObject(root);
474
                String oldFilePath = FileUtil.getRelativePath(rootFo, newFile.getParent()) + "/" + oldNameExt; //NOI18N
483
                String oldFilePath = FileUtil.getRelativePath(rootFo, newFile.getParent()) + "/" + oldNameExt; //NOI18N
475
476
                if (newFile.isData()) {
484
                if (newFile.isData()) {
477
                    scheduleWork(new DeleteWork(root, Collections.singleton(oldFilePath)), false);
485
                    final Work work = new DeleteWork(root, Collections.singleton(oldFilePath));
486
                    try {
487
                        eventQueue.record(FileEventLog.FileOp.DELETE, root, Util.resolveUrl(root, oldFilePath), fe, work);
488
                    } catch (MalformedURLException e) {
489
                        Exceptions.printStackTrace(e);
490
                    }
478
                } else {
491
                } else {
479
                    Set<String> oldFilePaths = new HashSet<String>();
492
                    Set<String> oldFilePaths = new HashSet<String>();
480
                    collectFilePaths(newFile, oldFilePath, oldFilePaths);
493
                    collectFilePaths(newFile, oldFilePath, oldFilePaths);
481
                    scheduleWork(new DeleteWork(root, oldFilePaths), false);
494
                    //ugly: need to register work for every file
495
                    for (String path : oldFilePaths) {
496
                        try {
497
                            final Work work = new DeleteWork(root, oldFilePaths);
498
                            eventQueue.record(FileEventLog.FileOp.DELETE, root, Util.resolveUrl(root, path), fe, work);
499
                        } catch (MalformedURLException e) {
500
                            Exceptions.printStackTrace(e);
501
                        }
502
                    }
482
                }
503
                }
504
                
483
505
484
                if (VisibilityQuery.getDefault().isVisible(newFile) && newFile.isData()) {
506
                if (VisibilityQuery.getDefault().isVisible(newFile) && newFile.isData()) {
485
                    final boolean sourceForBinaryRoot = sourcesForBinaryRoots.contains(root);
507
                    final boolean sourceForBinaryRoot = sourcesForBinaryRoots.contains(root);
486
                    ClassPath.Entry entry = sourceForBinaryRoot ? null : getClassPathEntry(rootFo);
508
                    ClassPath.Entry entry = sourceForBinaryRoot ? null : getClassPathEntry(rootFo);
487
                    if (entry == null || entry.includes(newFile)) {
509
                    if (entry == null || entry.includes(newFile)) {                        
488
                        // delaying of this task was just copied from the old java.source RepositoryUpdater
489
                        final FileListWork flw = new FileListWork(scannedRoots2Dependencies,root, Collections.singleton(newFile), false, false, true, sourceForBinaryRoot);
510
                        final FileListWork flw = new FileListWork(scannedRoots2Dependencies,root, Collections.singleton(newFile), false, false, true, sourceForBinaryRoot);
490
                        RequestProcessor.getDefault().create(new Runnable() {
511
                        eventQueue.record(FileEventLog.FileOp.CREATE, root, fe,flw);
491
                            public void run() {
492
                                scheduleWork(flw, false);
493
                            }
494
                        }).schedule(FILE_LOCKS_DELAY);
495
                    }
512
                    }
496
                }
513
                }
497
                processed = true;
514
                processed = true;
Lines 502-514 Link Here
502
                    if (parentFile != null) {
519
                    if (parentFile != null) {
503
                        try {
520
                        try {
504
                            URL oldBinaryRoot = new File (parentFile, oldNameExt).toURI().toURL();
521
                            URL oldBinaryRoot = new File (parentFile, oldNameExt).toURI().toURL();
505
                            scheduleWork(new BinaryWork(oldBinaryRoot), false);
522
                            eventQueue.record(FileEventLog.FileOp.DELETE, oldBinaryRoot, oldBinaryRoot, fe, new BinaryWork(oldBinaryRoot));
506
                        } catch (MalformedURLException mue) {
523
                        } catch (MalformedURLException mue) {
507
                            LOGGER.log(Level.WARNING, null, mue);
524
                            LOGGER.log(Level.WARNING, null, mue);
508
                        }
525
                        }
509
                    }
526
                    }
510
527
511
                    scheduleWork(new BinaryWork(root), false);
528
                    eventQueue.record(FileEventLog.FileOp.CREATE, root, root, fe,new BinaryWork(root));
512
                    processed = true;
529
                    processed = true;
513
                }
530
                }
514
            }
531
            }

Return to bug 134805