This is an automated email from the ASF dual-hosted git repository.

jlahoda pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new 18524270fd [NETBEANS-6881][NETBEANS-6880][NETBEANS-6921] Additional 
fixes for the multi-file launcher: - checking for null return result for 
getClassPath(COMPILE) - filtering out directories that belong to a project from 
the multi-file launcher source path - more thoroughly prevent creating of the 
multi-file launcher source ClassPath for files under projects - never touch 
read-only filesystems (i.e. typically jars/zip) - do not register the source CP 
into GlobalPathRegistry by de [...]
     new 7fc8a87c21 Merge pull request #6912 from 
lahodaj/multi-file-launcher-fixes
18524270fd is described below

commit 18524270fd822604724ca07acf3b578663d64f40
Author: Jan Lahoda <[email protected]>
AuthorDate: Wed Jan 3 11:12:35 2024 +0100

    [NETBEANS-6881][NETBEANS-6880][NETBEANS-6921] Additional fixes for the 
multi-file launcher:
    - checking for null return result for getClassPath(COMPILE)
    - filtering out directories that belong to a project from the multi-file 
launcher source path
    - more thoroughly prevent creating of the multi-file launcher source 
ClassPath for files under projects
    - never touch read-only filesystems (i.e. typically jars/zip)
    - do not register the source CP into GlobalPathRegistry by default in the 
IDE - the behavior can either be overriden using a localization bundle
---
 .../lsp/client/bindings/CustomIndexerImpl.java     |  7 ++-
 java/java.file.launcher/nbproject/project.xml      | 18 ++++++
 .../launcher/AttributeBasedSingleFileOptions.java  |  6 +-
 .../modules/java/file/launcher/SharedRootData.java | 10 +--
 .../java/file/launcher/SingleSourceFileUtil.java   | 13 +++-
 .../launcher/indexer/CompilerOptionsIndexer.java   | 14 ++++-
 .../launcher/queries/MultiSourceRootProvider.java  | 72 +++++++++++++++++++++-
 .../java/file/launcher/queries/Bundle.properties   | 18 ++++++
 .../modules/java/source/indexing/APTUtils.java     |  8 ++-
 9 files changed, 141 insertions(+), 25 deletions(-)

diff --git 
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/CustomIndexerImpl.java
 
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/CustomIndexerImpl.java
index c46c3d4095..9e97e8c736 100644
--- 
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/CustomIndexerImpl.java
+++ 
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/CustomIndexerImpl.java
@@ -51,8 +51,13 @@ public class CustomIndexerImpl extends CustomIndexer {
 
     @Override
     protected void index(Iterable<? extends Indexable> files, Context context) 
{
+        FileObject root = context.getRoot();
+
+        if (root == null) {
+            return ; //ignore
+        }
+
         handleStoredFiles(context, props -> {
-            FileObject root = context.getRoot();
             for (Indexable i : files) {
                 FileObject file = root.getFileObject(i.getRelativePath());
                 if (file != null) {
diff --git a/java/java.file.launcher/nbproject/project.xml 
b/java/java.file.launcher/nbproject/project.xml
index d5520075de..195981d25e 100644
--- a/java/java.file.launcher/nbproject/project.xml
+++ b/java/java.file.launcher/nbproject/project.xml
@@ -140,6 +140,15 @@
                         <specification-version>1.84</specification-version>
                     </run-dependency>
                 </dependency>
+                <dependency>
+                    
<code-name-base>org.netbeans.modules.parsing.api</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>9.30</specification-version>
+                    </run-dependency>
+                </dependency>
                 <dependency>
                     
<code-name-base>org.netbeans.modules.parsing.indexing</code-name-base>
                     <build-prerequisite/>
@@ -166,6 +175,15 @@
                         <specification-version>1.63</specification-version>
                     </run-dependency>
                 </dependency>
+                <dependency>
+                    
<code-name-base>org.netbeans.spi.editor.hints</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0</release-version>
+                        <specification-version>1.65</specification-version>
+                    </run-dependency>
+                </dependency>
                 <dependency>
                     <code-name-base>org.openide.filesystems</code-name-base>
                     <build-prerequisite/>
diff --git 
a/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/AttributeBasedSingleFileOptions.java
 
b/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/AttributeBasedSingleFileOptions.java
index 586415f3c4..cfa6c4d209 100644
--- 
a/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/AttributeBasedSingleFileOptions.java
+++ 
b/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/AttributeBasedSingleFileOptions.java
@@ -19,8 +19,6 @@
 package org.netbeans.modules.java.file.launcher;
 
 import javax.swing.event.ChangeListener;
-import org.netbeans.api.project.FileOwnerQuery;
-import org.netbeans.api.project.Project;
 import org.netbeans.modules.java.file.launcher.queries.MultiSourceRootProvider;
 import 
org.netbeans.modules.java.file.launcher.spi.SingleFileOptionsQueryImplementation;
 import org.openide.filesystems.FileAttributeEvent;
@@ -38,9 +36,7 @@ public class AttributeBasedSingleFileOptions implements 
SingleFileOptionsQueryIm
 
     @Override
     public Result optionsFor(FileObject file) {
-        Project p = FileOwnerQuery.getOwner(file);
-
-        if (p != null) {
+        if (!SingleSourceFileUtil.isSupportedFile(file)) {
             return null;
         }
 
diff --git 
a/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/SharedRootData.java
 
b/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/SharedRootData.java
index 3c9d909922..98530378dd 100644
--- 
a/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/SharedRootData.java
+++ 
b/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/SharedRootData.java
@@ -18,16 +18,13 @@
  */
 package org.netbeans.modules.java.file.launcher;
 
-import java.io.File;
 import java.io.IOException;
 import java.util.Enumeration;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import java.util.stream.Collectors;
 import org.netbeans.api.annotations.common.CheckForNull;
 import org.netbeans.modules.java.file.launcher.api.SourceLauncher;
 import org.openide.filesystems.FileAttributeEvent;
@@ -36,8 +33,6 @@ import org.openide.filesystems.FileChangeListener;
 import org.openide.filesystems.FileEvent;
 import org.openide.filesystems.FileObject;
 import org.openide.filesystems.FileUtil;
-import org.openide.modules.SpecificationVersion;
-import org.openide.util.Exceptions;
 
 /**
  *
@@ -108,10 +103,7 @@ public class SharedRootData {
         }
         String joinedCommandLine = 
SourceLauncher.joinCommandLines(options.values());
         try {
-            if (
-                    !root.getFileSystem().isReadOnly() // Skip read-only FSes 
(like JarFileSystem)
-                    && 
!joinedCommandLine.equals(root.getAttribute(SingleSourceFileUtil.FILE_VM_OPTIONS))
-            ) {
+            if 
(!joinedCommandLine.equals(root.getAttribute(SingleSourceFileUtil.FILE_VM_OPTIONS)))
 {
                 root.setAttribute(SingleSourceFileUtil.FILE_VM_OPTIONS, 
joinedCommandLine);
             }
         } catch (IOException ex) {
diff --git 
a/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/SingleSourceFileUtil.java
 
b/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/SingleSourceFileUtil.java
index 65b6fc08fd..0d18a7b12c 100644
--- 
a/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/SingleSourceFileUtil.java
+++ 
b/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/SingleSourceFileUtil.java
@@ -34,6 +34,7 @@ import 
org.netbeans.modules.java.file.launcher.spi.SingleFileOptionsQueryImpleme
 import 
org.netbeans.modules.java.file.launcher.spi.SingleFileOptionsQueryImplementation.Result;
 import org.netbeans.spi.java.queries.CompilerOptionsQueryImplementation;
 import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileStateInvalidException;
 import org.openide.filesystems.FileUtil;
 import org.openide.loaders.DataObject;
 import org.openide.util.Lookup;
@@ -74,13 +75,21 @@ public final class SingleSourceFileUtil {
     }
 
     public static boolean isSingleSourceFile(FileObject fObj) {
-        Project p = FileOwnerQuery.getOwner(fObj);
-        if (p != null || !fObj.getExt().equalsIgnoreCase("java")) { //NOI18N
+        if (!isSupportedFile(fObj) || !fObj.getExt().equalsIgnoreCase("java")) 
{ //NOI18N
             return false;
         }
         return true;
     }
 
+    public static boolean isSupportedFile(FileObject file) {
+        try {
+            return !MultiSourceRootProvider.DISABLE_MULTI_SOURCE_ROOT &&
+                   FileOwnerQuery.getOwner(file) == null &&
+                   !file.getFileSystem().isReadOnly();
+        } catch (FileStateInvalidException ex) {
+            return false;
+        }
+    }
     public static Process compileJavaSource(FileObject fileObject) {
         FileObject javac = 
JavaPlatformManager.getDefault().getDefaultPlatform().findTool("javac"); 
//NOI18N
         File javacFile = FileUtil.toFile(javac);
diff --git 
a/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/indexer/CompilerOptionsIndexer.java
 
b/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/indexer/CompilerOptionsIndexer.java
index d541b4c776..b8fe279be4 100644
--- 
a/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/indexer/CompilerOptionsIndexer.java
+++ 
b/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/indexer/CompilerOptionsIndexer.java
@@ -20,11 +20,12 @@ package org.netbeans.modules.java.file.launcher.indexer;
 
 import org.netbeans.modules.java.file.launcher.SharedRootData;
 import org.netbeans.api.editor.mimelookup.MimeRegistration;
-import org.netbeans.api.project.FileOwnerQuery;
+import org.netbeans.modules.java.file.launcher.SingleSourceFileUtil;
 import org.netbeans.modules.parsing.spi.indexing.Context;
 import org.netbeans.modules.parsing.spi.indexing.CustomIndexer;
 import org.netbeans.modules.parsing.spi.indexing.CustomIndexerFactory;
 import org.netbeans.modules.parsing.spi.indexing.Indexable;
+import org.openide.filesystems.FileObject;
 
 /**
  *
@@ -35,10 +36,17 @@ public class CompilerOptionsIndexer extends CustomIndexer {
 
     @Override
     protected void index(Iterable<? extends Indexable> files, Context context) 
{
-        if (FileOwnerQuery.getOwner(context.getRoot()) != null) {
+        FileObject root = context.getRoot();
+
+        if (root == null) {
+            return ; //ignore
+        }
+
+        if (!SingleSourceFileUtil.isSupportedFile(root)) {
             return ; //ignore roots under projects
         }
-        SharedRootData.ensureRootRegistered(context.getRoot());
+
+        SharedRootData.ensureRootRegistered(root);
     }
 
 
diff --git 
a/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/queries/MultiSourceRootProvider.java
 
b/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/queries/MultiSourceRootProvider.java
index 7f5061d3fa..ad76218b3e 100644
--- 
a/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/queries/MultiSourceRootProvider.java
+++ 
b/java/java.file.launcher/src/org/netbeans/modules/java/file/launcher/queries/MultiSourceRootProvider.java
@@ -21,6 +21,8 @@ package org.netbeans.modules.java.file.launcher.queries;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeSupport;
 import java.io.IOException;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -32,6 +34,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.WeakHashMap;
+import java.util.concurrent.atomic.AtomicReference;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
 import org.netbeans.api.java.classpath.ClassPath;
@@ -41,6 +44,7 @@ import org.netbeans.api.java.lexer.JavaTokenId;
 import org.netbeans.api.java.platform.JavaPlatformManager;
 import org.netbeans.api.lexer.TokenHierarchy;
 import org.netbeans.api.lexer.TokenSequence;
+import org.netbeans.api.project.FileOwnerQuery;
 import org.netbeans.api.queries.FileEncodingQuery;
 import org.netbeans.modules.java.file.launcher.SingleSourceFileUtil;
 import 
org.netbeans.modules.java.file.launcher.spi.SingleFileOptionsQueryImplementation;
@@ -48,11 +52,14 @@ import org.netbeans.spi.java.classpath.ClassPathFactory;
 import org.netbeans.spi.java.classpath.ClassPathImplementation;
 import static 
org.netbeans.spi.java.classpath.ClassPathImplementation.PROP_RESOURCES;
 import org.netbeans.spi.java.classpath.ClassPathProvider;
+import org.netbeans.spi.java.classpath.FilteringPathResourceImplementation;
 import org.netbeans.spi.java.classpath.PathResourceImplementation;
 import org.netbeans.spi.java.classpath.support.ClassPathSupport;
 import org.openide.filesystems.FileObject;
 import org.openide.filesystems.FileUtil;
+import org.openide.filesystems.URLMapper;
 import org.openide.util.Exceptions;
+import org.openide.util.NbBundle.Messages;
 import org.openide.util.lookup.ServiceProvider;
 import org.openide.util.lookup.ServiceProviders;
 
@@ -89,7 +96,7 @@ public class MultiSourceRootProvider implements 
ClassPathProvider {
     }
 
     private ClassPath getSourcePath(FileObject file) {
-        if (DISABLE_MULTI_SOURCE_ROOT) return null;
+        if (!SingleSourceFileUtil.isSupportedFile(file)) return null;
         synchronized (this) {
             //XXX: what happens if there's a Java file in user's home???
             if (file.isValid() && file.isData() && 
"text/x-java".equals(file.getMIMEType())) {
@@ -116,8 +123,10 @@ public class MultiSourceRootProvider implements 
ClassPathProvider {
                         }
 
                         return root2SourceCP.computeIfAbsent(root, r -> {
-                            ClassPath srcCP = 
ClassPathSupport.createClassPath(r);
-                            
GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, new ClassPath[] 
{srcCP});
+                            ClassPath srcCP = 
ClassPathSupport.createClassPath(Arrays.asList(new 
RootPathResourceImplementation(r)));
+                            if (registerRoot(r)) {
+                                
GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, new ClassPath[] 
{srcCP});
+                            }
                             return srcCP;
                         });
                     } catch (IOException ex) {
@@ -234,6 +243,13 @@ public class MultiSourceRootProvider implements 
ClassPathProvider {
         }
     }
 
+    @Messages({
+        "SETTING_AutoRegisterAsRoot=false"
+    })
+    private static boolean registerRoot(FileObject root) {
+        return "true".equals(Bundle.SETTING_AutoRegisterAsRoot());
+    }
+
     private static final class AttributeBasedClassPathImplementation 
implements ChangeListener, ClassPathImplementation {
         private final PropertyChangeSupport pcs = new 
PropertyChangeSupport(this);
         private final SingleFileOptionsQueryImplementation.Result delegate;
@@ -299,4 +315,54 @@ public class MultiSourceRootProvider implements 
ClassPathProvider {
 
     }
 
+    private static final class RootPathResourceImplementation implements 
FilteringPathResourceImplementation {
+
+        private final URL root;
+        private final URL[] roots;
+        private final AtomicReference<String> lastCheckedAsIncluded = new 
AtomicReference<>();
+
+        public RootPathResourceImplementation(FileObject root) {
+            this.root = root.toURL();
+            this.roots = new URL[] {this.root};
+        }
+        
+        @Override
+        public boolean includes(URL root, String resource) {
+            if (!resource.endsWith("/")) {
+                int lastSlash = resource.lastIndexOf('/');
+                if (lastSlash != (-1)) {
+                    resource = resource.substring(0, lastSlash + 1);
+                }
+            }
+            if (resource.equals(lastCheckedAsIncluded.get())) {
+                return true;
+            }
+            FileObject fo = URLMapper.findFileObject(root);
+            fo = fo != null ? fo.getFileObject(resource) : null;
+            boolean included = fo == null || FileOwnerQuery.getOwner(fo) == 
null;
+            if (included) {
+                lastCheckedAsIncluded.set(resource);
+            }
+            return included;
+        }
+
+        @Override
+        public URL[] getRoots() {
+            return roots;
+        }
+
+        @Override
+        public ClassPathImplementation getContent() {
+            return null;
+        }
+
+        @Override
+        public void addPropertyChangeListener(PropertyChangeListener listener) 
{
+        }
+
+        @Override
+        public void removePropertyChangeListener(PropertyChangeListener 
listener) {
+        }
+        
+    }
 }
diff --git 
a/java/java.lsp.server/nbcode/branding/modules/org-netbeans-modules-java-file-launcher.jar/org/netbeans/modules/java/file/launcher/queries/Bundle.properties
 
b/java/java.lsp.server/nbcode/branding/modules/org-netbeans-modules-java-file-launcher.jar/org/netbeans/modules/java/file/launcher/queries/Bundle.properties
new file mode 100644
index 0000000000..684c2d3a5f
--- /dev/null
+++ 
b/java/java.lsp.server/nbcode/branding/modules/org-netbeans-modules-java-file-launcher.jar/org/netbeans/modules/java/file/launcher/queries/Bundle.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+SETTING_AutoRegisterAsRoot=true
diff --git 
a/java/java.source.base/src/org/netbeans/modules/java/source/indexing/APTUtils.java
 
b/java/java.source.base/src/org/netbeans/modules/java/source/indexing/APTUtils.java
index 5f47ca7cd4..58f01106fc 100644
--- 
a/java/java.source.base/src/org/netbeans/modules/java/source/indexing/APTUtils.java
+++ 
b/java/java.source.base/src/org/netbeans/modules/java/source/indexing/APTUtils.java
@@ -135,7 +135,9 @@ public class APTUtils implements ChangeListener, 
PropertyChangeListener {
         this.root = root;
         bootPath = ClassPath.getClassPath(root, ClassPath.BOOT);
         compilePath = ClassPath.getClassPath(root, ClassPath.COMPILE);
-        compilePath.addPropertyChangeListener(this);
+        if (compilePath != null) {
+            compilePath.addPropertyChangeListener(this);
+        }
         processorPath = new AtomicReference<>(ClassPath.getClassPath(root, 
JavaClassPathConstants.PROCESSOR_PATH));
         processorModulePath = new 
AtomicReference<>(ClassPath.getClassPath(root, 
JavaClassPathConstants.MODULE_PROCESSOR_PATH));
         aptOptions = 
AnnotationProcessingQuery.getAnnotationProcessingOptions(root);
@@ -360,7 +362,9 @@ public class APTUtils implements ChangeListener, 
PropertyChangeListener {
                     compilePath.removePropertyChangeListener(this);
                 }
                 compilePath = ClassPath.getClassPath(root, ClassPath.COMPILE);
-                compilePath.addPropertyChangeListener(this);
+                if (compilePath != null) {
+                    compilePath.addPropertyChangeListener(this);
+                }
                 listenOnProcessorPath(pp, this);
                 classLoaderCache = null;
             }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to