From 30d64ca63bff479bfce8d261d1c38d186c7609ac Mon Sep 17 00:00:00 2001 From: Karoliine Holter Date: Fri, 12 Jan 2024 15:12:48 +0200 Subject: [PATCH] Extract goblint conf filewatcher to separate class and move refreshGoblintConfig from GoblintAnalysis --- src/main/java/Main.java | 18 +++++- src/main/java/analysis/GoblintAnalysis.java | 38 ++----------- .../goblintserver/GoblintConfWatcher.java | 57 +++++++++++++++++++ 3 files changed, 77 insertions(+), 36 deletions(-) create mode 100644 src/main/java/goblintserver/GoblintConfWatcher.java diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 42e4fd5..9f33fea 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -6,6 +6,7 @@ import api.GoblintService; import api.GoblintServiceLauncher; import api.messages.params.Params; +import goblintserver.GoblintConfWatcher; import goblintserver.GoblintServer; import gobpie.GobPieConfReader; import gobpie.GobPieConfiguration; @@ -17,7 +18,10 @@ import org.eclipse.lsp4j.MessageParams; import org.eclipse.lsp4j.MessageType; import org.eclipse.lsp4j.jsonrpc.messages.Either; +import util.FileWatcher; + import java.io.File; +import java.nio.file.Path; public class Main { @@ -40,8 +44,11 @@ public static void main(String... args) { // Connect GoblintService and read configuration GoblintService goblintService = connectGoblintService(magpieServer, gobpieConfiguration, goblintServer); + // Create file watcher for Goblint configuration + GoblintConfWatcher goblintConfWatcher = getGoblintConfWatcher(magpieServer, goblintService, gobpieConfiguration); + // Add analysis - addAnalysis(magpieServer, gobpieConfiguration, goblintServer, goblintService); + addAnalysis(magpieServer, gobpieConfiguration, goblintServer, goblintService, goblintConfWatcher); // Launch magpieServer magpieServer.configurationDone(); @@ -123,6 +130,11 @@ private static GoblintService connectGoblintService(MagpieServer magpieServer, G return goblintService; } + private static GoblintConfWatcher getGoblintConfWatcher(GoblintMagpieServer magpieServer, GoblintService goblintService, GobPieConfiguration gobpieConfiguration) { + FileWatcher fileWatcher = new FileWatcher(Path.of(gobpieConfiguration.getGoblintConf())); + return new GoblintConfWatcher(magpieServer, goblintService, gobpieConfiguration, fileWatcher); + } + /** * Method for creating and adding Goblint analysis to MagpieBridge server. @@ -130,12 +142,12 @@ private static GoblintService connectGoblintService(MagpieServer magpieServer, G * Creates the GoblintAnalysis classes. */ private static void addAnalysis(MagpieServer magpieServer, GobPieConfiguration gobpieConfiguration, - GoblintServer goblintServer, GoblintService goblintService) { + GoblintServer goblintServer, GoblintService goblintService, GoblintConfWatcher goblintConfWatcher) { // define language String language = "c"; // add analysis to the MagpieServer - ServerAnalysis serverAnalysis = new GoblintAnalysis(magpieServer, goblintServer, goblintService, gobpieConfiguration); + ServerAnalysis serverAnalysis = new GoblintAnalysis(magpieServer, goblintServer, goblintService, gobpieConfiguration, goblintConfWatcher); magpieServer.addAnalysis(Either.forLeft(serverAnalysis), language); // add HTTP server for showing CFGs, only if the option is specified in the configuration diff --git a/src/main/java/analysis/GoblintAnalysis.java b/src/main/java/analysis/GoblintAnalysis.java index d3cfbbc..2a063f9 100644 --- a/src/main/java/analysis/GoblintAnalysis.java +++ b/src/main/java/analysis/GoblintAnalysis.java @@ -5,6 +5,7 @@ import api.messages.params.AnalyzeParams; import api.messages.params.Params; import com.ibm.wala.classLoader.Module; +import goblintserver.GoblintConfWatcher; import goblintserver.GoblintServer; import gobpie.GobPieConfiguration; import gobpie.GobPieException; @@ -20,11 +21,9 @@ import org.zeroturnaround.exec.InvalidExitValueException; import org.zeroturnaround.exec.ProcessExecutor; import org.zeroturnaround.exec.ProcessResult; -import util.FileWatcher; import java.io.File; import java.io.IOException; -import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -54,20 +53,18 @@ public class GoblintAnalysis implements ServerAnalysis { private final GoblintServer goblintServer; private final GoblintService goblintService; private final GobPieConfiguration gobpieConfiguration; - private final FileWatcher goblintConfWatcher; - - private static boolean configValid = false; + private final GoblintConfWatcher goblintConfWatcher; private static Future lastAnalysisTask = null; private final Logger log = LogManager.getLogger(GoblintAnalysis.class); - public GoblintAnalysis(MagpieServer magpieServer, GoblintServer goblintServer, GoblintService goblintService, GobPieConfiguration gobpieConfiguration) { + public GoblintAnalysis(MagpieServer magpieServer, GoblintServer goblintServer, GoblintService goblintService, GobPieConfiguration gobpieConfiguration, GoblintConfWatcher goblintConfWatcher) { this.magpieServer = magpieServer; this.goblintServer = goblintServer; this.goblintService = goblintService; this.gobpieConfiguration = gobpieConfiguration; - this.goblintConfWatcher = new FileWatcher(Path.of(gobpieConfiguration.getGoblintConf())); + this.goblintConfWatcher = goblintConfWatcher; } @@ -113,9 +110,7 @@ public void analyze(Collection files, AnalysisConsumer consume } } - refreshGoblintConfig(); - - if (!configValid) { + if (!goblintConfWatcher.refreshGoblintConfig()) { return; } @@ -141,29 +136,6 @@ public void analyze(Collection files, AnalysisConsumer consume } - /** - * Reloads Goblint config if it has been changed or is currently invalid. - */ - private void refreshGoblintConfig() { - if (goblintConfWatcher.checkModified() || !configValid) { - configValid = goblintService.reset_config() - .thenCompose(_res -> - goblintService.read_config(new Params(new File(gobpieConfiguration.getGoblintConf()).getAbsolutePath()))) - .handle((_res, ex) -> { - if (ex != null) { - Throwable cause = ex instanceof CompletionException ? ex.getCause() : ex; - String msg = "Goblint was unable to successfully read the new configuration: " + cause.getMessage(); - magpieServer.forwardMessageToClient(new MessageParams(MessageType.Error, msg)); - log.error(msg); - return false; - } - return true; - }) - .join(); - } - } - - /** * The method that is triggered before each analysis. *

diff --git a/src/main/java/goblintserver/GoblintConfWatcher.java b/src/main/java/goblintserver/GoblintConfWatcher.java new file mode 100644 index 0000000..54ddf41 --- /dev/null +++ b/src/main/java/goblintserver/GoblintConfWatcher.java @@ -0,0 +1,57 @@ +package goblintserver; + +import api.GoblintService; +import api.messages.params.Params; +import gobpie.GobPieConfiguration; +import magpiebridge.core.MagpieServer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.eclipse.lsp4j.MessageParams; +import org.eclipse.lsp4j.MessageType; +import util.FileWatcher; + +import java.io.File; +import java.nio.file.Path; +import java.util.concurrent.CompletionException; + +public class GoblintConfWatcher { + + private final FileWatcher fileWatcher; + private final MagpieServer magpieServer; + private final GoblintService goblintService; + private final GobPieConfiguration gobpieConfiguration; + + public boolean configValid = false; + + private final Logger log = LogManager.getLogger(GoblintConfWatcher.class); + + public GoblintConfWatcher(MagpieServer magpieServer, GoblintService goblintService, GobPieConfiguration gobpieConfiguration, FileWatcher fileWatcher) { + this.magpieServer = magpieServer; + this.goblintService = goblintService; + this.gobpieConfiguration = gobpieConfiguration; + this.fileWatcher = fileWatcher; + } + + /** + * Reloads Goblint config if it has been changed or is currently invalid. + */ + public boolean refreshGoblintConfig() { + if (fileWatcher.checkModified() || !configValid) { + configValid = goblintService.reset_config() + .thenCompose(_res -> + goblintService.read_config(new Params(new File(gobpieConfiguration.getGoblintConf()).getAbsolutePath()))) + .handle((_res, ex) -> { + if (ex != null) { + Throwable cause = ex instanceof CompletionException ? ex.getCause() : ex; + String msg = "Goblint was unable to successfully read the new configuration: " + cause.getMessage(); + magpieServer.forwardMessageToClient(new MessageParams(MessageType.Error, msg)); + log.error(msg); + return false; + } + return true; + }) + .join(); + } + return configValid; + } +}