diff --git a/apisupport/maven.apisupport/test/unit/src/org/netbeans/modules/maven/apisupport/NBMNativeMWITest.java b/apisupport/maven.apisupport/test/unit/src/org/netbeans/modules/maven/apisupport/NBMNativeMWITest.java index b8592b8224c8..402397bd2519 100644 --- a/apisupport/maven.apisupport/test/unit/src/org/netbeans/modules/maven/apisupport/NBMNativeMWITest.java +++ b/apisupport/maven.apisupport/test/unit/src/org/netbeans/modules/maven/apisupport/NBMNativeMWITest.java @@ -38,7 +38,7 @@ public class NBMNativeMWITest extends NbTestCase { - private static final String EXPECTED_JAVAC_PLUGIN_VERSION = "3.15.0"; + private static final String EXPECTED_JAVAC_PLUGIN_VERSION = "3.16.0"; private FileObject wd; diff --git a/ide/editor/src/org/netbeans/modules/editor/EditorModule.java b/ide/editor/src/org/netbeans/modules/editor/EditorModule.java index eb8f3f0848ca..4c12a3330915 100644 --- a/ide/editor/src/org/netbeans/modules/editor/EditorModule.java +++ b/ide/editor/src/org/netbeans/modules/editor/EditorModule.java @@ -145,9 +145,18 @@ public void saveSetting(String settingName, Object value) { initAndCheckEditorKitTypeRegistry("text/html", HTMLEditorKit.class.getName()); //NOI18N initAndCheckEditorKitTypeRegistry("text/rtf", RTFEditorKit.class.getName()); //NOI18N initAndCheckEditorKitTypeRegistry("application/rtf", RTFEditorKit.class.getName()); //NOI18N - + // Now hook up to the JDK's editor kit registry - // XXX: This all should be removed, see IZ #80110 + // TODO: This all should be removed, see IZ #80110 or #9523 + if (!Boolean.parseBoolean(System.getProperty("nb.disable.editorkit.hack", "false" /*TODO true in future*/))) { + LOG.log(Level.WARNING, + """ + Setting content type by mime type String for NetBeans editor kits is no longer supported and will fail on JDK 27 and later, obtain the EditorKit instead: + jtextarea.setContentType("text/x-properties") => + jtextarea.setEditorKit(CloneableEditorSupport.getEditorKit("text/x-properties")) + Set the sytem property 'nb.disable.editorkit.hack=true' to disable this warning. + """ + ); try { Field keyField = JEditorPane.class.getDeclaredField("kitRegistryKey"); // NOI18N keyField.setAccessible(true); @@ -166,21 +175,10 @@ public void saveSetting(String settingName, Object value) { // Hashtable kitMapping = (Hashtable)sun.awt.AppContext.getAppContext().get(key); // sun.awt.AppContext.getAppContext().put(key, new HackMap(kitMapping)); } catch (Throwable t) { - if (debug) { - LOG.log(Level.WARNING, "Can't hack in to the JEditorPane's registry for kits.", t); - } else { - LOG.log(Level.WARNING, "Can''t hack in to the JEditorPane''s registry for kits: {0}", new Object[] {t}); - } + LOG.log(Level.WARNING, "Can't hack in to the JEditorPane's registry to replace editor kits."); } - - // Registration of the editor kits to JEditorPane -// for (int i = 0; i < replacements.length; i++) { -// JEditorPane.registerEditorKitForContentType( -// replacements[i].contentType, -// replacements[i].newKitClassName, -// getClass().getClassLoader() -// ); -// } + } + // removeme end // ------------------------------------------------------------ diff --git a/ide/parsing.lucene/src/org/netbeans/modules/parsing/lucene/LuceneIndex.java b/ide/parsing.lucene/src/org/netbeans/modules/parsing/lucene/LuceneIndex.java index 6fb7be785b26..5e429fa08a3a 100644 --- a/ide/parsing.lucene/src/org/netbeans/modules/parsing/lucene/LuceneIndex.java +++ b/ide/parsing.lucene/src/org/netbeans/modules/parsing/lucene/LuceneIndex.java @@ -230,8 +230,12 @@ private void queryTermsImpl( changeIndexReader(adapter, in); try { - for(LeafReaderContext lrc: in.leaves()) { - TermsEnum te = lrc.reader().terms(field).iterator(); + for (LeafReaderContext lrc: in.leaves()) { + Terms terms = lrc.reader().terms(field); + if (terms == null) { + continue; + } + TermsEnum te = terms.iterator(); if (te.seekCeil(startBytesRef) != TermsEnum.SeekStatus.END) { do { if (cancel != null && cancel.get()) { diff --git a/ide/parsing.lucene/src/org/netbeans/modules/parsing/lucene/MemoryIndex.java b/ide/parsing.lucene/src/org/netbeans/modules/parsing/lucene/MemoryIndex.java index 8dc70d04a6fb..a6466fe3e4c3 100644 --- a/ide/parsing.lucene/src/org/netbeans/modules/parsing/lucene/MemoryIndex.java +++ b/ide/parsing.lucene/src/org/netbeans/modules/parsing/lucene/MemoryIndex.java @@ -245,8 +245,12 @@ public void queryTerms( if (in == null) { return; } - for(LeafReaderContext lrc: in.leaves()) { - TermsEnum te = lrc.reader().terms(field).iterator(); + for (LeafReaderContext lrc: in.leaves()) { + Terms terms = lrc.reader().terms(field); + if (terms == null) { + continue; + } + TermsEnum te = terms.iterator(); if (te.seekCeil(startBytesRef) != TermsEnum.SeekStatus.END) { do { if (cancel != null && cancel.get()) { diff --git a/ide/projectui/src/org/netbeans/modules/project/ui/OpenProjectList.java b/ide/projectui/src/org/netbeans/modules/project/ui/OpenProjectList.java index 982cb07f7156..edf9d6c36387 100644 --- a/ide/projectui/src/org/netbeans/modules/project/ui/OpenProjectList.java +++ b/ide/projectui/src/org/netbeans/modules/project/ui/OpenProjectList.java @@ -27,7 +27,6 @@ import java.io.IOException; import java.lang.ref.WeakReference; import java.net.URL; -import java.text.Collator; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -122,10 +121,6 @@ public final class OpenProjectList { * otherwise we get a deadlock fairly fast */ static final Mutex MUTEX = new Mutex(); - - public static Comparator projectByPath() { - return new ProjectByPathComparator(); - } // Property names public static final String PROPERTY_OPEN_PROJECTS = "OpenProjects"; @@ -221,6 +216,10 @@ public static void waitProjectsFullyOpen() { getDefault().LOAD.waitFinished(0); } + public static Comparator projectByPath() { + return PROJECT_BY_PATH_COMPARATOR; + } + static void preferredProject(final Project lazyP) { if (lazyP != null) { OPENING_RP.post(new Runnable() { @@ -1922,21 +1921,35 @@ public URL getURL() { } - private static class ProjectByPathComparator implements Comparator { - @Override - public int compare(Project p1, Project p2) { - if (p1 == null && p2 == null) { - return 0; - } - if (p1 == null) { - return -1; - } - if (p2 == null) { - return 1; + /// ensures that child dirs follow right after the parent + private static final Comparator PATH_COMPONENT_COMPARATOR = (p1, p2) -> { + String[] comp1 = p1.split("/"); + String[] comp2 = p2.split("/"); + int min = Math.min(comp1.length, comp2.length); + for (int i = 0; i < min; i++) { + int c = comp1[i].compareTo(comp2[i]); + if (c != 0) { + return c; } - return p1.getProjectDirectory().getPath().compareTo(p2.getProjectDirectory().getPath()); } - } + return Integer.compare(comp1.length, comp2.length); + }; + + private static final Comparator PROJECT_BY_PATH_COMPARATOR = (p1, p2) -> { + if (p1 == null && p2 == null) { + return 0; + } + if (p1 == null) { + return -1; + } + if (p2 == null) { + return 1; + } + return PATH_COMPONENT_COMPARATOR.compare( + p1.getProjectDirectory().getPath(), // String normalized with '/' separator + p2.getProjectDirectory().getPath() + ); + }; private final class NbProjectDeletionListener extends FileChangeAdapter { diff --git a/ide/projectui/test/unit/src/org/netbeans/modules/project/ui/OpenProjectListTest.java b/ide/projectui/test/unit/src/org/netbeans/modules/project/ui/OpenProjectListTest.java index ffc848f9956f..dd5f17400032 100644 --- a/ide/projectui/test/unit/src/org/netbeans/modules/project/ui/OpenProjectListTest.java +++ b/ide/projectui/test/unit/src/org/netbeans/modules/project/ui/OpenProjectListTest.java @@ -21,6 +21,7 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.io.File; import java.lang.reflect.Field; import java.net.MalformedURLException; import java.net.URL; @@ -29,6 +30,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; @@ -40,6 +42,7 @@ import java.util.logging.Level; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Stream; import org.netbeans.api.project.FileOwnerQuery; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectManager; @@ -48,6 +51,8 @@ import org.netbeans.junit.MockServices; import org.netbeans.junit.NbTestCase; import org.netbeans.junit.RandomlyFails; +import org.netbeans.modules.masterfs.filebasedfs.fileobjects.FolderObj; +import org.netbeans.modules.masterfs.filebasedfs.naming.NamingFactory; import org.netbeans.modules.project.ui.actions.TestSupport; import org.netbeans.spi.project.SubprojectProvider; import org.netbeans.spi.project.ui.ProjectOpenedHook; @@ -56,6 +61,7 @@ import org.openide.filesystems.URLMapper; import org.openide.loaders.DataObject; import org.openide.loaders.DataObjectNotFoundException; +import org.openide.util.Lookup; import org.openide.util.RequestProcessor; import org.openide.util.lookup.Lookups; @@ -63,7 +69,6 @@ * * @author Jiri Rechtacek */ -@RandomlyFails public class OpenProjectListTest extends NbTestCase { FileObject f1_1_open, f1_2_open, f1_3_close; FileObject f2_1_open; @@ -112,6 +117,7 @@ protected Level logLevel() { OpenProjectList.getDefault().close(OpenProjectList.getDefault().getOpenProjects(), false); } + @RandomlyFails public void testOpen () throws Exception { assertTrue ("No project is open.", OpenProjectList.getDefault ().getOpenProjects ().length == 0); CharSequence log = Log.enable("org.netbeans.ui", Level.FINE); @@ -130,6 +136,7 @@ public void testOpen () throws Exception { */ } + @RandomlyFails public void testListenerOpenClose () throws Exception { assertTrue ("No project is open.", OpenProjectList.getDefault ().getOpenProjects ().length == 0); ChangeListener list = new ChangeListener(); @@ -187,6 +194,7 @@ public void testClose () throws Exception { assertTrue ("Document f2_1_open is still loaded.", handler.openFiles.contains (f2_1_open.toURL ().toExternalForm ())); } + @RandomlyFails public void testSerialize() throws Exception { testOpen(); @@ -209,6 +217,7 @@ public void testSerialize() throws Exception { } } + @RandomlyFails public void testOpenDependingProject () throws Exception { assertTrue ("No project is open.", OpenProjectList.getDefault ().getOpenProjects ().length == 0); CharSequence log = Log.enable("org.netbeans.ui", Level.FINE); @@ -226,6 +235,7 @@ public void testOpenDependingProject () throws Exception { assertTrue ("Document f2_1_open is loaded.", handler.openFiles.contains (f2_1_open.toURL ().toExternalForm ())); } + @RandomlyFails public void testCloseProjectWithoutOpenDocuments () throws Exception { assertTrue ("No project is open.", OpenProjectList.getDefault ().getOpenProjects ().length == 0); OpenProjectList.getDefault ().open (project2, false); @@ -242,6 +252,7 @@ public void testCloseProjectWithoutOpenDocuments () throws Exception { assertFalse ("Project2 is closed.", OpenProjectList.getDefault ().isOpen (project2)); } + @RandomlyFails public void testProjectOpenedClosed() throws Exception { ((TestSupport.TestProject) project1).setLookup(Lookups.fixed(new Object[] { new TestProjectOpenedHookImpl(), @@ -263,6 +274,7 @@ public void testProjectOpenedClosed() throws Exception { assertEquals("both close hooks were called", 2, TestProjectOpenedHookImpl.closed); } + @RandomlyFails public void testNotifyDeleted() throws Exception { FileObject workDir = FileUtil.toFileObject (getWorkDir ()); @@ -299,6 +311,7 @@ public void testNotifyDeleted() throws Exception { assertFalse("project2 is not in recent projects list", OpenProjectList.getDefault().getRecentProjects().contains(prj2)); } + @RandomlyFails public void testMainProject() throws Exception { FileObject workDir = FileUtil.toFileObject (getWorkDir ()); @@ -348,6 +361,7 @@ public void testMainProject() throws Exception { OpenProjectList.getDefault().setMainProject(prj1); } + @RandomlyFails public void testProjectClosedRace() throws Exception { final class POHImpl extends ProjectOpenedHook { @@ -427,6 +441,43 @@ public void run() { } + public void testChildrenFirstPathComparator() throws Exception { + // keep relative or this will fail on windows due to File conversion + List paths = Stream.of( + "a/maven", + "a/maven-indexer", + "a/maven-indexer/indexer-core", + "a/maven/maven-model" + ).map(s -> new File(s.replace("/", File.separator))).map(PathProject::new).toList(); + + List sorted = new ArrayList<>(paths); + sorted.sort(OpenProjectList.projectByPath()); + assertEquals( + "maven-indexer must be last", + "[a/maven, a/maven/maven-model, a/maven-indexer, a/maven-indexer/indexer-core]", + sorted.toString() + ); + } + + private record PathProject(File file) implements Project { + + @Override + public FileObject getProjectDirectory() { + return new FolderObj(file, NamingFactory.fromFile(file)); + } + + @Override + public Lookup getLookup() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String toString() { + return file.toString().replace(File.separator, "/"); + } + + } + // helper code private static class MySubprojectProvider implements SubprojectProvider { diff --git a/java/maven/src/org/netbeans/modules/maven/options/MavenVersionSettings.java b/java/maven/src/org/netbeans/modules/maven/options/MavenVersionSettings.java index 6e2a6ee0d043..cc29eed4bf76 100644 --- a/java/maven/src/org/netbeans/modules/maven/options/MavenVersionSettings.java +++ b/java/maven/src/org/netbeans/modules/maven/options/MavenVersionSettings.java @@ -45,15 +45,15 @@ public final class MavenVersionSettings { static { // TODO update periodically - modifications might require unit test adjustments (e.g NBMNativeMWITest) // (e.g NBMNativeMWITest checks the compiler plugin version) - String nb_version = "RELEASE310"; + String nb_version = "RELEASE320"; String nb_utilities_version = "14.5"; fallback = Map.ofEntries( entry(key("org.netbeans.api", "org-netbeans-modules-editor"), nb_version), // represents all other nb artifacts - entry(key(Constants.GROUP_APACHE_PLUGINS, Constants.PLUGIN_COMPILER), "3.15.0"), - entry(key(Constants.GROUP_APACHE_PLUGINS, Constants.PLUGIN_JAR), "3.5.0"), + entry(key(Constants.GROUP_APACHE_PLUGINS, Constants.PLUGIN_COMPILER), "3.16.0"), + entry(key(Constants.GROUP_APACHE_PLUGINS, Constants.PLUGIN_JAR), "3.5.1"), entry(key(Constants.GROUP_APACHE_PLUGINS, Constants.PLUGIN_RESOURCES), "3.5.0"), - entry(key(Constants.GROUP_APACHE_PLUGINS, Constants.PLUGIN_FAILSAFE), "3.5.6"), - entry(key(Constants.GROUP_APACHE_PLUGINS, Constants.PLUGIN_SUREFIRE), "3.5.6"), + entry(key(Constants.GROUP_APACHE_PLUGINS, Constants.PLUGIN_FAILSAFE), "3.6.0"), + entry(key(Constants.GROUP_APACHE_PLUGINS, Constants.PLUGIN_SUREFIRE), "3.6.0"), entry(key("org.apache.netbeans.utilities", "utilities-parent"), nb_utilities_version), entry(key("org.apache.netbeans.utilities", "nbm-maven-harness"), nb_utilities_version), entry(key("org.apache.netbeans.utilities", "nbm-shared"), nb_utilities_version), diff --git a/nbbuild/antsrc/org/netbeans/nbbuild/RatRelativize.java b/nbbuild/antsrc/org/netbeans/nbbuild/RatRelativize.java new file mode 100644 index 000000000000..3f4c28d727bb --- /dev/null +++ b/nbbuild/antsrc/org/netbeans/nbbuild/RatRelativize.java @@ -0,0 +1,91 @@ +/* + * 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. + */ +package org.netbeans.nbbuild; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +/** + * The apache-rat tasked used to report missing/wrong licensing in the + * repository reports the resources with absolute paths. This task rewrites + * the names to be relative to the root of the repository. + */ +public class RatRelativize extends Task { + + private File file; + + public File getFile() { + return file; + } + + public void setFile(File file) { + this.file = file; + } + + @Override + public void execute() throws BuildException { + Path root = file.getParentFile().getParentFile().getParentFile().toPath(); + try { + // Use the DOM parser for covenience. It should be possible to + // handle this in a streaming manor, but it is much easier to load + // the 15MB, process them and dump them back. + Document doc = DocumentBuilderFactory + .newDefaultInstance() + .newDocumentBuilder() + .parse(file); + + // Fetch all resource Elements (don't work directly on the NodeList + // as this kill performance (the nodelist is refreshed on each + // modifying access to the DOM) + NodeList nl = doc.getElementsByTagName("resource"); + List elementsToModify = new ArrayList<>(nl.getLength()); + for(int i = 0; i < nl.getLength(); i++) { + elementsToModify.add((Element) nl.item(i)); + } + + for(Element resourceElement: elementsToModify) { + Path absolutePath = Path.of(resourceElement.getAttribute("name")); + Path relativePath = root.relativize(absolutePath); + resourceElement.setAttribute("name", relativePath.toString()); + } + + TransformerFactory + .newDefaultInstance() + .newTransformer() + .transform(new DOMSource(doc), new StreamResult(file)); + } catch (ParserConfigurationException | RuntimeException | SAXException | IOException | TransformerException ex) { + throw new BuildException(ex); + } + } +} diff --git a/nbbuild/antsrc/org/netbeans/nbbuild/RatReportTask.java b/nbbuild/antsrc/org/netbeans/nbbuild/RatReportTask.java index 7d1bc48a3fa9..c9fef95ee25e 100644 --- a/nbbuild/antsrc/org/netbeans/nbbuild/RatReportTask.java +++ b/nbbuild/antsrc/org/netbeans/nbbuild/RatReportTask.java @@ -25,8 +25,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedHashMap; @@ -235,7 +233,7 @@ private static String writeFiles(Set listFile, String repo) { private void doPopulateUnapproved(Map moduleRATInfo, Element rootElement, XPath path) throws XPathExpressionException { NodeList evaluate = (NodeList) path.evaluate("descendant::resource[license/@approval=\"false\"]", rootElement, XPathConstants.NODESET); for (int i = 0; i < evaluate.getLength(); i++) { - String resources = relativize(evaluate.item(i).getAttributes().getNamedItem("name").getTextContent()); + String resources = evaluate.item(i).getAttributes().getNamedItem("name").getTextContent(); String moduleName = getModuleName(resources); if (!moduleRATInfo.containsKey(moduleName)) { moduleRATInfo.get(NOT_CLUSTER).addUnapproved(resources); @@ -248,7 +246,7 @@ private void doPopulateUnapproved(Map moduleRATInfo, Element private void doPopulateApproved(Map moduleRATInfo, Element rootElement, XPath path) throws XPathExpressionException { NodeList evaluate = (NodeList) path.evaluate("descendant::resource[license/@approval=\"true\"]", rootElement, XPathConstants.NODESET); for (int i = 0; i < evaluate.getLength(); i++) { - String resources = relativize(evaluate.item(i).getAttributes().getNamedItem("name").getTextContent()); + String resources = evaluate.item(i).getAttributes().getNamedItem("name").getTextContent(); String moduleName = getModuleName(resources); if (!moduleRATInfo.containsKey(moduleName)) { moduleRATInfo.get(NOT_CLUSTER).addApproved(resources); @@ -259,12 +257,6 @@ private void doPopulateApproved(Map moduleRATInfo, Element r } } - private String relativize(String target) { - Path full = Paths.get(target); - Path rootPath = root.toPath(); - return rootPath.relativize(full).toString(); - } - private String getModuleName(String resource) { String moduleName; int firstSeparator = resource.indexOf(File.separator); diff --git a/nbbuild/build.xml b/nbbuild/build.xml index c3b347bdbc20..7fe00ca5b472 100644 --- a/nbbuild/build.xml +++ b/nbbuild/build.xml @@ -2192,16 +2192,27 @@ It is possible to use -Ddebug.port=3234 -Ddebug.pause=y to start the system in d - - - - + + + + + + + + + - +