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

(-)a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawler.java (-2 / +35 lines)
Lines 53-58 Link Here
53
import java.util.HashSet;
53
import java.util.HashSet;
54
import java.util.Iterator;
54
import java.util.Iterator;
55
import java.util.Map;
55
import java.util.Map;
56
import java.util.Map.Entry;
56
import java.util.Set;
57
import java.util.Set;
57
import java.util.TreeMap;
58
import java.util.TreeMap;
58
import java.util.TreeSet;
59
import java.util.TreeSet;
Lines 114-131 Link Here
114
        if (files != null) {
115
        if (files != null) {
115
            if (files.length > 1) {
116
            if (files.length > 1) {
116
                Map<FileObject, Set<FileObject>> clusters = new HashMap<FileObject, Set<FileObject>>();
117
                Map<FileObject, Set<FileObject>> clusters = new HashMap<FileObject, Set<FileObject>>();
117
                for(FileObject f : files) {
118
                Map<FileObject, StringBuilder> relPaths = new HashMap<FileObject, StringBuilder>();
119
                OUTER: for(FileObject f : files) {
118
                    FileObject parent = f.getParent();
120
                    FileObject parent = f.getParent();
119
                    Set<FileObject> cluster = clusters.get(parent);
121
                    Set<FileObject> cluster = clusters.get(parent);
120
                    if (cluster == null) {
122
                    if (cluster == null) {
123
                        StringBuilder currentRelPath = getRelativePath(root, parent);
124
                        
125
                        for (Iterator<Entry<FileObject, StringBuilder>> it = relPaths.entrySet().iterator(); it.hasNext();) {
126
                            Entry<FileObject, StringBuilder> e = it.next();
127
                            switch (computeStartsRelation(e.getValue(), currentRelPath)) {
128
                                case FIRST_STARTS_WITH_SECOND:
129
                                    //we are currently processing a parent folder of something that was already added, skip the old value:
130
                                    clusters.remove(e.getKey());
131
                                    it.remove();
132
                                    break;
133
                                case SECOND_STARTS_WITH_FIRST:
134
                                    //something existing is a parent folder of what we are processing now - ignore the current request
135
                                    continue OUTER;
136
                            }
137
                        }
121
                        cluster = new HashSet<FileObject>();
138
                        cluster = new HashSet<FileObject>();
122
                        clusters.put(parent, cluster);
139
                        clusters.put(parent, cluster);
140
                        relPaths.put(parent, currentRelPath);
123
                    }
141
                    }
124
                    cluster.add(f);
142
                    cluster.add(f);
125
                }
143
                }
126
                for(FileObject parent : clusters.keySet()) {
144
                for(FileObject parent : clusters.keySet()) {
127
                    Set<FileObject> cluster = clusters.get(parent);
145
                    Set<FileObject> cluster = clusters.get(parent);
128
                    StringBuilder relativePath = getRelativePath(root, parent);
146
                    StringBuilder relativePath = relPaths.get(parent);
129
                    if (relativePath != null) {
147
                    if (relativePath != null) {
130
                        finished = collect(
148
                        finished = collect(
131
                                cluster.toArray(new FileObject[cluster.size()]),
149
                                cluster.toArray(new FileObject[cluster.size()]),
Lines 274-279 Link Here
274
            return null;
292
            return null;
275
        }
293
        }
276
    }
294
    }
295
    
296
    private static enum SubstringKind {
297
        FIRST_STARTS_WITH_SECOND,
298
        SECOND_STARTS_WITH_FIRST,
299
        UNRELATED;
300
    }
301
    private SubstringKind computeStartsRelation(StringBuilder first, StringBuilder second) {
302
        int end = Math.min(first.length(), second.length());
303
        
304
        for (int i = 0; i < end; i++) {
305
            if (first.charAt(i) != second.charAt(i)) return SubstringKind.UNRELATED;
306
        }
307
        
308
        return first.length() > second.length() ? SubstringKind.FIRST_STARTS_WITH_SECOND : SubstringKind.SECOND_STARTS_WITH_FIRST;
309
    } 
277
310
278
    private boolean isVisible (final @NonNull FileObject fo) {
311
    private boolean isVisible (final @NonNull FileObject fo) {
279
        try {
312
        try {
(-)a/parsing.api/test/unit/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawlerTest.java (-4 / +38 lines)
Lines 46-59 Link Here
46
import java.io.File;
46
import java.io.File;
47
import java.io.IOException;
47
import java.io.IOException;
48
import java.net.URL;
48
import java.net.URL;
49
import java.util.ArrayList;
49
import java.util.Arrays;
50
import java.util.Arrays;
50
import java.util.Collection;
51
import java.util.Collection;
52
import java.util.Collections;
51
import java.util.EnumSet;
53
import java.util.EnumSet;
52
import java.util.HashMap;
54
import java.util.HashMap;
53
import java.util.HashSet;
55
import java.util.List;
54
import java.util.Map;
56
import java.util.Map;
55
import java.util.Set;
56
import java.util.regex.Pattern;
57
import java.util.regex.Pattern;
58
import static junit.framework.Assert.assertNull;
57
import org.netbeans.api.java.classpath.ClassPath;
59
import org.netbeans.api.java.classpath.ClassPath;
58
import org.netbeans.junit.NbTestCase;
60
import org.netbeans.junit.NbTestCase;
59
import org.netbeans.modules.parsing.spi.indexing.Indexable;
61
import org.netbeans.modules.parsing.spi.indexing.Indexable;
Lines 303-319 Link Here
303
                "folder2/data3.txt");
305
                "folder2/data3.txt");
304
    }
306
    }
305
307
308
    public void testDuplicateResults1() throws IOException {
309
        File root = new File(getWorkDir(), "src");
310
        String [] paths = new String [] {
311
                "org/pckg1/file1.txt",
312
                "org/pckg1/pckg2/file1.txt",
313
                "org/pckg1/pckg2/file2.txt",
314
        };
315
        
316
        populateFolderStructure(root, paths);
317
        
318
        FileObject rootFO = FileUtil.toFileObject(root);
319
        FileObjectCrawler crawler = new FileObjectCrawler(rootFO, new FileObject[] {rootFO.getFileObject("org/pckg1/pckg2/file1.txt"), rootFO.getFileObject("org/pckg1/pckg2")}, EnumSet.<Crawler.TimeStampAction>of(Crawler.TimeStampAction.UPDATE), null, CR, SuspendSupport.NOP);
320
        assertCollectedFiles("Wrong files collected", crawler.getResources(), new String[] {"org/pckg1/pckg2/file1.txt", "org/pckg1/pckg2/file2.txt"});
321
    }
322
    
323
    public void testDuplicateResults2() throws IOException {
324
        File root = new File(getWorkDir(), "src");
325
        String [] paths = new String [] {
326
                "org/pckg1/file1.txt",
327
                "org/pckg1/pckg2/file1.txt",
328
                "org/pckg1/pckg2/file2.txt",
329
        };
330
        
331
        populateFolderStructure(root, paths);
332
        
333
        FileObject rootFO = FileUtil.toFileObject(root);
334
        FileObjectCrawler crawler = new FileObjectCrawler(rootFO, new FileObject[] {rootFO.getFileObject("org/pckg1/pckg2/file1.txt"), rootFO.getFileObject("org/pckg1/pckg2/file2.txt")}, EnumSet.<Crawler.TimeStampAction>of(Crawler.TimeStampAction.UPDATE), null, CR, SuspendSupport.NOP);
335
        assertCollectedFiles("Wrong files collected", crawler.getResources(), new String[] {"org/pckg1/pckg2/file1.txt", "org/pckg1/pckg2/file2.txt"});
336
    }
337
    
306
    protected void assertCollectedFiles(String message, Collection<Indexable> resources, String... expectedPaths) throws IOException {
338
    protected void assertCollectedFiles(String message, Collection<Indexable> resources, String... expectedPaths) throws IOException {
307
        Set<String> collectedPaths = new HashSet<String>();
339
        List<String> collectedPaths = new ArrayList<String>();
308
        for(Indexable ii : resources) {
340
        for(Indexable ii : resources) {
309
            collectedPaths.add(ii.getRelativePath());
341
            collectedPaths.add(ii.getRelativePath());
310
        }
342
        }
311
        Set<String> expectedPathsFiltered = new HashSet<String>();
343
        List<String> expectedPathsFiltered = new ArrayList<String>();
312
        for(String path : expectedPaths) {
344
        for(String path : expectedPaths) {
313
            if (!path.endsWith("/")) { // crawler only collects files
345
            if (!path.endsWith("/")) { // crawler only collects files
314
                expectedPathsFiltered.add(path);
346
                expectedPathsFiltered.add(path);
315
            }
347
            }
316
        }
348
        }
349
        Collections.sort(collectedPaths);
350
        Collections.sort(expectedPathsFiltered);
317
        assertEquals(message, expectedPathsFiltered, collectedPaths);
351
        assertEquals(message, expectedPathsFiltered, collectedPaths);
318
    }
352
    }
319
353

Return to bug 224783