Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into writebackupToTemp
Browse files Browse the repository at this point in the history
* upstream/master:
  Enable Merging of BibDatabases (#6689)
  Refactor file preferences (#6779)
  Interrupt all running tasks during shutdown (#6118)
  Fixes #6705 , added icon for multiple identifiers (#6809)
  Apply css files correctly to dialogs (#6828)
  Fix link
  Make template more explicit
  • Loading branch information
Siedlerchr committed Sep 1, 2020
2 parents 679631f + 35f5078 commit 7b68deb
Show file tree
Hide file tree
Showing 61 changed files with 1,517 additions and 1,034 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

# Changelog

All notable changes to this project will be documented in this file.
Expand All @@ -16,10 +17,15 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve

### Changed

- We restructured the 'File' tab and extracted some parts into the 'Linked files' tab [#6779](https://github.com/JabRef/jabref/pull/6779)
- JabRef now offers journal lists from <https://abbrv.jabref.org>. JabRef the lists which use a dot inside the abbreviations. [#5749](https://github.com/JabRef/jabref/pull/5749)

### Fixed

- We fixed an issue where the `.sav` file was not deleted upon exiting JabRef. [#6109](https://github.com/JabRef/jabref/issues/6109)
- We fixed a linked identifier icon inconsistency. [#6705](https://github.com/JabRef/jabref/issues/6705)
- We fixed the wrong behavior that font size changes are not reflected in dialogs. [#6039](https://github.com/JabRef/jabref/issues/6039)

### Removed


Expand Down
2 changes: 1 addition & 1 deletion docs/adr/0003-use-gradle-as-build-tool.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Chosen option: "Gradle", because it is lean and fits our development style.
* Good, because [it offers custom dependency scopes](https://gradle.org/maven-vs-gradle/)
* Good, because [it has good community support](https://linuxhint.com/ant-vs-maven-vs-gradle/)
* Good, because [its performance can be 100 times more than maven's performance](https://gradle.org/gradle-vs-maven-performance/).
* Bad, because [not that many plugins are available/maintained yet](https://blog.philipphauer.de/moving-back-from-gradle-to-maven/)
* Bad, because [not that many plugins are available/maintained yet](https://phauer.com/2018/moving-back-from-gradle-to-maven/)
* Bad, because [it lacks a wide variety of application server integrations](http://pages.zeroturnaround.com/rs/zeroturnaround/images/java-build-tools-part-2.pdf)
* Bad, because [it has a medium popularity](http://pages.zeroturnaround.com/rs/zeroturnaround/images/java-build-tools-part-2.pdf)
* Bad, because [it allows custom build scripts which need to be debugged](https://www.softwareyoga.com/10-reasons-why-we-chose-maven-over-gradle/)
Expand Down
16 changes: 16 additions & 0 deletions docs/adr/0016-mutable-preferences-objects.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Mutable preferences objects

## Context and Problem Statement

To create an immutable preferences object every time seems to be a waste of time and computer memory.

## Considered Options

* Create a new object every time a preferences object should be altered by a with*-method, similar to a Builder.
* Alter the existing object and return it.

## Decision Outcome

Chosen option: 1, because the preferences objects are just wrappers around the basic preferences framework of JDK. They
should be mutable on-the-fly similar to objects with a Builder inside and to be stored immediatly again in the
preferences.
88 changes: 41 additions & 47 deletions docs/adr/template.md
Original file line number Diff line number Diff line change
@@ -1,73 +1,67 @@
# \[short title of solved problem and solution\]
# MADR Templae

* Status: \[proposed \| rejected \| accepted \| deprecated \|\| superseded by [ADR-0005](0005-fully-support-utf8-only-for-latex-files.md)\]
* Deciders: \[list everyone involved in the decision\]
* Date: \[YYYY-MM-DD when the decision was last updated\]
The template of [MADR](https://adr.github.io/madr/) is available at <https://github.com/adr/madr#the-template>.
You can omit the `<-- optional -->` parts, which lead to a very minimal ADR:

Technical Story: \[description \| ticket/issue URL\]
```markdown
# [short title of solved problem and solution]

## Context and Problem Statement

\[Describe the context and problem statement, e.g., in free form using two to three sentences. You may want to articulate the problem in form of a question.\]

## Decision Drivers

* \[driver 1, e.g., a force, facing concern, …\]
* \[driver 2, e.g., a force, facing concern, …\]
*
[Describe the context and problem statement, e.g., in free form using two to three sentences. You may want to articulate the problem in form of a question.]

## Considered Options

* \[option 1\]
* \[option 2\]
* \[option 3\]
*
* [option 1]
* [option 2]
* [option 3]
* … <!-- numbers of options can vary -->

## Decision Outcome

Chosen option: "\[option 1\]", because \[justification. e.g., only option, which meets k.o. criterion decision driver \| which resolves force force \|\| comes out best \(see below\)\].

### Positive Consequences
Chosen option: "[option 1]", because [justification. e.g., only option, which meets k.o. criterion decision driver | which resolves force force | … ].
```

* \[e.g., improvement of quality attribute satisfaction, follow-up decisions required, …\]
*
In case you want to include the pros and cons of the options, the template is as follows:

### Negative Consequences
```markdown
# [short title of solved problem and solution]

* \[e.g., compromising quality attribute, follow-up decisions required, …\]
*

## Pros and Cons of the Options
## Context and Problem Statement

### \[option 1\]
[Describe the context and problem statement, e.g., in free form using two to three sentences. You may want to articulate the problem in form of a question.]

\[example \| description \| pointer to more information \|\]
## Considered Options

* Good, because \[argument a\]
* Good, because \[argument b\]
* Bad, because \[argument c\]
*
* [option 1]
* [option 2]
* [option 3]
* … <!-- numbers of options can vary -->

### \[option 2\]
## Decision Outcome

\[example \| description \| pointer to more information \|\]
Chosen option: "[option 1]", because comes out best (see below).

* Good, because \[argument a\]
* Good, because \[argument b\]
* Bad, because \[argument c\]
*
## Pros and Cons of the Options

### \[option 3\]
### [option 1]

\[example \| description \| pointer to more information \|\]
* Good, because [argument a]
* Good, because [argument b]
* Bad, because [argument c]
* … <!-- numbers of pros and cons can vary -->

* Good, because \[argument a\]
* Good, because \[argument b\]
* Bad, because \[argument c\]
*
### [option 2]

## Links
* Good, because [argument a]
* Good, because [argument b]
* Bad, because [argument c]
* … <!-- numbers of pros and cons can vary -->

* \[Link type\] \[Link to ADR\]
*
### [option 3]

* Good, because [argument a]
* Good, because [argument b]
* Bad, because [argument c]
* … <!-- numbers of pros and cons can vary -->
```
42 changes: 37 additions & 5 deletions src/main/java/org/jabref/JabRefExecutorService.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,29 @@
public class JabRefExecutorService {

public static final JabRefExecutorService INSTANCE = new JabRefExecutorService();

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

private final ExecutorService executorService = Executors.newCachedThreadPool(r -> {
Thread thread = new Thread(r);
thread.setName("JabRef CachedThreadPool");
thread.setUncaughtExceptionHandler(new FallbackExceptionHandler());
return thread;
});

private final ExecutorService lowPriorityExecutorService = Executors.newCachedThreadPool(r -> {
Thread thread = new Thread(r);
thread.setName("JabRef LowPriorityCachedThreadPool");
thread.setUncaughtExceptionHandler(new FallbackExceptionHandler());
return thread;
});

private final Timer timer = new Timer("timer", true);

private Thread remoteThread;

private JabRefExecutorService() {
}
}

public void execute(Runnable command) {
Objects.requireNonNull(command);
Expand Down Expand Up @@ -132,13 +137,16 @@ public void submit(TimerTask timerTask, long millisecondsDelay) {
timer.schedule(timerTask, millisecondsDelay);
}

/**
* Shuts everything down. After termination, this method returns.
*/
public void shutdownEverything() {
// those threads will be allowed to finish
this.executorService.shutdown();
// those threads will be interrupted in their current task
this.lowPriorityExecutorService.shutdownNow();
// kill the remote thread
stopRemoteThread();

gracefullyShutdown(this.executorService);
gracefullyShutdown(this.lowPriorityExecutorService);

timer.cancel();
}

Expand All @@ -164,4 +172,28 @@ public void run() {
}
}
}

/**
* Shuts down the provided executor service by first trying a normal shutdown, then waiting for the shutdown and then forcibly shutting it down.
* Returns if the status of the shut down is known.
*/
public static void gracefullyShutdown(ExecutorService executorService) {
try {
// This is non-blocking. See https://stackoverflow.com/a/57383461/873282.
executorService.shutdown();
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
LOGGER.debug("One minute passed, {} still not completed. Trying forced shutdown.", executorService.toString());
// those threads will be interrupted in their current task
executorService.shutdownNow();
if (executorService.awaitTermination(60, TimeUnit.SECONDS)) {
LOGGER.debug("One minute passed again - forced shutdown of {} worked.", executorService.toString());
} else {
LOGGER.error("{} did not terminate", executorService.toString());
}
}
} catch (InterruptedException ie) {
executorService.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
7 changes: 6 additions & 1 deletion src/main/java/org/jabref/JabRefMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.jabref.cli.JabRefCLI;
import org.jabref.gui.FXDialog;
import org.jabref.gui.remote.JabRefMessageHandler;
import org.jabref.logic.exporter.ExporterFactory;
import org.jabref.logic.journals.JournalAbbreviationLoader;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.net.ProxyAuthenticator;
Expand Down Expand Up @@ -168,7 +169,11 @@ private static void applyPreferences(JabRefPreferences preferences) {
Globals.prefs.getXMPPreferences(), Globals.getFileUpdateMonitor());
Globals.entryTypesManager.addCustomOrModifiedTypes(preferences.loadBibEntryTypes(BibDatabaseMode.BIBTEX),
preferences.loadBibEntryTypes(BibDatabaseMode.BIBLATEX));
Globals.exportFactory = Globals.prefs.getExporterFactory(Globals.journalAbbreviationRepository);
Globals.exportFactory = ExporterFactory.create(
Globals.prefs.getCustomExportFormats(Globals.journalAbbreviationRepository),
Globals.prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationRepository),
Globals.prefs.getSavePreferencesForExport(),
Globals.prefs.getXMPPreferences());

// Initialize protected terms loader
Globals.protectedTermsLoader = new ProtectedTermsLoader(Globals.prefs.getProtectedTermsPreferences());
Expand Down
20 changes: 12 additions & 8 deletions src/main/java/org/jabref/cli/ArgumentProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ private boolean exportMatches(List<ParserResult> loaded) {

// export new database
Optional<Exporter> exporter = Globals.exportFactory.getExporterByName(formatName);
if (!exporter.isPresent()) {
if (exporter.isEmpty()) {
System.err.println(Localization.lang("Unknown export format") + ": " + formatName);
} else {
// We have an TemplateExporter instance:
Expand Down Expand Up @@ -387,7 +387,7 @@ private boolean generateAux(List<ParserResult> loaded, String[] data) {
private void saveDatabase(BibDatabase newBase, String subName) {
try {
System.out.println(Localization.lang("Saving") + ": " + subName);
SavePreferences prefs = Globals.prefs.loadForSaveFromPreferences();
SavePreferences prefs = Globals.prefs.getSavePreferences();
AtomicFileWriter fileWriter = new AtomicFileWriter(Path.of(subName), prefs.getEncoding());
BibDatabaseWriter databaseWriter = new BibtexDatabaseWriter(fileWriter, prefs, Globals.entryTypesManager);
databaseWriter.saveDatabase(new BibDatabaseContext(newBase));
Expand Down Expand Up @@ -435,7 +435,7 @@ private void exportFile(List<ParserResult> loaded, String[] data) {
.getFileDirectories(Globals.prefs.getFilePreferences());
System.out.println(Localization.lang("Exporting") + ": " + data[0]);
Optional<Exporter> exporter = Globals.exportFactory.getExporterByName(data[1]);
if (!exporter.isPresent()) {
if (exporter.isEmpty()) {
System.err.println(Localization.lang("Unknown export format") + ": " + data[1]);
} else {
// We have an exporter:
Expand All @@ -458,9 +458,9 @@ private void importPreferences() {
Globals.entryTypesManager.addCustomOrModifiedTypes(Globals.prefs.loadBibEntryTypes(BibDatabaseMode.BIBTEX),
Globals.prefs.loadBibEntryTypes(BibDatabaseMode.BIBLATEX));
List<TemplateExporter> customExporters = Globals.prefs.getCustomExportFormats(Globals.journalAbbreviationRepository);
LayoutFormatterPreferences layoutPreferences = Globals.prefs
.getLayoutFormatterPreferences(Globals.journalAbbreviationRepository);
SavePreferences savePreferences = Globals.prefs.loadForExportFromPreferences();
LayoutFormatterPreferences layoutPreferences =
Globals.prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationRepository);
SavePreferences savePreferences = Globals.prefs.getSavePreferencesForExport();
XmpPreferences xmpPreferences = Globals.prefs.getXMPPreferences();
Globals.exportFactory = ExporterFactory.create(customExporters, layoutPreferences, savePreferences, xmpPreferences);
} catch (JabRefException ex) {
Expand Down Expand Up @@ -495,7 +495,11 @@ private void automaticallySetFileLinks(List<ParserResult> loaded) {
for (ParserResult parserResult : loaded) {
BibDatabase database = parserResult.getDatabase();
LOGGER.info(Localization.lang("Automatically setting file links"));
AutoSetFileLinksUtil util = new AutoSetFileLinksUtil(parserResult.getDatabaseContext(), Globals.prefs.getFilePreferences(), Globals.prefs.getAutoLinkPreferences(), ExternalFileTypes.getInstance());
AutoSetFileLinksUtil util = new AutoSetFileLinksUtil(
parserResult.getDatabaseContext(),
Globals.prefs.getFilePreferences(),
Globals.prefs.getAutoLinkPreferences(),
ExternalFileTypes.getInstance());
util.linkAssociatedFiles(database.getEntries(), new NamedCompound(""));
}
}
Expand Down Expand Up @@ -534,7 +538,7 @@ private Optional<ParserResult> fetch(String fetchCommand) {
Optional<SearchBasedFetcher> selectedFetcher = fetchers.stream()
.filter(fetcher -> fetcher.getName().equalsIgnoreCase(engine))
.findFirst();
if (!selectedFetcher.isPresent()) {
if (selectedFetcher.isEmpty()) {
System.out.println(Localization.lang("Could not find fetcher '%0'", engine));

System.out.println(Localization.lang("The following fetchers are available:"));
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/EntryTypeViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

import org.jabref.Globals;
import org.jabref.gui.duplicationFinder.DuplicateResolverDialog;
import org.jabref.logic.bibtex.DuplicateCheck;
import org.jabref.logic.citationkeypattern.CitationKeyGenerator;
import org.jabref.logic.database.DuplicateCheck;
import org.jabref.logic.importer.FetcherException;
import org.jabref.logic.importer.IdBasedFetcher;
import org.jabref.logic.importer.WebFetchers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import org.jabref.gui.undo.UndoableRemoveEntries;
import org.jabref.gui.util.BackgroundTask;
import org.jabref.gui.util.DefaultTaskExecutor;
import org.jabref.logic.bibtex.DuplicateCheck;
import org.jabref.logic.database.DuplicateCheck;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.database.BibDatabaseMode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public ExporterViewModel saveExporter() {

// Create a new exporter to be returned to ExportCustomizationDialogViewModel, which requested it
LayoutFormatterPreferences layoutPreferences = preferences.getLayoutFormatterPreferences(repository);
SavePreferences savePreferences = preferences.loadForExportFromPreferences();
SavePreferences savePreferences = preferences.getSavePreferencesForExport();
TemplateExporter format = new TemplateExporter(name.get(), layoutFile.get(), extension.get(),
layoutPreferences, savePreferences);
format.setCustomExport(true);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/exporter/ExportCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public ExportCommand(JabRefFrame frame, boolean selectedOnly, JabRefPreferences
public void execute() {
List<TemplateExporter> customExporters = preferences.getCustomExportFormats(Globals.journalAbbreviationRepository);
LayoutFormatterPreferences layoutPreferences = preferences.getLayoutFormatterPreferences(Globals.journalAbbreviationRepository);
SavePreferences savePreferences = preferences.loadForExportFromPreferences();
SavePreferences savePreferences = preferences.getSavePreferencesForExport();
XmpPreferences xmpPreferences = preferences.getXMPPreferences();

// Get list of exporters and sort before adding to file dialog
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ private Optional<Path> askForSavePath() {

private boolean save(BibDatabaseContext bibDatabaseContext, SaveDatabaseMode mode) {
Optional<Path> databasePath = bibDatabaseContext.getDatabasePath();
if (!databasePath.isPresent()) {
if (databasePath.isEmpty()) {
Optional<Path> savePath = askForSavePath();
if (!savePath.isPresent()) {
return false;
Expand Down Expand Up @@ -238,10 +238,10 @@ private boolean save(Path targetPath, SaveDatabaseMode mode) {
}

private boolean saveDatabase(Path file, boolean selectedOnly, Charset encoding, SavePreferences.DatabaseSaveType saveType) throws SaveException {
SavePreferences preferences = this.preferences.loadForSaveFromPreferences()
SavePreferences preferences = this.preferences.getSavePreferences()
.withEncoding(encoding)
.withSaveType(saveType);
try (AtomicFileWriter fileWriter = new AtomicFileWriter(file, preferences.getEncoding(), preferences.makeBackup())) {
try (AtomicFileWriter fileWriter = new AtomicFileWriter(file, preferences.getEncoding(), preferences.shouldMakeBackup())) {
BibtexDatabaseWriter databaseWriter = new BibtexDatabaseWriter(fileWriter, preferences, entryTypesManager);

if (selectedOnly) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,12 @@ public void execute() {
List<BibEntry> entries = stateManager.getSelectedEntries();

final NamedCompound nc = new NamedCompound(Localization.lang("Automatically set file links"));
AutoSetFileLinksUtil util = new AutoSetFileLinksUtil(database, preferences.getFilePreferences(), preferences.getAutoLinkPreferences(), ExternalFileTypes.getInstance());
Task<List<BibEntry>> linkFilesTask = new Task<List<BibEntry>>() {
AutoSetFileLinksUtil util = new AutoSetFileLinksUtil(
database,
preferences.getFilePreferences(),
preferences.getAutoLinkPreferences(),
ExternalFileTypes.getInstance());
Task<List<BibEntry>> linkFilesTask = new Task<>() {

@Override
protected List<BibEntry> call() {
Expand Down
Loading

0 comments on commit 7b68deb

Please sign in to comment.