diff --git a/app/pom.xml b/app/pom.xml index 25dc1fbaf..6a25933ca 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -31,6 +31,13 @@ gluon-plugin ${project.version} + + org.glassfish + jakarta.json + 2.0.1 + module + runtime + diff --git a/app/src/main/java/com/oracle/javafx/scenebuilder/app/DocumentWindowController.java b/app/src/main/java/com/oracle/javafx/scenebuilder/app/DocumentWindowController.java index f9487bbf1..ce4b14ee1 100644 --- a/app/src/main/java/com/oracle/javafx/scenebuilder/app/DocumentWindowController.java +++ b/app/src/main/java/com/oracle/javafx/scenebuilder/app/DocumentWindowController.java @@ -1405,7 +1405,7 @@ private void updateHierarchyDisplayOption() { public void onManageJarFxml(ActionEvent event) { if(libraryDialogController==null){ libraryDialogController = new LibraryDialogController(editorController, AppSettings.getUserM2Repository(), - AppSettings.getTempM2Repository(), PreferencesController.getSingleton(), getStage()); + PreferencesController.getSingleton(), getStage()); libraryDialogController.setOnAddJar(() -> onImportJarFxml(libraryDialogController.getStage())); libraryDialogController.setOnEditFXML(fxmlPath -> { if (SceneBuilderApp.getSingleton().findFirstUnusedDocumentWindowController().isPresent()) { diff --git a/app/src/main/java/com/oracle/javafx/scenebuilder/app/util/AppSettings.java b/app/src/main/java/com/oracle/javafx/scenebuilder/app/util/AppSettings.java index a2751220c..178eb3b80 100644 --- a/app/src/main/java/com/oracle/javafx/scenebuilder/app/util/AppSettings.java +++ b/app/src/main/java/com/oracle/javafx/scenebuilder/app/util/AppSettings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Gluon and/or its affiliates. + * Copyright (c) 2016, 2024, Gluon and/or its affiliates. * All rights reserved. Use is subject to license terms. * * This file is available and licensed under the following license: @@ -40,10 +40,10 @@ import javafx.scene.image.Image; import javafx.stage.Stage; -import javax.json.Json; -import javax.json.JsonObject; -import javax.json.JsonReader; -import javax.json.JsonReaderFactory; +import jakarta.json.Json; +import jakarta.json.JsonObject; +import jakarta.json.JsonReader; +import jakarta.json.JsonReaderFactory; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -78,10 +78,10 @@ public class AppSettings { private static final JsonReaderFactory readerFactory = Json.createReaderFactory(null); static { - initSceneBuiderVersion(); + initSceneBuilderVersion(); } - private static void initSceneBuiderVersion() { + private static void initSceneBuilderVersion() { try (InputStream in = AboutWindowController.class.getResourceAsStream("about.properties")) { if (in != null) { Properties sbProps = new Properties(); @@ -206,11 +206,4 @@ public static String getUserM2Repository() { return m2Path; } - public static String getTempM2Repository() { - String m2Path = System.getProperty("java.io.tmpdir") + File.separator + "m2Tmp"; //NOI18N - - assert m2Path != null; - - return m2Path; - } } diff --git a/app/src/main/java/module-info.java b/app/src/main/java/module-info.java index e66a94de1..965ab83e3 100644 --- a/app/src/main/java/module-info.java +++ b/app/src/main/java/module-info.java @@ -39,7 +39,7 @@ requires transitive com.gluonhq.scenebuilder.gluon.plugin; requires java.logging; requires java.prefs; - requires javax.json.api; + requires jakarta.json; opens com.oracle.javafx.scenebuilder.app to javafx.fxml; opens com.oracle.javafx.scenebuilder.app.about to javafx.fxml; diff --git a/kit/pom.xml b/kit/pom.xml index 8259bb8d6..a1bc27573 100644 --- a/kit/pom.xml +++ b/kit/pom.xml @@ -28,54 +28,17 @@ ${javafx.version} - + - org.eclipse.aether - aether-api - ${aether.version} - - - org.eclipse.aether - aether-impl - ${aether.version} - - - org.eclipse.aether - aether-connector-basic - ${aether.version} - - - org.eclipse.aether - aether-transport-file - ${aether.version} - - - org.eclipse.aether - aether-transport-http - ${aether.version} - - - org.apache.maven - maven-aether-provider - 3.3.9 + org.apache.maven.resolver + maven-resolver-supplier + ${maven.resolver.version} - - - org.apache.httpcomponents - httpclient - 4.5.13 - - - javax.json - javax.json-api - 1.0 - org.glassfish - javax.json - 1.0.4 - runtime + jakarta.json + 2.0.1 diff --git a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/manager/LibraryDialogController.java b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/manager/LibraryDialogController.java index ef297ec48..6e9511e74 100644 --- a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/manager/LibraryDialogController.java +++ b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/manager/LibraryDialogController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Gluon and/or its affiliates. + * Copyright (c) 2016, 2024, Gluon and/or its affiliates. * All rights reserved. Use is subject to license terms. * * This file is available and licensed under the following license: @@ -95,19 +95,17 @@ public class LibraryDialogController extends AbstractFxmlWindowController { private Runnable onAddFolder; private Consumer onEditFXML; - private String userM2Repository; - private String tempM2Repository; + private final String userM2Repository; private final PreferencesControllerBase preferencesControllerBase; - public LibraryDialogController(EditorController editorController, String userM2Repository, String tempM2Repository, + public LibraryDialogController(EditorController editorController, String userM2Repository, PreferencesControllerBase preferencesController, Stage owner) { super(LibraryPanelController.class.getResource("LibraryDialog.fxml"), I18N.getBundle(), owner); //NOI18N this.owner = owner; this.editorController = editorController; this.userLibrary = (UserLibrary) editorController.getLibrary(); this.userM2Repository = userM2Repository; - this.tempM2Repository = tempM2Repository; this.preferencesControllerBase = preferencesController; } @@ -192,7 +190,7 @@ private void close() { @FXML private void manage() { RepositoryManagerController repositoryDialogController = new RepositoryManagerController(editorController, - userM2Repository, tempM2Repository, preferencesControllerBase, getStage()); + userM2Repository, preferencesControllerBase, getStage()); repositoryDialogController.openWindow(); } @@ -216,7 +214,7 @@ private void addFolder() { @FXML private void addRelease() { SearchMavenDialogController mavenDialogController = new SearchMavenDialogController(editorController, - userM2Repository, tempM2Repository, preferencesControllerBase, getStage()); + userM2Repository, preferencesControllerBase, getStage()); mavenDialogController.openWindow(); mavenDialogController.getStage().showingProperty().addListener(new InvalidationListener() { @Override @@ -232,7 +230,7 @@ public void invalidated(Observable observable) { @FXML private void addManually() { MavenDialogController mavenDialogController = new MavenDialogController(editorController, userM2Repository, - tempM2Repository, preferencesControllerBase, getStage()); + preferencesControllerBase, getStage()); mavenDialogController.openWindow(); mavenDialogController.getStage().showingProperty().addListener(new InvalidationListener() { @Override diff --git a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/MavenDialogController.java b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/MavenDialogController.java index e214a40f9..5c8c5113c 100644 --- a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/MavenDialogController.java +++ b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/MavenDialogController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017 Gluon and/or its affiliates. + * Copyright (c) 2016, 2024, Gluon and/or its affiliates. * All rights reserved. Use is subject to license terms. * * This file is available and licensed under the following license: @@ -111,14 +111,14 @@ public class MavenDialogController extends AbstractFxmlWindowController { private final PreferencesControllerBase preferencesControllerBase; public MavenDialogController(EditorController editorController, String userM2Repository, - String tempM2Repository, PreferencesControllerBase preferencesControllerBase, Stage owner) { + PreferencesControllerBase preferencesControllerBase, Stage owner) { super(LibraryPanelController.class.getResource("MavenDialog.fxml"), I18N.getBundle(), owner); //NOI18N this.userLibrary = (UserLibrary) editorController.getLibrary(); this.owner = owner; this.editorController = editorController; this.preferencesControllerBase = preferencesControllerBase; - maven = new MavenRepositorySystem(false, userM2Repository, tempM2Repository, + maven = new MavenRepositorySystem(false, userM2Repository, preferencesControllerBase.getRepositoryPreferences()); versionsService = new Service>() { diff --git a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/MavenRepositorySystem.java b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/MavenRepositorySystem.java index 4bf55929b..dc73141cf 100644 --- a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/MavenRepositorySystem.java +++ b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/MavenRepositorySystem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Gluon and/or its affiliates. + * Copyright (c) 2016, 2024, Gluon and/or its affiliates. * All rights reserved. Use is subject to license terms. * * This file is available and licensed under the following license: @@ -34,32 +34,29 @@ import com.oracle.javafx.scenebuilder.kit.editor.panel.library.maven.repository.Repository; import com.oracle.javafx.scenebuilder.kit.editor.panel.library.maven.preset.MavenPresets; import java.io.File; +import java.nio.file.Path; import java.io.IOException; import java.nio.file.Files; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Comparator; import java.util.List; import java.util.Locale; import java.util.Objects; +import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.stream.Collectors; import java.util.stream.Stream; import com.oracle.javafx.scenebuilder.kit.preferences.RepositoryPreferences; -import org.apache.commons.lang3.exception.ExceptionUtils; -import org.apache.maven.repository.internal.MavenRepositorySystemUtils; -import org.codehaus.plexus.util.FileUtils; import org.eclipse.aether.AbstractRepositoryListener; -import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositoryEvent; import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.collection.CollectRequest; -import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; +import org.eclipse.aether.collection.DependencySelector; import org.eclipse.aether.graph.Dependency; -import org.eclipse.aether.graph.DependencyFilter; -import org.eclipse.aether.impl.DefaultServiceLocator; import org.eclipse.aether.installation.InstallRequest; import org.eclipse.aether.installation.InstallationException; import org.eclipse.aether.metadata.DefaultMetadata; @@ -73,108 +70,92 @@ import org.eclipse.aether.resolution.ArtifactResult; import org.eclipse.aether.resolution.DependencyRequest; import org.eclipse.aether.resolution.DependencyResolutionException; +import org.eclipse.aether.resolution.DependencyResult; import org.eclipse.aether.resolution.VersionRangeRequest; import org.eclipse.aether.resolution.VersionRangeResolutionException; import org.eclipse.aether.resolution.VersionRangeResult; -import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; -import org.eclipse.aether.spi.connector.transport.TransporterFactory; +import org.eclipse.aether.supplier.RepositorySystemSupplier; import org.eclipse.aether.transfer.AbstractTransferListener; import org.eclipse.aether.transfer.TransferEvent; -import org.eclipse.aether.transport.file.FileTransporterFactory; -import org.eclipse.aether.transport.http.HttpTransporterFactory; -import org.eclipse.aether.util.artifact.JavaScopes; -import org.eclipse.aether.util.filter.DependencyFilterUtils; +import org.eclipse.aether.util.graph.selector.AndDependencySelector; +import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector; +import org.eclipse.aether.util.graph.selector.OptionalDependencySelector; +import org.eclipse.aether.util.graph.selector.ScopeDependencySelector; import org.eclipse.aether.util.repository.AuthenticationBuilder; import org.eclipse.aether.version.Version; +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; + public class MavenRepositorySystem { + private static final Logger LOG = Logger.getLogger(MavenRepositorySystem.class.getName()); + // TODO: Manage List of Repositories // TODO: Manage private repositories and credentials private RepositorySystem system; - - private DefaultRepositorySystemSession session; - + + private RepositorySystemSession session; + private LocalRepository localRepo; private VersionRangeResult rangeResult; private final boolean onlyReleases; - - private BasicRepositoryConnectorFactory basicRepositoryConnectorFactory; - private final String userM2Repository; - private final String tempM2Repository; private final RepositoryPreferences repositoryPreferences; - public MavenRepositorySystem(boolean onlyReleases, String userM2Repository, String tempM2Repository, + public MavenRepositorySystem(boolean onlyReleases, String userM2Repository, RepositoryPreferences repositoryPreferences) { this.onlyReleases = onlyReleases; this.userM2Repository = userM2Repository; - this.tempM2Repository = tempM2Repository; this.repositoryPreferences = repositoryPreferences; initRepositorySystem(); } private void initRepositorySystem() { - DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); - locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); - locator.addService(TransporterFactory.class, FileTransporterFactory.class); - locator.addService(TransporterFactory.class, HttpTransporterFactory.class); - locator.setErrorHandler(new DefaultServiceLocator.ErrorHandler() { - @Override - public void serviceCreationFailed(Class type, Class impl, Throwable exception) { - throw new RuntimeException(exception); - } - }); - - basicRepositoryConnectorFactory = new BasicRepositoryConnectorFactory(); - basicRepositoryConnectorFactory.initService(locator); - - system = locator.getService(RepositorySystem.class); - - session = MavenRepositorySystemUtils.newSession(); - - localRepo = new LocalRepository(new File(userM2Repository)); - session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo)); - - // TODO: log file transfers - session.setTransferListener(new AbstractTransferListener() { - @Override - public void transferSucceeded(TransferEvent event) { } + system = new RepositorySystemSupplier().get(); + if (system == null) { + throw new RuntimeException("Error initializing repository system"); + } + localRepo = new LocalRepository(Path.of(userM2Repository)); - @Override - public void transferFailed(TransferEvent event) { } - }); - - // TODO: Log repository changes - session.setRepositoryListener(new AbstractRepositoryListener() { - @Override - public void artifactResolved(RepositoryEvent event) { } - }); - + // Exclude test and provided dependencies + DependencySelector dependencySelector = new AndDependencySelector( + new ScopeDependencySelector("test", "provided"), + new OptionalDependencySelector(), new ExclusionDependencySelector() + ); + session = system.createSessionBuilder() + .withTransferListener(new AbstractTransferListener() { + @Override + public void transferSucceeded(TransferEvent event) { + LOG.finest("Transfer succeeded: " + event); + } + @Override + public void transferFailed(TransferEvent event) { + LOG.finest("Transfer failed: " + event); + } + }) + .withRepositoryListener(new AbstractRepositoryListener() { + @Override + public void artifactResolved(RepositoryEvent event) { + LOG.finest("Artifact resolved: " + event); + } + }) + .withLocalRepositories(localRepo) + .setDependencySelector(dependencySelector) + .build(); } - public RepositorySystem getRepositorySystem() { - return system; - } - - public DefaultRepositorySystemSession getRepositorySession() { - return session; - } - public List getRepositories() { final List list = MavenPresets.getPresetRepositories().stream() - .filter(r -> !onlyReleases || - (onlyReleases && !r.getId().toUpperCase(Locale.ROOT).contains("SNAPSHOT"))) + .filter(r -> !onlyReleases || !r.getId().toUpperCase(Locale.ROOT).contains("SNAPSHOT")) .map(this::createRepository) .collect(Collectors.toList()); list.addAll(repositoryPreferences.getRepositories().stream() - .filter(r -> !onlyReleases || - (onlyReleases && !r.getId().toUpperCase(Locale.ROOT).contains("SNAPSHOT"))) + .filter(r -> !onlyReleases || !r.getId().toUpperCase(Locale.ROOT).contains("SNAPSHOT")) .map(this::createRepository) - .collect(Collectors.toList())); + .toList()); return list; } @@ -187,17 +168,7 @@ public RemoteRepository getRemoteRepository(Version version) { .filter(r -> r.getId().equals(rangeResult.getRepository(version).getId())) .findFirst() .orElse(new RemoteRepository - .Builder(MavenPresets.LOCAL, "default", session.getLocalRepository().getBasedir().getAbsolutePath()) - .build()); - } - - public RemoteRepository getRemoteRepository(String name) { - return getRepositories() - .stream() - .filter(r -> r.getId().equals(name)) - .findFirst() - .orElse(new RemoteRepository - .Builder(MavenPresets.LOCAL, "default", session.getLocalRepository().getBasedir().getAbsolutePath()) + .Builder(MavenPresets.LOCAL, "default", session.getLocalRepository().getBasePath().toAbsolutePath().toString()) .build()); } @@ -210,7 +181,9 @@ public List findVersions(Artifact artifact) { cleanMetadata(artifact); return rangeResult.getVersions(); - } catch (VersionRangeResolutionException ex) { } + } catch (VersionRangeResolutionException ex) { + LOG.finer("VersionRangeResolutionException finding version for artifact " + artifact + ": " + ex); + } return new ArrayList<>(); } @@ -221,72 +194,72 @@ public Version findLatestVersion(Artifact artifact) { try { rangeResult = system.resolveVersionRange(session, rangeRequest); cleanMetadata(artifact); - return rangeResult.getVersions() - .stream() - .filter(v -> !v.toString().toLowerCase(Locale.ROOT).contains("snapshot")) - .sorted((v1, v2) -> v2.compareTo(v1)) - .findFirst() - .orElse(null); - } catch (VersionRangeResolutionException ex) { } + return rangeResult.getVersions().stream() + .filter(v -> !v.toString().toLowerCase(Locale.ROOT).contains("snapshot")) + .max(Comparator.naturalOrder()) + .orElse(null); + } catch (VersionRangeResolutionException ex) { + LOG.finer("VersionRangeResolutionException finding latest version for artifact " + artifact + ": " + ex); + } return null; } private void cleanMetadata(Artifact artifact) { - final String path = localRepo.getBasedir().getAbsolutePath() + File.separator - + artifact.getGroupId().replaceAll("\\.", Matcher.quoteReplacement(File.separator)) + File.separator - + artifact.getArtifactId() + File.separator; + final Path path = localRepo.getBasePath() + .resolve(artifact.getGroupId().replaceAll("\\.", Matcher.quoteReplacement(File.separator))) + .resolve(artifact.getArtifactId()); final DefaultMetadata metadata = new DefaultMetadata("maven-metadata.xml", Metadata.Nature.RELEASE); getRepositories() .stream() .map(r -> session.getLocalRepositoryManager().getPathForRemoteMetadata(metadata, r, "")) .forEach(s -> { - File file = new File(path + s); - if (file.exists()) { + Path file = path.resolve(s); + if (Files.exists(file)) { try { - Files.delete(file.toPath()); - Files.delete(new File(path + s + ".sha1").toPath()); - } catch (IOException ex) { } + Files.delete(file); + Files.delete(new File(file + ".sha1").toPath()); + } catch (IOException ex) { + LOG.finer("Error deleting file " + file + ": " + ex); + } } }); } public String resolveArtifacts(RemoteRepository remoteRepository, Artifact... artifact) { - - LocalRepository localTmpRepo = new LocalRepository(tempM2Repository); - session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localTmpRepo)); - + List artifacts = Stream.of(artifact) .map(a -> { ArtifactRequest artifactRequest = new ArtifactRequest(); artifactRequest.setArtifact(a); - artifactRequest.setRepositories(remoteRepository == null ? getRepositories() : - Arrays.asList(remoteRepository)); + artifactRequest.setRepositories(remoteRepository == null ? getRepositories() : List.of(remoteRepository)); return artifactRequest; }) .map(ar -> { try { ArtifactResult result = system.resolveArtifact(session, ar); return result.getArtifact(); - } catch (ArtifactResolutionException ex) { } + } catch (ArtifactResolutionException ex) { + LOG.finer("ArtifactResolutionException for artifact request " + ar + ": " + ex); + } return null; }) .filter(Objects::nonNull) - .collect(Collectors.toList()); - - session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo)); - - List sha1Files = null; - if (artifacts != null && !artifacts.isEmpty()) { - sha1Files = artifacts.stream() - .filter(a -> a.getFile() != null) - .map(a -> new File(a.getFile().getAbsolutePath().concat(".sha1"))) - .collect(Collectors.toList()); - + .toList(); + + List sha1Paths = null; + if (!artifacts.isEmpty()) { + sha1Paths = artifacts.stream() + .filter(a -> a.getPath() != null) + .map(a -> Path.of(a.getPath().toAbsolutePath() + ".sha1")) + .toList(); + InstallRequest installRequest = new InstallRequest(); installRequest.setArtifacts(artifacts); try { system.install(session, installRequest); - } catch (InstallationException ex) { } + } catch (InstallationException ex) { + LOG.finer("InstallationException for install request " + installRequest + ": " + ex); + } } // return path from local m2 @@ -294,42 +267,37 @@ public String resolveArtifacts(RemoteRepository remoteRepository, Artifact... ar artifactRequest.setArtifact(artifact[0]); String absolutePath = ""; try { - final File jarFile = system.resolveArtifact(session, artifactRequest).getArtifact().getFile(); - absolutePath = jarFile.getAbsolutePath(); - if (sha1Files != null) { - sha1Files.stream() - .forEach(f -> { - try { - FileUtils.copyFile(f, new File(jarFile.getParent() + File.separator + f.getName())); - } catch (IOException ex) { } - }); + final Path jarFile = system.resolveArtifact(session, artifactRequest).getArtifact().getPath(); + absolutePath = jarFile.toAbsolutePath().toString(); + if (sha1Paths != null) { + sha1Paths.forEach(path -> copyFile(path, jarFile.getParent().resolve(path.getFileName()))); } - } catch (ArtifactResolutionException ex) { } - - try { - FileUtils.deleteDirectory(tempM2Repository); - } catch (IOException ex) { } - + } catch (ArtifactResolutionException ex) { + LOG.finer("ArtifactResolutionException for artifact request " + artifactRequest + ": " + ex); + } + return absolutePath; } public String resolveDependencies(RemoteRepository remoteRepository, Artifact artifact) { - DependencyFilter classpathFlter = DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE); CollectRequest collectRequest = new CollectRequest(); - collectRequest.setRoot(new Dependency(artifact, JavaScopes.COMPILE)); - collectRequest.setRepositories(remoteRepository == null ? getRepositories() : - Arrays.asList(remoteRepository)); + collectRequest.setRoot(new Dependency(artifact, "compile")); + collectRequest.setRepositories(remoteRepository == null ? getRepositories() : List.of(remoteRepository)); + + DependencyRequest dependencyRequest = new DependencyRequest(); + dependencyRequest.setCollectRequest(collectRequest); - DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, classpathFlter); try { - List artifactResults = system.resolveDependencies(session, dependencyRequest) - .getArtifactResults(); - + DependencyResult dependencyResult = system.resolveDependencies(session, dependencyRequest); + List artifactResults = dependencyResult.getArtifactResults(); + return artifactResults.stream() .skip(1) // exclude jar itself - .map(a -> a.getArtifact().getFile().getAbsolutePath()) + .map(a -> a.getArtifact().getPath().toAbsolutePath().toString()) .collect(Collectors.joining(File.pathSeparator)); - } catch (DependencyResolutionException ex) { } + } catch (DependencyResolutionException ex) { + LOG.finer("DependencyResolutionException for artifact " + artifact + ": " + ex); + } return ""; } @@ -342,13 +310,12 @@ private RemoteRepository createRepository(Repository repository) { .addPassword(repository.getPassword()) .build(); } - - final RemoteRepository repo = new RemoteRepository + + return new RemoteRepository .Builder(repository.getId() , repository.getType(), repository.getURL()) .setSnapshotPolicy(onlyReleases ? new RepositoryPolicy(false, null, null) : new RepositoryPolicy()) .setAuthentication(auth) .build(); - return repo; } public String validateRepository(Repository repository) { @@ -356,11 +323,11 @@ public String validateRepository(Repository repository) { ArtifactRequest artifactRequest = new ArtifactRequest(); artifactRequest.setArtifact(new DefaultArtifact("test:test:1.0")); - artifactRequest.setRepositories(Arrays.asList(remoteRepository)); + artifactRequest.setRepositories(List.of(remoteRepository));; try { system.resolveArtifact(session, artifactRequest); } catch (ArtifactResolutionException ex) { - final String rootCauseMessage = ExceptionUtils.getRootCauseMessage(ex); + final String rootCauseMessage = getExceptionCause(ex).toString(); if (rootCauseMessage != null && !rootCauseMessage.contains("ArtifactNotFoundException")) { return rootCauseMessage; } @@ -368,4 +335,23 @@ public String validateRepository(Repository repository) { return ""; } + + private static void copyFile(Path source, Path destination) { + try { + Files.createDirectories(destination.getParent()); + Files.copy(source, destination, REPLACE_EXISTING); + } catch (IOException ex) { + LOG.finer("Error copying file " + source + " to destination " + destination + ": " + ex); + } + } + + private static Throwable getExceptionCause(Throwable e) { + Throwable t = e; + Throwable cause; + while (null != (cause = t.getCause()) && t != cause) { + t = cause; + } + return t; + } + } diff --git a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/repository/RepositoryManagerController.java b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/repository/RepositoryManagerController.java index 29b883c3e..9782061ea 100644 --- a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/repository/RepositoryManagerController.java +++ b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/repository/RepositoryManagerController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Gluon and/or its affiliates. + * Copyright (c) 2016, 2024, Gluon and/or its affiliates. * All rights reserved. Use is subject to license terms. * * This file is available and licensed under the following license: @@ -65,24 +65,22 @@ public class RepositoryManagerController extends AbstractFxmlWindowController { private ObservableList listItems; private final String userM2Repository; - private final String tempM2Repository; private final PreferencesControllerBase preferencesControllerBase; public RepositoryManagerController(EditorController editorController, String userM2Repository, - String tempM2Repository, PreferencesControllerBase preferencesControllerBase, + PreferencesControllerBase preferencesControllerBase, Stage owner) { super(LibraryPanelController.class.getResource("RepositoryManager.fxml"), I18N.getBundle(), owner); //NOI18N this.owner = owner; this.editorController = editorController; this.userM2Repository = userM2Repository; - this.tempM2Repository = tempM2Repository; this.preferencesControllerBase = preferencesControllerBase; } @Override protected void controllerDidCreateStage() { if (this.owner == null) { - // Dialog will be appliation modal + // Dialog will be application modal getStage().initModality(Modality.APPLICATION_MODAL); } else { // Dialog will be window modal @@ -137,7 +135,7 @@ private void addRepository() { private void repositoryDialog(Repository repository) { RepositoryDialogController repositoryDialogController = new RepositoryDialogController(editorController, - userM2Repository, tempM2Repository, preferencesControllerBase, getStage()); + userM2Repository, preferencesControllerBase, getStage()); repositoryDialogController.openWindow(); repositoryDialogController.setRepository(repository); repositoryDialogController.getStage().showingProperty().addListener(new InvalidationListener() { diff --git a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/repository/dialog/RepositoryDialogController.java b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/repository/dialog/RepositoryDialogController.java index 7a5187292..391f055e7 100644 --- a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/repository/dialog/RepositoryDialogController.java +++ b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/repository/dialog/RepositoryDialogController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Gluon and/or its affiliates. + * Copyright (c) 2016, 2024, Gluon and/or its affiliates. * All rights reserved. Use is subject to license terms. * * This file is available and licensed under the following license: @@ -110,17 +110,15 @@ public class RepositoryDialogController extends AbstractFxmlWindowController { private final Service testService; private final String userM2Repository; - private final String tempM2Repository; private final PreferencesControllerBase preferencesControllerBase; public RepositoryDialogController(EditorController editorController, String userM2Repository, - String tempM2Repository, PreferencesControllerBase preferencesControllerBase, + PreferencesControllerBase preferencesControllerBase, Stage owner) { super(LibraryPanelController.class.getResource("RepositoryDialog.fxml"), I18N.getBundle(), owner); //NOI18N this.owner = owner; this.editorController = editorController; this.userM2Repository = userM2Repository; - this.tempM2Repository = tempM2Repository; this.preferencesControllerBase = preferencesControllerBase; testService = new Service() { @@ -221,7 +219,7 @@ public void openWindow() { passwordTextfield.disableProperty().bind(privateCheckBox.selectedProperty().not()); progress.visibleProperty().bind(testService.runningProperty()); resultLabel.setText(""); - maven = new MavenRepositorySystem(false, userM2Repository, tempM2Repository, + maven = new MavenRepositorySystem(false, userM2Repository, preferencesControllerBase.getRepositoryPreferences()); } diff --git a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/search/MavenSearch.java b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/search/MavenSearch.java index ef46580c8..c12140b65 100644 --- a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/search/MavenSearch.java +++ b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/search/MavenSearch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Gluon and/or its affiliates. + * Copyright (c) 2016, 2024, Gluon and/or its affiliates. * All rights reserved. Use is subject to license terms. * * This file is available and licensed under the following license: @@ -33,35 +33,36 @@ import com.oracle.javafx.scenebuilder.kit.editor.panel.library.maven.preset.MavenPresets; import java.io.IOException; +import java.io.StringReader; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import javax.json.Json; -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.json.JsonReader; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.HttpClients; +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.json.JsonReader; import org.eclipse.aether.artifact.DefaultArtifact; public class MavenSearch implements Search { // maven - private static final String URL_PREFIX = "http://search.maven.org/solrsearch/select?q="; + private static final String URL_PREFIX = "https://search.maven.org/solrsearch/select?q="; private static final String URL_SUFFIX = "&rows=200&wt=json"; - private static final String URL_PREFIX_FULLCLASS = "http://search.maven.org/solrsearch/select?q=fc:%22"; + private static final String URL_PREFIX_FULLCLASS = "https://search.maven.org/solrsearch/select?q=fc:%22"; private static final String URL_SUFFIX_FULLCLASS = "%22&rows=200&wt=json"; private final HttpClient client; public MavenSearch() { - client = HttpClients.createDefault(); + client = HttpClient.newHttpClient(); } @Override @@ -71,9 +72,11 @@ public List getCoordinates(String query) { map.put("Repository", MavenPresets.MAVEN); try { - HttpGet request = new HttpGet(URL_PREFIX + query + URL_SUFFIX); - HttpResponse response = client.execute(request); - try (JsonReader rdr = Json.createReader(response.getEntity().getContent())) { + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(URL_PREFIX + query + URL_SUFFIX)) + .build(); + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + try (JsonReader rdr = Json.createReader(new StringReader(response.body()))) { JsonObject obj = rdr.readObject(); if (obj != null && !obj.isEmpty() && obj.containsKey("response")) { JsonObject jsonResponse = obj.getJsonObject("response"); @@ -88,7 +91,7 @@ public List getCoordinates(String query) { } } } - } catch (IOException ex) { + } catch (InterruptedException | IOException ex) { Logger.getLogger(MavenSearch.class.getName()).log(Level.SEVERE, null, ex); } return null; diff --git a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/search/NexusSearch.java b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/search/NexusSearch.java index dbba61a29..3668dca3a 100644 --- a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/search/NexusSearch.java +++ b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/search/NexusSearch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Gluon and/or its affiliates. + * Copyright (c) 2016, 2024, Gluon and/or its affiliates. * All rights reserved. Use is subject to license terms. * * This file is available and licensed under the following license: @@ -32,22 +32,23 @@ package com.oracle.javafx.scenebuilder.kit.editor.panel.library.maven.search; import java.io.IOException; +import java.io.StringReader; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.util.ArrayList; +import java.util.Base64; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import javax.json.Json; -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.json.JsonReader; -import static org.apache.commons.codec.binary.Base64.encodeBase64; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.HttpClients; +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.json.JsonReader; import org.eclipse.aether.artifact.DefaultArtifact; public class NexusSearch implements Search { @@ -65,12 +66,11 @@ public class NexusSearch implements Search { private static boolean first; private static int iteration; - private int totalCount = 0; private static final int ITEMS_ITERATION = 200; private static final int MAX_RESULTS = 2000; public NexusSearch(String name, String domain, String username, String password) { - client = HttpClients.createDefault(); + client = HttpClient.newHttpClient(); this.name = name; this.domain = domain; this.username = username; @@ -83,18 +83,20 @@ public NexusSearch(String name, String domain, String username, String password) @Override public List getCoordinates(String query) { try { - HttpGet request = new HttpGet(domain + URL_PREFIX + query + (first ? "" : URL_SUFFIX + iteration * ITEMS_ITERATION)); + HttpRequest.Builder builder = HttpRequest.newBuilder() + .uri(URI.create(domain + URL_PREFIX + query + (first ? "" : URL_SUFFIX + iteration * ITEMS_ITERATION))) + .header("Accept", "application/json"); if (!username.isEmpty() && !password.isEmpty()) { - String authStringEnc = new String(encodeBase64((username + ":" + password).getBytes())); - request.addHeader("Authorization", "Basic " + authStringEnc); + String authStringEnc = Base64.getEncoder().encodeToString((username + ":" + password).getBytes()); + builder.header("Authorization", "Basic " + authStringEnc); } - request.setHeader("Accept", "application/json"); - HttpResponse response = client.execute(request); - try (JsonReader rdr = Json.createReader(response.getEntity().getContent())) { + HttpRequest request = builder.build(); + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + try (JsonReader rdr = Json.createReader(new StringReader(response.body()))) { JsonObject obj = rdr.readObject(); if (first && obj != null && !obj.isEmpty() && obj.containsKey("totalCount")) { first = false; - totalCount = Math.min(obj.getInt("totalCount", 0), MAX_RESULTS); + int totalCount = Math.min(obj.getInt("totalCount", 0), MAX_RESULTS); if (totalCount > ITEMS_ITERATION) { List coordinates = new ArrayList<>(processRequest(obj)); while (totalCount > ITEMS_ITERATION) { @@ -104,7 +106,7 @@ public List getCoordinates(String query) { .filter(ga -> coordinates.stream() .noneMatch(ar -> ar.getGroupId().equals(ga.getGroupId()) && ar.getArtifactId().equals(ga.getArtifactId()))) - .collect(Collectors.toList())); + .toList()); totalCount -= ITEMS_ITERATION; } @@ -113,7 +115,7 @@ public List getCoordinates(String query) { } return processRequest(obj); } - } catch (IOException ex) { + } catch (InterruptedException | IOException ex) { Logger.getLogger(NexusSearch.class.getName()).log(Level.SEVERE, null, ex); } return null; diff --git a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/search/SearchMavenDialogController.java b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/search/SearchMavenDialogController.java index cc6962c3a..fb94f5cf8 100644 --- a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/search/SearchMavenDialogController.java +++ b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/library/maven/search/SearchMavenDialogController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017 Gluon and/or its affiliates. + * Copyright (c) 2016, 2024, Gluon and/or its affiliates. * All rights reserved. Use is subject to license terms. * * This file is available and licensed under the following license: @@ -66,7 +66,6 @@ import javafx.scene.control.Tooltip; import javafx.stage.Modality; import javafx.stage.Stage; -import javafx.stage.Window; import javafx.stage.WindowEvent; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.artifact.DefaultArtifact; @@ -110,7 +109,7 @@ public class SearchMavenDialogController extends AbstractFxmlWindowController { private final PreferencesControllerBase preferencesControllerBase; public SearchMavenDialogController(EditorController editorController, String userM2Repository, - String tempM2Repository, PreferencesControllerBase preferencesControllerBase, + PreferencesControllerBase preferencesControllerBase, Stage owner) { super(LibraryPanelController.class.getResource("SearchMavenDialog.fxml"), I18N.getBundle(), owner); //NOI18N this.userLibrary = (UserLibrary) editorController.getLibrary(); @@ -118,7 +117,7 @@ public SearchMavenDialogController(EditorController editorController, String use this.editorController = editorController; this.preferencesControllerBase = preferencesControllerBase; - maven = new MavenRepositorySystem(true, userM2Repository, tempM2Repository, + maven = new MavenRepositorySystem(true, userM2Repository, preferencesControllerBase.getRepositoryPreferences()); // only releases searchService = new SearchService(userM2Repository); diff --git a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/fxom/FXOMLoader.java b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/fxom/FXOMLoader.java index 0fa6dcaf7..c4ef3864c 100644 --- a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/fxom/FXOMLoader.java +++ b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/fxom/FXOMLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Gluon and/or its affiliates. + * Copyright (c) 2017, 2024, Gluon and/or its affiliates. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. * All rights reserved. Use is subject to license terms. * @@ -120,7 +120,7 @@ private void handleUnknownAndMissingCauses(Exception x) throws IOException { } private void handleKnownCauses(Exception x) throws IOException { - if (x.getCause().getClass() == XMLStreamException.class) { + if (x.getCause() instanceof XMLStreamException) { knownErrorsHandler.accept(x); } else { handleUnknownAndMissingCauses(x); diff --git a/kit/src/main/java/module-info.java b/kit/src/main/java/module-info.java index a6bca64e4..be398b96f 100644 --- a/kit/src/main/java/module-info.java +++ b/kit/src/main/java/module-info.java @@ -39,22 +39,15 @@ requires transitive javafx.web; requires java.logging; - requires static javax.json.api; + requires java.net.http; + requires static jakarta.json; requires transitive static java.prefs; - requires transitive static aether.api; - requires static aether.connector.basic; - requires static aether.impl; - requires static aether.spi; - requires static aether.transport.file; - requires static aether.transport.http; - requires static aether.util; - requires static org.apache.commons.codec; - requires static org.apache.httpcomponents.httpclient; - requires static org.apache.httpcomponents.httpcore; - requires static commons.lang3; - requires static maven.aether.provider; - requires static plexus.utils; + requires org.apache.maven.resolver; + requires org.apache.maven.resolver.spi; + requires org.apache.maven.resolver.impl; + requires org.apache.maven.resolver.supplier; + requires org.apache.maven.resolver.util; opens com.oracle.javafx.scenebuilder.kit to javafx.fxml; opens com.oracle.javafx.scenebuilder.kit.alert; diff --git a/kit/src/test/java/com/oracle/javafx/scenebuilder/kit/fxom/FXOMLoaderTest.java b/kit/src/test/java/com/oracle/javafx/scenebuilder/kit/fxom/FXOMLoaderTest.java index d3cd6f99d..aa7d1e14e 100644 --- a/kit/src/test/java/com/oracle/javafx/scenebuilder/kit/fxom/FXOMLoaderTest.java +++ b/kit/src/test/java/com/oracle/javafx/scenebuilder/kit/fxom/FXOMLoaderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Gluon and/or its affiliates. + * Copyright (c) 2022, 2024, Gluon and/or its affiliates. * All rights reserved. Use is subject to license terms. * * This file is available and licensed under the following license: @@ -38,6 +38,7 @@ import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; +import javax.xml.stream.XMLStreamException; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -58,7 +59,7 @@ public void that_LoadException_caused_by_XMLStreamException_is_handled() throws String validFxmlText = FXOMDocument.readContentFromURL(validResource); FXOMDocument document = new FXOMDocument(validFxmlText, validResource, null, null); - // When there are exceptions, than the error handler should store these here + // When there are exceptions, then the error handler should store these here Map, Throwable> handledErrors = new HashMap<>(); // In Scene Builder, the error is displayed in an error dialog. @@ -73,7 +74,7 @@ public void that_LoadException_caused_by_XMLStreamException_is_handled() throws FXOMLoader classUnderTest = new FXOMLoader(document, errorHandler); assertDoesNotThrow(()->classUnderTest.load(invalidXmlText)); - assertTrue(handledErrors.containsKey(javax.xml.stream.XMLStreamException.class)); + assertTrue(handledErrors.values().stream().anyMatch(v -> v instanceof XMLStreamException)); assertTrue(handledErrors.containsKey(javafx.fxml.LoadException.class)); } } diff --git a/pom.xml b/pom.xml index c36bd29ec..7028f9cab 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ ${java.version} ${java.version} 23.0.1 - 1.1.0 + 2.0.0-alpha-8 6.2.3 4.0.21 5.10.0 @@ -30,6 +30,7 @@ gluonhq/scenebuilder github.com:${project.github.repository} RELEASE +