Skip to content

Commit

Permalink
Extract goblint conf filewatcher to separate class and move refreshGo…
Browse files Browse the repository at this point in the history
…blintConfig from GoblintAnalysis
  • Loading branch information
karoliineh committed Jan 12, 2024
1 parent e2a99c3 commit 30d64ca
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 36 deletions.
18 changes: 15 additions & 3 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {

Expand All @@ -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();
Expand Down Expand Up @@ -123,19 +130,24 @@ 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.
* <p>
* 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
Expand Down
38 changes: 5 additions & 33 deletions src/main/java/analysis/GoblintAnalysis.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}


Expand Down Expand Up @@ -113,9 +110,7 @@ public void analyze(Collection<? extends Module> files, AnalysisConsumer consume
}
}

refreshGoblintConfig();

if (!configValid) {
if (!goblintConfWatcher.refreshGoblintConfig()) {
return;
}

Expand All @@ -141,29 +136,6 @@ public void analyze(Collection<? extends Module> 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.
* <p>
Expand Down
57 changes: 57 additions & 0 deletions src/main/java/goblintserver/GoblintConfWatcher.java
Original file line number Diff line number Diff line change
@@ -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;
}
}

0 comments on commit 30d64ca

Please sign in to comment.