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

(-)a/java.api.common/nbproject/project.xml (+9 lines)
Lines 30-35 Link Here
30
                    <run-dependency>
30
                    <run-dependency>
31
                        <release-version>1</release-version>
31
                        <release-version>1</release-version>
32
                        <specification-version>1.0</specification-version>
32
                        <specification-version>1.0</specification-version>
33
                    </run-dependency>
34
                </dependency>
35
                <dependency>
36
                    <code-name-base>org.netbeans.api.progress</code-name-base>
37
                    <build-prerequisite/>
38
                    <compile-dependency/>
39
                    <run-dependency>
40
                        <release-version>1</release-version>
41
                        <specification-version>1.17</specification-version>
33
                    </run-dependency>
42
                    </run-dependency>
34
                </dependency>
43
                </dependency>
35
                <dependency>
44
                <dependency>
(-)a/java.api.common/src/org/netbeans/modules/java/api/common/project/ui/wizards/Bundle.properties (+1 lines)
Lines 42-44 Link Here
42
CTL_RemoveFolder=Remove
42
CTL_RemoveFolder=Remove
43
ACSD_FolderList=List of folders
43
ACSD_FolderList=List of folders
44
ACSD_NA=N/A
44
ACSD_NA=N/A
45
TXT_SearchingSourceRoots=Searching source roots
(-)a/java.api.common/src/org/netbeans/modules/java/api/common/project/ui/wizards/FolderList.java (-10 / +49 lines)
Lines 43-50 Link Here
43
43
44
import java.awt.Component;
44
import java.awt.Component;
45
import java.io.File;
45
import java.io.File;
46
import java.util.ArrayList;
47
import java.util.Collection;
48
import java.util.Collections;
46
import java.util.HashSet;
49
import java.util.HashSet;
50
import java.util.List;
47
import java.util.Set;
51
import java.util.Set;
52
import java.util.concurrent.atomic.AtomicBoolean;
48
import javax.swing.DefaultListModel;
53
import javax.swing.DefaultListModel;
49
import javax.swing.DefaultListCellRenderer;
54
import javax.swing.DefaultListCellRenderer;
50
import javax.swing.JFileChooser;
55
import javax.swing.JFileChooser;
Lines 52-62 Link Here
52
import javax.swing.event.ListSelectionListener;
57
import javax.swing.event.ListSelectionListener;
53
import javax.swing.event.ListSelectionEvent;
58
import javax.swing.event.ListSelectionEvent;
54
import org.netbeans.api.java.project.JavaProjectConstants;
59
import org.netbeans.api.java.project.JavaProjectConstants;
60
import org.netbeans.api.progress.ProgressUtils;
55
import org.netbeans.api.project.FileOwnerQuery;
61
import org.netbeans.api.project.FileOwnerQuery;
56
import org.netbeans.api.project.Project;
62
import org.netbeans.api.project.Project;
57
import org.netbeans.api.project.SourceGroup;
63
import org.netbeans.api.project.SourceGroup;
58
import org.netbeans.api.project.Sources;
64
import org.netbeans.api.project.Sources;
59
import org.netbeans.modules.java.api.common.project.ui.customizer.SourceRootsUi;
65
import org.netbeans.modules.java.api.common.project.ui.customizer.SourceRootsUi;
66
import org.netbeans.spi.java.project.support.JavadocAndSourceRootDetection;
60
import org.openide.filesystems.FileObject;
67
import org.openide.filesystems.FileObject;
61
import org.openide.filesystems.FileUtil;
68
import org.openide.filesystems.FileUtil;
62
import org.openide.util.NbBundle;
69
import org.openide.util.NbBundle;
Lines 229-252 Link Here
229
        chooser.setMultiSelectionEnabled(true);
236
        chooser.setMultiSelectionEnabled(true);
230
        if (this.lastUsedFolder != null && this.lastUsedFolder.isDirectory()) {
237
        if (this.lastUsedFolder != null && this.lastUsedFolder.isDirectory()) {
231
            chooser.setCurrentDirectory (this.lastUsedFolder);
238
            chooser.setCurrentDirectory (this.lastUsedFolder);
232
        }        
239
        }
233
        else if (this.projectFolder != null && this.projectFolder.isDirectory()) {
240
        else if (this.projectFolder != null && this.projectFolder.isDirectory()) {
234
            chooser.setCurrentDirectory (this.projectFolder);            
241
            chooser.setCurrentDirectory (this.projectFolder);
235
        }                        
242
        }
236
        if (chooser.showOpenDialog(this)== JFileChooser.APPROVE_OPTION) {
243
        if (chooser.showOpenDialog(this)== JFileChooser.APPROVE_OPTION) {
237
            File[] files = chooser.getSelectedFiles();
244
            final AtomicBoolean cancel = new AtomicBoolean();
238
            int[] indecesToSelect = new int[files.length];
245
            final File[] files = normalizeFiles(chooser.getSelectedFiles());
246
            final List<File> toAdd = Collections.synchronizedList(new ArrayList<File>());
247
            final Runnable task = new Runnable() {
248
                public void run() {
249
                    for (File file : files) {
250
                        if (cancel.get()) {
251
                            return;
252
                        }
253
                        final Collection<? extends FileObject> detectedRoots = JavadocAndSourceRootDetection.findSourceRoots(FileUtil.toFileObject(file),cancel);
254
                        if (detectedRoots.isEmpty()) {
255
                            toAdd.add(file);
256
                        }
257
                        else {
258
                            for (FileObject detectedRoot : detectedRoots) {
259
                                toAdd.add (FileUtil.toFile(detectedRoot));
260
                            }
261
                        }
262
                    }
263
                }
264
            };
265
            ProgressUtils.runOffEventDispatchThread(task, NbBundle.getMessage(FolderList.class, "TXT_SearchingSourceRoots"), cancel, true);
266
            File[] toAddArr;
267
            synchronized (toAdd) {
268
                toAddArr = cancel.get() ? files : toAdd.toArray(new File[toAdd.size()]);
269
            }
270
            int[] indecesToSelect = new int[toAdd.size()];
239
            DefaultListModel model = (DefaultListModel)this.roots.getModel();
271
            DefaultListModel model = (DefaultListModel)this.roots.getModel();
240
            Set<File> invalidRoots = new HashSet<File>();
272
            Set<File> invalidRoots = new HashSet<File>();
241
            File[] relatedFolders = this.relatedFolderList == null ? 
273
            File[] relatedFolders = this.relatedFolderList == null ?
242
                new File[0] : this.relatedFolderList.getFiles();
274
                new File[0] : this.relatedFolderList.getFiles();
243
            for (int i=0, index=model.size(); i<files.length; i++, index++) {
275
            for (int i=0, index=model.size(); i<toAddArr.length; i++, index++) {
244
                File normalizedFile = FileUtil.normalizeFile(files[i]);
276
                File normalizedFile = toAddArr[i];
245
                if (!isValidRoot(normalizedFile, relatedFolders, this.projectFolder)) {
277
                if (!isValidRoot(normalizedFile, relatedFolders, this.projectFolder)) {
246
                    invalidRoots.add (normalizedFile);
278
                    invalidRoots.add (normalizedFile);
247
                }
279
                }
248
                else {
280
                else {
249
                    int pos = model.indexOf (normalizedFile);                
281
                    int pos = model.indexOf (normalizedFile);
250
                    if (pos == -1) {
282
                    if (pos == -1) {
251
                        model.addElement (normalizedFile);
283
                        model.addElement (normalizedFile);
252
                        indecesToSelect[i] = index;
284
                        indecesToSelect[i] = index;
Lines 267-273 Link Here
267
            }
299
            }
268
        }
300
        }
269
    }//GEN-LAST:event_addButtonActionPerformed
301
    }//GEN-LAST:event_addButtonActionPerformed
270
    
302
303
    private static File[] normalizeFiles(final File... files) {
304
        for (int i=0; i< files.length; i++) {
305
            files[i] = FileUtil.normalizeFile(files[i]);
306
        }
307
        return files;
308
    }
309
271
    public static boolean isValidRoot (File file, File[] relatedRoots, File projectFolder) {
310
    public static boolean isValidRoot (File file, File[] relatedRoots, File projectFolder) {
272
        Project p;
311
        Project p;
273
        if ((p = FileOwnerQuery.getOwner(file.toURI()))!=null 
312
        if ((p = FileOwnerQuery.getOwner(file.toURI()))!=null 
(-)a/java.project/apichanges.xml (+16 lines)
Lines 106-111 Link Here
106
    <!-- ACTUAL CHANGES BEGIN HERE: -->
106
    <!-- ACTUAL CHANGES BEGIN HERE: -->
107
107
108
    <changes>
108
    <changes>
109
        <change id="JavadocAndSourceRootDetection.findSourceRoots">
110
            <api name="general"/>
111
            <summary>Added JavadocAndSourceRootDetection.findSourceRoots method to find all source roots under the given folder</summary>
112
            <version major="1" minor="31"/>
113
            <date day="15" month="1" year="2010"/>
114
            <author login="tzezula"/>
115
            <compatibility addition="yes"/>
116
            <description>
117
                <p>
118
                    Added JavadocAndSourceRootDetection.findSourceRoots to find all source roots under the given folder.
119
                    This method is used by the import source roots in the new project wizards.
120
                </p>
121
            </description>
122
            <class package="org.netbeans.spi.java.project.support" name="JavadocAndSourceRootDetection"/>
123
            <issue number="179427"/>
124
        </change>
109
        <change id="JavaRunner-runtime-encoding">
125
        <change id="JavaRunner-runtime-encoding">
110
            <api name="general"/>
126
            <api name="general"/>
111
            <summary>Added JavaRunner.PROP_RUNTIME_ENCODING property for COS Runner</summary>
127
            <summary>Added JavaRunner.PROP_RUNTIME_ENCODING property for COS Runner</summary>
(-)a/java.project/manifest.mf (-1 / +1 lines)
Lines 3-9 Link Here
3
OpenIDE-Module-Layer: org/netbeans/modules/java/project/layer.xml
3
OpenIDE-Module-Layer: org/netbeans/modules/java/project/layer.xml
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/project/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/project/Bundle.properties
5
OpenIDE-Module-Needs: javax.script.ScriptEngine.freemarker
5
OpenIDE-Module-Needs: javax.script.ScriptEngine.freemarker
6
OpenIDE-Module-Specification-Version: 1.30
6
OpenIDE-Module-Specification-Version: 1.31
7
OpenIDE-Module-Recommends: org.netbeans.spi.java.project.runner.JavaRunnerImplementation
7
OpenIDE-Module-Recommends: org.netbeans.spi.java.project.runner.JavaRunnerImplementation
8
AutoUpdate-Show-In-Client: false
8
AutoUpdate-Show-In-Client: false
9
9
(-)a/java.project/src/org/netbeans/spi/java/project/support/JavadocAndSourceRootDetection.java (-1 / +55 lines)
Lines 45-57 Link Here
45
import java.io.InputStream;
45
import java.io.InputStream;
46
import java.io.InputStreamReader;
46
import java.io.InputStreamReader;
47
import java.io.Reader;
47
import java.io.Reader;
48
import java.util.Collection;
49
import java.util.Collections;
50
import java.util.LinkedList;
51
import java.util.List;
52
import java.util.concurrent.atomic.AtomicBoolean;
48
import java.util.logging.Level;
53
import java.util.logging.Level;
49
import java.util.logging.Logger;
54
import java.util.logging.Logger;
50
import java.util.regex.Matcher;
55
import java.util.regex.Matcher;
51
import java.util.regex.Pattern;
56
import java.util.regex.Pattern;
57
import org.netbeans.api.annotations.common.NonNull;
58
import org.netbeans.api.annotations.common.NullAllowed;
52
import org.netbeans.modules.classfile.ClassFile;
59
import org.netbeans.modules.classfile.ClassFile;
53
import org.netbeans.modules.classfile.ClassName;
60
import org.netbeans.modules.classfile.ClassName;
54
import org.openide.filesystems.FileObject;
61
import org.openide.filesystems.FileObject;
62
import org.openide.filesystems.FileUtil;
55
import org.openide.util.Exceptions;
63
import org.openide.util.Exceptions;
56
import org.openide.util.Parameters;
64
import org.openide.util.Parameters;
57
65
Lines 103-109 Link Here
103
        }
111
        }
104
        return null;
112
        return null;
105
    }
113
    }
106
    
114
115
    /**
116
     * Finds Java sources roots inside of given folder.
117
     *
118
     * @param folder to start search in; routine will traverse subfolders
119
     *  to find a Java file to detect package root; cannot be null; must be folder
120
     * @param canceled if set to true the method immediatelly returns roots it has alredy found,
121
     * may be null
122
     * @return {@link Collection} of found package roots
123
     * @since 1.31
124
     */
125
    public static Collection<? extends FileObject> findSourceRoots(final @NonNull FileObject folder, final @NullAllowed AtomicBoolean canceled) {
126
        Parameters.notNull("folder", folder);   //NOI18N
127
        if (!folder.isValid()) {
128
            throw new IllegalArgumentException("Folder: " + FileUtil.getFileDisplayName(folder)+" is not valid.");  //NOI18N
129
        }
130
        if (!folder.isFolder()) {
131
            throw new IllegalArgumentException("The parameter: " + FileUtil.getFileDisplayName(folder) + " has to be a directory.");    //NOI18N
132
        }
133
        final List<FileObject> result = new LinkedList<FileObject>();
134
        findAllSourceRoots(folder, result, canceled, 0);
135
        return Collections.unmodifiableList(result);
136
    }
107
    /**
137
    /**
108
     * Returns package root of the given java or class file.
138
     * Returns package root of the given java or class file.
109
     *
139
     *
Lines 120-125 Link Here
120
        }
150
        }
121
    }
151
    }
122
152
153
    private static FileObject findAllSourceRoots(final FileObject folder, final Collection<? super FileObject> result,
154
            final AtomicBoolean canceled, final int depth) {
155
        if (depth == 50) {
156
            return null;
157
        }
158
        final FileObject[] children = folder.getChildren();
159
        for (FileObject child : children) {
160
            if (canceled != null && canceled.get()) {
161
                return null;
162
            } else if (child.isData() && "text/x-java".equals(FileUtil.getMIMEType(child, "text/x-java"))) {   //NOI18N
163
                final FileObject root = findPackageRoot(child);
164
                if (root != null) {
165
                    result.add(root);
166
                }
167
                return root;
168
            } else if (child.isFolder()) {
169
                final FileObject upTo = findAllSourceRoots(child, result, canceled, depth+1);
170
                if (upTo != null && !upTo.equals(child)) {
171
                    return upTo;
172
                }
173
            }
174
        }
175
        return null;
176
    }
123
177
124
    private static FileObject findJavadocRoot(FileObject fo, int level) {
178
    private static FileObject findJavadocRoot(FileObject fo, int level) {
125
        FileObject fo1 = fo.getFileObject("package-list", null); // NOI18N
179
        FileObject fo1 = fo.getFileObject("package-list", null); // NOI18N
(-)a/java.project/test/unit/src/org/netbeans/spi/java/project/support/JavadocAndSourceRootDetectionTest.java (+50 lines)
Lines 40-46 Link Here
40
package org.netbeans.spi.java.project.support;
40
package org.netbeans.spi.java.project.support;
41
41
42
import java.io.File;
42
import java.io.File;
43
import java.io.FileWriter;
44
import java.io.IOException;
45
import java.io.PrintWriter;
43
import java.net.URL;
46
import java.net.URL;
47
import java.util.Arrays;
48
import java.util.Collection;
49
import java.util.HashSet;
50
import java.util.Set;
44
import java.util.regex.Matcher;
51
import java.util.regex.Matcher;
45
import org.netbeans.junit.NbTestCase;
52
import org.netbeans.junit.NbTestCase;
46
import org.openide.filesystems.FileObject;
53
import org.openide.filesystems.FileObject;
Lines 110-115 Link Here
110
        assertParse("/*****/package foo;", false, "foo");
117
        assertParse("/*****/package foo;", false, "foo");
111
        // would like to test stack overflow from #154894, but never managed to reproduce it in a unit test (only in standalone j2seproject)
118
        // would like to test stack overflow from #154894, but never managed to reproduce it in a unit test (only in standalone j2seproject)
112
    }
119
    }
120
121
122
    public void testFindAllSourceRoots() throws Exception {
123
        FileUtil.setMIMEType("java", "text/x-java");
124
        final File wd = getWorkDir();
125
        final File root1 = new File (wd,"root1");
126
        final File root2 = new File (new File (wd,"foo"),"root2");
127
        final File root3 = new File (new File (new File (wd,"foo"),"test"),"root3");
128
        final File root4 = new File (wd,"root4");
129
        createJava(root1,"org.me.Test1","package org.me; class Test1{}");
130
        createJava(root2,"org.me.Test2","package org.me; class Test2{}");
131
        createJava(root3,"org.me.Test3","package org.me; class Test3{}");
132
        createJava(root4,"org.me.Test4","package org.me; class Test4{}");
133
        final FileObject wdFo = FileUtil.toFileObject(wd);
134
        assertNotNull(wdFo);
135
        final Collection<? extends FileObject> result = JavadocAndSourceRootDetection.findSourceRoots(wdFo, null);
136
        final Collection<FileObject> expected = Arrays.asList(
137
                FileUtil.toFileObject(root1),
138
                FileUtil.toFileObject(root2),
139
                FileUtil.toFileObject(root3),
140
                FileUtil.toFileObject(root4));
141
        assertEquals (expected, result);
142
    }
143
144
    private static File createJava(final File root, final String fqn, final String content) throws IOException {
145
        final File f = new File (root,fqn.replace('.', File.separatorChar)+".java");
146
        f.getParentFile().mkdirs();
147
        final PrintWriter out = new PrintWriter(new FileWriter(f));
148
        try {
149
            out.println(content);
150
        } finally {
151
            out.close();
152
        }
153
        return f;
154
    }
155
156
    private void assertEquals(final Collection<? extends FileObject> expected, final Collection<? extends FileObject> result) {
157
        assertEquals(expected.size(), result.size());
158
        final Set<FileObject> diff = new HashSet<FileObject>(expected);
159
        diff.removeAll(result);
160
        assertEquals(0, diff.size());
161
    }
162
113
    private void assertParse(String text, boolean packageInfo, String expectedPackage) {
163
    private void assertParse(String text, boolean packageInfo, String expectedPackage) {
114
        Matcher m = (packageInfo ? JavadocAndSourceRootDetection.PACKAGE_INFO : JavadocAndSourceRootDetection.JAVA_FILE).matcher(text);
164
        Matcher m = (packageInfo ? JavadocAndSourceRootDetection.PACKAGE_INFO : JavadocAndSourceRootDetection.JAVA_FILE).matcher(text);
115
        assertEquals("Misparse of:\n" + text, expectedPackage, m.matches() ? m.group(1) : null);
165
        assertEquals("Misparse of:\n" + text, expectedPackage, m.matches() ? m.group(1) : null);

Return to bug 179427