Skip to content

Commit

Permalink
Process CLI arguments before starting gui (#9217)
Browse files Browse the repository at this point in the history
* Process CLI arguments before starting gui
* Display logs on ui thread
* Demote some of the log calls to debug
* Remove unused test class
  • Loading branch information
tobiasdiez authored Oct 12, 2022
1 parent b871301 commit c827c43
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 121 deletions.
3 changes: 3 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@

"onCreateCommand": "gradle assemble",

// Forward the noVNC port (desktop-lite: https://github.com/devcontainers/features/tree/main/src/desktop-lite)
"forwardPorts": [6080],

// Need to connect as root otherwise we run into issues with gradle.
// default option is "vscode". More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "root",
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ java {
}

application {
mainClass.set('org.jabref.gui.JabRefLauncher')
mainClass.set('org.jabref.cli.Launcher')
mainModule.set('org.jabref')
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.jabref.gui;
package org.jabref.cli;

import java.io.File;
import java.io.IOException;
Expand All @@ -9,13 +9,8 @@
import java.util.Comparator;
import java.util.Map;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;

import org.jabref.cli.ArgumentProcessor;
import org.jabref.cli.JabRefCLI;
import org.jabref.gui.openoffice.OOBibBaseConnect;
import org.jabref.gui.Globals;
import org.jabref.gui.MainApplication;
import org.jabref.gui.remote.JabRefMessageHandler;
import org.jabref.logic.exporter.ExporterFactory;
import org.jabref.logic.journals.JournalAbbreviationLoader;
Expand All @@ -42,99 +37,84 @@
import org.tinylog.configuration.Configuration;

/**
* JabRef's main class to process command line options and to start the UI
* The main entry point for the JabRef application.
* <p>
* It has two main functions:
* - Handle the command line arguments
* - Start the JavaFX application (if not in cli mode)
*/
public class JabRefMain extends Application {
public class Launcher {
private static Logger LOGGER;

private static String[] arguments;

public static void main(String[] args) {
addLogToDisk();
arguments = args;
launch(arguments);
}

private static void initializeLogger() {
LOGGER = LoggerFactory.getLogger(JabRefMain.class);
}

/**
* This needs to be called as early as possible. After the first log write, it is not possible to alter
* the log configuration programmatically anymore.
*/
private static void addLogToDisk() {
Path directory = Path.of(AppDirsFactory.getInstance().getUserLogDir(
"jabref",
new BuildInfo().version.toString(),
"org.jabref"));
try {
Files.createDirectories(directory);
} catch (IOException e) {
initializeLogger();
LOGGER.error("Could not create log directory {}", directory, e);
return;
}
// The "Shared File Writer" is explained at https://tinylog.org/v2/configuration/#shared-file-writer
Map<String, String> configuration = Map.of(
"writerFile", "shared file",
"writerFile.level", "info",
"writerFile.file", directory.resolve("log.txt").toString(),
"writerFile.charset", "UTF-8");

configuration.entrySet().forEach(config -> Configuration.set(config.getKey(), config.getValue()));
initializeLogger();
}

@Override
public void start(Stage mainStage) {
try {
FallbackExceptionHandler.installExceptionHandler();

// Init preferences
final JabRefPreferences preferences = JabRefPreferences.getInstance();
Globals.prefs = preferences;
// Perform migrations
PreferencesMigrations.runMigrations();

configureProxy(preferences.getProxyPreferences());
// Early exit in case another instance is already running
if (!handleMultipleAppInstances(args, preferences)) {
return;
}

// Init rest of preferences
configureProxy(preferences.getProxyPreferences());
configureSSL(preferences.getSSLPreferences());

Globals.startBackgroundTasks();

applyPreferences(preferences);

clearOldSearchIndices();

try {
// Process arguments
ArgumentProcessor argumentProcessor = new ArgumentProcessor(arguments, ArgumentProcessor.Mode.INITIAL_START, preferences);
// Check for running JabRef
if (!handleMultipleAppInstances(arguments, preferences) || argumentProcessor.shouldShutDown()) {
Platform.exit();
ArgumentProcessor argumentProcessor = new ArgumentProcessor(args, ArgumentProcessor.Mode.INITIAL_START,
preferences);
if (argumentProcessor.shouldShutDown()) {
LOGGER.debug("JabRef shut down after processing command line arguments");
return;
}

// If not, start GUI
new JabRefGUI(mainStage, argumentProcessor.getParserResults(), argumentProcessor.isBlank(), preferences);
MainApplication.create(argumentProcessor.getParserResults(), argumentProcessor.isBlank(), preferences);
} catch (ParseException e) {
LOGGER.error("Problem parsing arguments", e);

JabRefCLI.printUsage();
Platform.exit();
}
} catch (Exception ex) {
LOGGER.error("Unexpected exception", ex);
Platform.exit();
}
}

@Override
public void stop() {
OOBibBaseConnect.closeOfficeConnection();
Globals.stopBackgroundTasks();
Globals.shutdownThreadPools();
/**
* This needs to be called as early as possible. After the first log write, it
* is not possible to alter
* the log configuration programmatically anymore.
*/
private static void addLogToDisk() {
Path directory = Path.of(AppDirsFactory.getInstance().getUserLogDir(
"jabref",
new BuildInfo().version.toString(),
"org.jabref"));
try {
Files.createDirectories(directory);
} catch (IOException e) {
initializeLogger();
LOGGER.error("Could not create log directory {}", directory, e);
return;
}
// The "Shared File Writer" is explained at
// https://tinylog.org/v2/configuration/#shared-file-writer
Map<String, String> configuration = Map.of(
"writerFile", "shared file",
"writerFile.level", "info",
"writerFile.file", directory.resolve("log.txt").toString(),
"writerFile.charset", "UTF-8");

configuration.entrySet().forEach(config -> Configuration.set(config.getKey(), config.getValue()));
initializeLogger();
}

private static void initializeLogger() {
LOGGER = LoggerFactory.getLogger(MainApplication.class);
}

private static boolean handleMultipleAppInstances(String[] args, PreferencesService preferences) {
Expand All @@ -143,7 +123,8 @@ private static boolean handleMultipleAppInstances(String[] args, PreferencesServ
// Try to contact already running JabRef
RemoteClient remoteClient = new RemoteClient(remotePreferences.getPort());
if (remoteClient.ping()) {
// We are not alone, there is already a server out there, send command line arguments to other instance
// We are not alone, there is already a server out there, send command line
// arguments to other instance
if (remoteClient.sendCommandLineArguments(args)) {
// So we assume it's all taken care of, and quit.
LOGGER.info(Localization.lang("Arguments passed on to running JabRef instance. Shutting down."));
Expand All @@ -153,15 +134,17 @@ private static boolean handleMultipleAppInstances(String[] args, PreferencesServ
}
} else {
// We are alone, so we start the server
Globals.REMOTE_LISTENER.openAndStart(new JabRefMessageHandler(), remotePreferences.getPort(), preferences);
Globals.REMOTE_LISTENER.openAndStart(new JabRefMessageHandler(), remotePreferences.getPort(),
preferences);
}
}
return true;
}

private static void applyPreferences(PreferencesService preferences) {
// Read list(s) of journal names and abbreviations
Globals.journalAbbreviationRepository = JournalAbbreviationLoader.loadRepository(preferences.getJournalAbbreviationPreferences());
Globals.journalAbbreviationRepository = JournalAbbreviationLoader
.loadRepository(preferences.getJournalAbbreviationPreferences());

// Build list of Import and Export formats
Globals.IMPORT_FORMAT_READER.resetImportFormats(
Expand Down Expand Up @@ -208,12 +191,13 @@ private static void clearOldSearchIndices() {

try (DirectoryStream<Path> stream = Files.newDirectoryStream(appData)) {
for (Path path : stream) {
if (Files.isDirectory(path) && !path.toString().endsWith("ssl") && path.toString().contains("lucene") && !path.equals(currentIndexPath)) {
if (Files.isDirectory(path) && !path.toString().endsWith("ssl") && path.toString().contains("lucene")
&& !path.equals(currentIndexPath)) {
LOGGER.info("Deleting out-of-date fulltext search index at {}.", path);
Files.walk(path)
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
}
}
} catch (IOException e) {
Expand Down
10 changes: 0 additions & 10 deletions src/main/java/org/jabref/gui/JabRefLauncher.java

This file was deleted.

41 changes: 41 additions & 0 deletions src/main/java/org/jabref/gui/MainApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.jabref.gui;

import java.util.List;

import javafx.application.Application;
import javafx.stage.Stage;

import org.jabref.gui.openoffice.OOBibBaseConnect;
import org.jabref.logic.importer.ParserResult;
import org.jabref.preferences.JabRefPreferences;

/**
* JabRef's main class to process command line options and to start the UI
*/
public class MainApplication extends Application {
private static List<ParserResult> parserResults;
private static boolean isBlank;
private static JabRefPreferences preferences;

public static void create(List<ParserResult> parserResults, boolean blank, JabRefPreferences preferences) {
MainApplication.parserResults = parserResults;
MainApplication.isBlank = blank;
MainApplication.preferences = preferences;
launch();
}

@Override
public void start(Stage mainStage) {
FallbackExceptionHandler.installExceptionHandler();

Globals.startBackgroundTasks();
new JabRefGUI(mainStage, parserResults, isBlank, preferences);
}

@Override
public void stop() {
OOBibBaseConnect.closeOfficeConnection();
Globals.stopBackgroundTasks();
Globals.shutdownThreadPools();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.jabref.gui.ClipBoardManager;
import org.jabref.gui.DialogService;
import org.jabref.gui.desktop.JabRefDesktop;
import org.jabref.gui.util.BindingsHelper;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.logging.LogMessages;
import org.jabref.logic.util.BuildInfo;
Expand All @@ -25,6 +26,7 @@
import org.slf4j.LoggerFactory;

public class ErrorConsoleViewModel extends AbstractViewModel {

private static final Logger LOGGER = LoggerFactory.getLogger(ErrorConsoleViewModel.class);

private final DialogService dialogService;
Expand All @@ -36,7 +38,7 @@ public ErrorConsoleViewModel(DialogService dialogService, ClipBoardManager clipB
this.dialogService = Objects.requireNonNull(dialogService);
this.clipBoardManager = Objects.requireNonNull(clipBoardManager);
this.buildInfo = Objects.requireNonNull(buildInfo);
ObservableList<LogEventViewModel> eventViewModels = EasyBind.map(LogMessages.getInstance().getMessages(), LogEventViewModel::new);
ObservableList<LogEventViewModel> eventViewModels = EasyBind.map(BindingsHelper.forUI(LogMessages.getInstance().getMessages()), LogEventViewModel::new);
allMessagesData = new ReadOnlyListWrapper<>(eventViewModels);
}

Expand Down
3 changes: 1 addition & 2 deletions src/main/java/org/jabref/gui/logging/GuiWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import java.util.EnumSet;
import java.util.Map;

import org.jabref.gui.util.DefaultTaskExecutor;
import org.jabref.logic.logging.LogMessages;

import org.tinylog.core.LogEntry;
Expand All @@ -29,7 +28,7 @@ public Collection<LogEntryValue> getRequiredLogEntryValues() {

@Override
public void write(LogEntry logEntry) throws Exception {
DefaultTaskExecutor.runInJavaFXThread(() -> LogMessages.getInstance().add(logEntry));
LogMessages.getInstance().add(logEntry);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public X509Certificate getCertificate(String alias) {
*/
public static void createTruststoreFileIfNotExist(Path storePath) {
try {
LOGGER.info("Trust store path: {}", storePath.toAbsolutePath());
LOGGER.debug("Trust store path: {}", storePath.toAbsolutePath());
Path storeResourcePath = Path.of(TrustStoreManager.class.getResource("/ssl/truststore.jks").toURI());
Files.createDirectories(storePath.getParent());
if (Files.notExists(storePath)) {
Expand Down
28 changes: 0 additions & 28 deletions src/test/java/org/jabref/testutils/TestUtils.java

This file was deleted.

0 comments on commit c827c43

Please sign in to comment.