Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into biblatexDateCleanup
Browse files Browse the repository at this point in the history
* upstream/master:
  builds.jabref.org: Keep html files and just remove *.exe, *.dmg, *.jar during upload of a new build
  Fix comment typo
  Fix typos in comments in .travis.yml
  Switch to LGoodDatePicker (#2340)
  Gradle build scans should only run on TravisCI, not on the other CI services
  Try scans.gradle.com
  Remove reference to GPL - we are MIT now
  fix date changes in medline fetcher results
  Fix #2336: shutdown is working again (#2338)
  • Loading branch information
Siedlerchr committed Dec 5, 2016
2 parents 65454d9 + 8ccd424 commit 15f8c51
Show file tree
Hide file tree
Showing 14 changed files with 126 additions and 137 deletions.
12 changes: 6 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ language: java

# we test at Ubuntu Trusty (Ubuntu 14.04 LTS)
# see https://docs.travis-ci.com/user/trusty-ci-environment/
# This environment is continuosly updated as described in https://docs.travis-ci.com/user/build-environment-updates/
# This environment is continuously updated as described in https://docs.travis-ci.com/user/build-environment-updates/
dist: trusty
sudo: required

Expand All @@ -20,8 +20,8 @@ before_script:
- mysql -u root -e 'create database jabref'

script:
- ./gradlew check
- ./gradlew databaseTest
- ./gradlew check -Dscan
- ./gradlew databaseTest -Dscan
# Prepare integration tests
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
Expand All @@ -30,7 +30,7 @@ script:
# currently does not work: "stop: Unknown instance:" - sudo service mysql stop
- sudo service postgresql stop
# following services identified by "sudo service --status-all" do not need to run, too
# excluded: rsyslog (feels wrong), udev (feels wrong), friendly-recovery ("Unkonwn instance" error)
# excluded: rsyslog (feels wrong), udev (feels wrong), friendly-recovery ("Unknown instance" error)
- sudo service acpid stop
- sudo service atd stop
- sudo service cron stop
Expand All @@ -40,8 +40,8 @@ script:
- sudo service resolvconf stop
- sudo service sshguard stop
- sudo service ssh stop
# Integratation tests run in a timeout. Just start them and kill them after 60s
- timeout 60 ./gradlew integrationTest --info || true
# Integration tests run in a timeout. Just start them and kill them after 60s.
- timeout 60 ./gradlew integrationTest -Dscan --info || true

after_script:
# enable codecov report
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#


### Fixed
- We fixed an issue which prevented JabRef from closing using the "Quit" menu command. [#2336](https://github.com/JabRef/jabref/issues/2336)
- We fixed an issue which caused a metadata loss on reconnection to shared database. [#2219](https://github.com/JabRef/jabref/issues/2219)
- We fixed an issue which caused an internal error when leaving the file path field empty and connecting to a shared database.
- We fixed an issue where the file permissions of the .bib-file were changed upon saving [#2279](https://github.com/JabRef/jabref/issues/2279).
Expand Down
9 changes: 9 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,20 @@ buildscript {
}

plugins {
id 'com.gradle.build-scan' version '1.3'
id "com.install4j.gradle" version "6.1.3"
id 'com.github.johnrengelman.shadow' version '1.2.3'
// If this is updated to 0.0.9, check configurations.errorprone
id "net.ltgt.errorprone" version "0.0.8"
id 'me.champeau.gradle.jmh' version '0.3.1'
}

// use the gradle build scan feature: https://scans.gradle.com/get-started
buildScan {
licenseAgreementUrl = 'https://gradle.com/terms-of-service'
licenseAgree = 'yes'
}

apply plugin: "java"
apply plugin: "application"
apply plugin: "project-report"
Expand Down Expand Up @@ -123,6 +130,8 @@ dependencies {
compile 'org.citationstyles:styles:1.0.1-SNAPSHOT'
compile 'org.citationstyles:locales:1.0.1-SNAPSHOT'
compile 'de.undercouch:citeproc-java:1.0.1'

compile 'com.github.lgooddatepicker:LGoodDatePicker:8.2.2'

testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:2.2.26'
Expand Down
9 changes: 4 additions & 5 deletions external-libraries.txt
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,10 @@ Project: SwingX
URL: https://swingx.java.net/
License: LGPL-3.0

Id: microba
Path: lib/microba.jar
Project: Microba
URL: https://github.com/tdbear/microba
License: BSD
Id: com.github.lgooddatepicker:LGoodDatePicker
Project: LGoodDatePicker
URL: https://github.com/LGoodDatePicker/LGoodDatePicker
License: MIT

Id: spin
Path: lib/spin.jar
Expand Down
Binary file removed lib/microba.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion scripts/upload-to-builds.jabref.org.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ command="cd www/\n"
# then, "snapshot" is extracted
if [ "snapshot" != "$branch" ] ; then
# change into dir and delete old snapshots
command="${command}mkdir $branch\ncd $branch\nrm *\n"
command="${command}mkdir $branch\ncd $branch\nrm *.dmg\nrm *.jar\nrm *.exe\n"
fi

#only upload [Jr]ab[Rr]ef*, not md5sums, updates.xml, etc.
Expand Down
1 change: 1 addition & 0 deletions src/main/java/net/sf/jabref/gui/IconTheme.java
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ public enum JabRefIcon {
FACEBOOK("\uf20c"), /* css: facebook */
BLOG("\uf46b"), /* css: rss */
GLOBAL_SEARCH("\uF1E7"), /* css: earth */
DATE_PICKER("\uF0ED;"), /* css: calendar */
// STILL MISSING:
GROUP_REGULAR("\uF4E6", Color.RED);

Expand Down
7 changes: 1 addition & 6 deletions src/main/java/net/sf/jabref/gui/JabRefFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -1684,9 +1684,7 @@ public void addTab(BasePanel basePanel, boolean raisePanel) {
autosaver.registerListener(new AutosaveUIManager(basePanel));
}

if (readyForBackup(context)) {
BackupManager.start(context);
}
BackupManager.start(context);
}

public BasePanel addTab(BibDatabaseContext databaseContext, boolean raisePanel) {
Expand All @@ -1702,9 +1700,6 @@ private boolean readyForAutosave(BibDatabaseContext context) {
context.getDatabaseFile().isPresent();
}

private boolean readyForBackup(BibDatabaseContext context) {
return context.getLocation() == DatabaseLocation.LOCAL && context.getDatabaseFile().isPresent();
}

/**
* Creates icons for the disabled state for all JMenuItems with FontBasedIcons in the given menuElement.
Expand Down
39 changes: 24 additions & 15 deletions src/main/java/net/sf/jabref/gui/date/DatePickerButton.java
Original file line number Diff line number Diff line change
@@ -1,51 +1,60 @@
package net.sf.jabref.gui.date;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

import javax.swing.JComponent;
import javax.swing.JPanel;

import net.sf.jabref.Globals;
import net.sf.jabref.gui.IconTheme;
import net.sf.jabref.gui.fieldeditors.FieldEditor;
import net.sf.jabref.logic.util.date.EasyDateFormat;
import net.sf.jabref.preferences.JabRefPreferences;

import com.michaelbaranov.microba.calendar.DatePicker;
import com.github.lgooddatepicker.components.DatePicker;
import com.github.lgooddatepicker.components.DatePickerSettings;
import com.github.lgooddatepicker.optionalusertools.DateChangeListener;
import com.github.lgooddatepicker.zinternaltools.DateChangeEvent;

/**
* wrapper and service class for the DatePicker handling at the EntryEditor
*/
public class DatePickerButton implements ActionListener {
public class DatePickerButton implements DateChangeListener {

private final DatePicker datePicker = new DatePicker();
private final DatePicker datePicker;
private final JPanel panel = new JPanel();
private final FieldEditor editor;
private final boolean isoFormat;


public DatePickerButton(FieldEditor pEditor, Boolean isoFormat) {
this.isoFormat = isoFormat;
datePicker.showButtonOnly(true);
datePicker.addActionListener(this);
datePicker.setShowTodayButton(true);
// Create a date picker with hidden text field (showing button only).
DatePickerSettings dateSettings = new DatePickerSettings();
dateSettings.setVisibleDateTextField(false);
dateSettings.setGapBeforeButtonPixels(0);

datePicker = new DatePicker(dateSettings);
datePicker.addDateChangeListener(this);
datePicker.getComponentToggleCalendarButton().setIcon(IconTheme.JabRefIcon.DATE_PICKER.getIcon());
datePicker.getComponentToggleCalendarButton().setText("");

panel.setLayout(new BorderLayout());
panel.add(datePicker, BorderLayout.WEST);
editor = pEditor;
}

@Override
public void actionPerformed(ActionEvent e) {
Date date = datePicker.getDate();
public void dateChanged(DateChangeEvent dateChangeEvent) {
LocalDate date = datePicker.getDate();
if (date != null) {
if (isoFormat) {
editor.setText(EasyDateFormat.isoDateFormat().getDateAt(date));
editor.setText(date.format(DateTimeFormatter.ISO_DATE));
} else {
editor.setText(EasyDateFormat
.fromTimeStampFormat(Globals.prefs.get(JabRefPreferences.TIME_STAMP_FORMAT))
.getDateAt(date));
EasyDateFormat.fromTimeStampFormat(Globals.prefs.get(JabRefPreferences.TIME_STAMP_FORMAT)).getDateAt(ZonedDateTime.from(date));
}
} else {
// in this case the user selected "none" in the date picker, so we just clear the field
Expand Down
134 changes: 64 additions & 70 deletions src/main/java/net/sf/jabref/logic/autosaveandbackup/BackupManager.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package net.sf.jabref.logic.autosaveandbackup;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
Expand Down Expand Up @@ -31,7 +30,8 @@

/**
* Backups the given bib database file from {@link BibDatabaseContext} on every {@link BibDatabaseContextChangedEvent}.
* An intelligent {@link ExecutorService} with a {@link BlockingQueue} prevents a high load while making backups and rejects all redundant backup tasks.
* An intelligent {@link ExecutorService} with a {@link BlockingQueue} prevents a high load while making backups and
* rejects all redundant backup tasks.
* This class does not manage the .bak file which is created when opening a database.
*/
public class BackupManager {
Expand All @@ -44,63 +44,19 @@ public class BackupManager {

private final BibDatabaseContext bibDatabaseContext;
private final JabRefPreferences preferences;
private final BlockingQueue<Runnable> workerQueue;
private final ExecutorService executor;
private final Charset charset;

private Path originalPath;
private Path backupPath;
private final Runnable backupTask = () -> determineBackupPath().ifPresent(this::performBackup);


private BackupManager(BibDatabaseContext bibDatabaseContext) {
this.bibDatabaseContext = bibDatabaseContext;
this.preferences = JabRefPreferences.getInstance();
this.workerQueue = new ArrayBlockingQueue<>(1);
BlockingQueue<Runnable> workerQueue = new ArrayBlockingQueue<>(1);
this.executor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS, workerQueue);
this.charset = bibDatabaseContext.getMetaData().getEncoding().orElse(preferences.getDefaultEncoding());
}


private final Runnable backupTask = new Runnable() {
@Override
public void run() {
try {
SavePreferences prefs = SavePreferences.loadForSaveFromPreferences(preferences).withEncoding(charset).withMakeBackup(false);
new BibtexDatabaseWriter<>(FileSaveSession::new).saveDatabase(bibDatabaseContext, prefs).commit(backupPath);
} catch (SaveException e) {
LOGGER.error("Error while saving file.", e);
}
}
};

@Subscribe
public synchronized void listen(@SuppressWarnings("unused") BibDatabaseContextChangedEvent event) {
startBackupTask();
}

private void startBackupTask() {
try {
executor.submit(backupTask);
} catch (RejectedExecutionException e) {
LOGGER.debug("Rejecting while another backup process is already running.");
}
}

/**
* Unregisters the BackupManager from the eventBus of {@link BibDatabaseContext} and deletes the backup file.
* This method should only be used when closing a database/JabRef legally.
*/
private void shutdown() {
bibDatabaseContext.getDatabase().unregisterListener(this);
bibDatabaseContext.getMetaData().unregisterListener(this);
executor.shutdown();
try {
if (Files.exists(backupPath) && !Files.isDirectory(backupPath)) {
Files.delete(backupPath);
}
} catch (IOException e) {
LOGGER.error("Error while deleting the backup file.", e);
}
// Listen for change events
bibDatabaseContext.getDatabase().registerListener(this);
bibDatabaseContext.getMetaData().registerListener(this);
}

static Path getBackupPath(Path originalPath) {
Expand All @@ -109,38 +65,26 @@ static Path getBackupPath(Path originalPath) {

/**
* Starts the BackupManager which is associated with the given {@link BibDatabaseContext}.
* If no database file is present in {@link BibDatabaseContext}, {@link BackupManager} will do nothing.
* As long as no database file is present in {@link BibDatabaseContext}, the {@link BackupManager} will do nothing.
*
* @param bibDatabaseContext Associated {@link BibDatabaseContext}
*/
public static BackupManager start(BibDatabaseContext bibDatabaseContext) {
BackupManager backupManager = new BackupManager(bibDatabaseContext);

Optional<File> originalFile = bibDatabaseContext.getDatabaseFile();

if (originalFile.isPresent()) {
backupManager.originalPath = originalFile.get().toPath();
backupManager.backupPath = getBackupPath(backupManager.originalPath);
backupManager.startBackupTask();
bibDatabaseContext.getDatabase().registerListener(backupManager);
bibDatabaseContext.getMetaData().registerListener(backupManager);
runningInstances.add(backupManager);
}

backupManager.startBackupTask();
runningInstances.add(backupManager);
return backupManager;
}

/**
* Shuts down the BackupManager which is associated with the given {@link BibDatabaseContext}
* Shuts down the BackupManager which is associated with the given {@link BibDatabaseContext}.
*
* @param bibDatabaseContext Associated {@link BibDatabaseContext}
*/
public static void shutdown(BibDatabaseContext bibDatabaseContext) {
runningInstances.stream().filter(instance -> instance.bibDatabaseContext == bibDatabaseContext).findAny()
.ifPresent(instance -> {
instance.shutdown();
runningInstances.remove(instance);
});
runningInstances.stream().filter(instance -> instance.bibDatabaseContext == bibDatabaseContext).forEach(
BackupManager::shutdown);
runningInstances.removeIf(instance -> instance.bibDatabaseContext == bibDatabaseContext);
}

/**
Expand All @@ -166,4 +110,54 @@ public static void restoreBackup(Path originalPath) {
LOGGER.error("Error while restoring the backup file.", e);
}
}

private Optional<Path> determineBackupPath() {
return bibDatabaseContext.getDatabasePath().map(BackupManager::getBackupPath);
}

private void performBackup(Path backupPath) {
try {
Charset charset = bibDatabaseContext.getMetaData().getEncoding().orElse(preferences.getDefaultEncoding());
SavePreferences savePreferences = SavePreferences.loadForSaveFromPreferences(preferences).withEncoding
(charset).withMakeBackup(false);
new BibtexDatabaseWriter<>(FileSaveSession::new).saveDatabase(bibDatabaseContext, savePreferences).commit
(backupPath);
} catch (SaveException e) {
LOGGER.error("Error while saving file.", e);
}
}

@Subscribe
public synchronized void listen(@SuppressWarnings("unused") BibDatabaseContextChangedEvent event) {
startBackupTask();
}

private void startBackupTask() {
try {
executor.submit(backupTask);
} catch (RejectedExecutionException e) {
LOGGER.debug("Rejecting while another backup process is already running.");
}
}

/**
* Unregisters the BackupManager from the eventBus of {@link BibDatabaseContext} and deletes the backup file.
* This method should only be used when closing a database/JabRef legally.
*/
private void shutdown() {
bibDatabaseContext.getDatabase().unregisterListener(this);
bibDatabaseContext.getMetaData().unregisterListener(this);
executor.shutdown();
determineBackupPath().ifPresent(this::deleteBackupFile);
}

private void deleteBackupFile(Path backupPath) {
try {
if (Files.exists(backupPath) && !Files.isDirectory(backupPath)) {
Files.delete(backupPath);
}
} catch (IOException e) {
LOGGER.error("Error while deleting the backup file.", e);
}
}
}
Loading

0 comments on commit 15f8c51

Please sign in to comment.