Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added option in preferences to use custom URL base for DOI generation #7480

Merged
merged 11 commits into from
Mar 8, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public IdentifierEditor(Field field,
SuggestionProvider<?> suggestionProvider,
FieldCheckers fieldCheckers,
PreferencesService preferences) {
this.viewModel = new IdentifierEditorViewModel(field, suggestionProvider, taskExecutor, dialogService, fieldCheckers);
this.viewModel = new IdentifierEditorViewModel(field, suggestionProvider, taskExecutor, dialogService, fieldCheckers, preferences);

ViewLoader.view(this)
.root(this)
Expand All @@ -50,6 +50,7 @@ public IdentifierEditor(Field field,
new Tooltip(Localization.lang("Look up %0", field.getDisplayName())));

if (field.equals(StandardField.DOI)) {

textArea.initContextMenu(EditorMenus.getDOIMenu(textArea));
} else {
textArea.initContextMenu(new DefaultMenu(textArea));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.Field;
import org.jabref.model.entry.field.StandardField;
import org.jabref.model.entry.identifier.DOI;
import org.jabref.model.entry.identifier.Identifier;
import org.jabref.preferences.PreferencesService;

import com.tobiasdiez.easybind.EasyBind;

Expand All @@ -32,12 +35,16 @@ public class IdentifierEditorViewModel extends AbstractEditorViewModel {
private final ObjectProperty<Optional<? extends Identifier>> identifier = new SimpleObjectProperty<>();
private final TaskExecutor taskExecutor;
private final DialogService dialogService;
private final Field field;
private PreferencesService preferences;

public IdentifierEditorViewModel(Field field, SuggestionProvider<?> suggestionProvider, TaskExecutor taskExecutor, DialogService dialogService, FieldCheckers fieldCheckers) {
public IdentifierEditorViewModel(Field field, SuggestionProvider<?> suggestionProvider, TaskExecutor taskExecutor, DialogService dialogService, FieldCheckers fieldCheckers, PreferencesService preferences) {
super(field, suggestionProvider, fieldCheckers);

this.taskExecutor = taskExecutor;
this.dialogService = dialogService;
this.preferences = preferences;
this.field = field;

identifier.bind(
EasyBind.map(text, input -> IdentifierParser.parse(field, input))
Expand Down Expand Up @@ -67,6 +74,15 @@ public BooleanProperty validIdentifierIsNotPresentProperty() {
}

public void openExternalLink() {
if (field.equals(StandardField.DOI) && preferences.getDOIPreferences().isUseCustom()) {
String baseURI = preferences.getDOIPreferences().getDefaultBaseURI();
openDOIWithCustomBase(baseURI);
} else {
openExternalLinkDefault();
}
}

public void openExternalLinkDefault() {
identifier.get().flatMap(Identifier::getExternalURI).ifPresent(
url -> {
try {
Expand All @@ -78,6 +94,18 @@ public void openExternalLink() {
);
}

public void openDOIWithCustomBase(String baseURI) {
identifier.get().map(x -> (DOI) x).flatMap(x -> x.getExternalURIWithCustomBase(baseURI)).ifPresent(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
identifier.get().map(x -> (DOI) x).flatMap(x -> x.getExternalURIWithCustomBase(baseURI)).ifPresent(
identifier.get().map(identifier-> (DOI) identifier).flatMap(DOI::getExternalURIWithCustomBase(baseURI)).ifPresent(

please no single char variable name like x, use a meaninfgul variable and inside the flatmap you should be able to use a static syntax like DOI::getExternalUriWithCustomBase

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct me if I'm wrong but since flatMap requires Function and we have two input arguments (String baseUri and DOI) is it not impossible to implement the static syntax? IntelliJ seems to agree with that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, overlooked that, you are right

uri -> {
try {
JabRefDesktop.openBrowser(uri);
} catch (IOException ex) {
dialogService.showErrorDialogAndWait(Localization.lang("Unable to open link."), ex);
}
}
);
}

public boolean getIdentifierLookupInProgress() {
return identifierLookupInProgress.get();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.jabref.gui.JabRefFrame;
import org.jabref.gui.preferences.appearance.AppearanceTab;
import org.jabref.gui.preferences.citationkeypattern.CitationKeyPatternTab;
import org.jabref.gui.preferences.customization.CustomizationTab;
import org.jabref.gui.preferences.entryeditor.EntryEditorTab;
import org.jabref.gui.preferences.entryeditortabs.CustomEditorFieldsTab;
import org.jabref.gui.preferences.exporter.ExportCustomizationTab;
Expand Down Expand Up @@ -74,6 +75,7 @@ public PreferencesDialogViewModel(DialogService dialogService, PreferencesServic
new JournalAbbreviationsTab(),
new GroupsTab(),
new EntryEditorTab(),
new CustomizationTab(),
new CustomEditorFieldsTab(),
new CitationKeyPatternTab(),
new LinkedFilesTab(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.layout.HBox?>
<fx:root spacing="10.0" type="VBox"
xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml"
fx:controller="org.jabref.gui.preferences.customization.CustomizationTab">
<Label styleClass="titleHeader" text="%Customization"/>

<Label styleClass="sectionHeader" text="%Custom DOI URI"/>
<HBox alignment="CENTER_LEFT" spacing="10.0">
<CheckBox fx:id="useCustomDOI" text="%Use custom DOI base URI for article access"/>
<TextField fx:id="useCustomDOIName" HBox.hgrow="ALWAYS"/>
</HBox>
</fx:root>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing newline at the end of the file

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.jabref.gui.preferences.customization;

import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TextField;

import org.jabref.gui.preferences.AbstractPreferenceTabView;
import org.jabref.gui.preferences.PreferencesTab;
import org.jabref.logic.l10n.Localization;

import com.airhacks.afterburner.views.ViewLoader;

public class CustomizationTab extends AbstractPreferenceTabView<CustomizationTabViewModel> implements PreferencesTab {

@FXML private CheckBox useCustomDOI;
@FXML private TextField useCustomDOIName;

public CustomizationTab() {
ViewLoader.view(this)
.root(this)
.load();
}

@Override
public String getTabName() {
return Localization.lang("Customization");
}

public void initialize() {
this.viewModel = new CustomizationTabViewModel(dialogService, preferencesService);

useCustomDOI.selectedProperty().bindBidirectional(viewModel.useCustomDOIProperty());
useCustomDOIName.textProperty().bindBidirectional(viewModel.useCustomDOINameProperty());
useCustomDOIName.disableProperty().bind(useCustomDOI.selectedProperty().not());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.jabref.gui.preferences.customization;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

import org.jabref.gui.DialogService;
import org.jabref.gui.preferences.PreferenceTabViewModel;
import org.jabref.logic.preferences.DOIPreferences;
import org.jabref.preferences.PreferencesService;

public class CustomizationTabViewModel implements PreferenceTabViewModel {

private final BooleanProperty useCustomDOIProperty = new SimpleBooleanProperty();
private final StringProperty useCustomDOINameProperty = new SimpleStringProperty("");

private final DialogService dialogService;
private final PreferencesService preferencesService;
private final DOIPreferences initialDOIPreferences;

public CustomizationTabViewModel(DialogService dialogService, PreferencesService preferencesService) {
this.dialogService = dialogService;
this.preferencesService = preferencesService;
this.initialDOIPreferences = preferencesService.getDOIPreferences();
}

@Override
public void setValues() {
useCustomDOIProperty.setValue(initialDOIPreferences.isUseCustom());
useCustomDOINameProperty.setValue(initialDOIPreferences.getDefaultBaseURI());
}

@Override
public void storeSettings() {
preferencesService.storeDOIPreferences(new DOIPreferences(
useCustomDOIProperty.getValue(),
useCustomDOINameProperty.getValue().trim()));
}

public BooleanProperty useCustomDOIProperty() {
return this.useCustomDOIProperty;
}

public StringProperty useCustomDOINameProperty() {
return this.useCustomDOINameProperty;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

public class GeneralTab extends AbstractPreferenceTabView<GeneralTabViewModel> implements PreferencesTab {

private final ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
@FXML private ComboBox<Language> language;
@FXML private ComboBox<Charset> defaultEncoding;
@FXML private ComboBox<BibDatabaseMode> biblatexMode;
Expand All @@ -42,8 +43,6 @@ public class GeneralTab extends AbstractPreferenceTabView<GeneralTabViewModel> i
@FXML private CheckBox addCreationDate;
@FXML private CheckBox addModificationDate;

private final ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();

public GeneralTab() {
ViewLoader.view(this)
.root(this)
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/org/jabref/logic/preferences/DOIPreferences.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.jabref.logic.preferences;

public class DOIPreferences {
private final boolean useCustom;
private final String defaultBaseURI;

public DOIPreferences(boolean useCustom, String defaultBaseURI) {
this.useCustom = useCustom;
this.defaultBaseURI = defaultBaseURI;
}

public boolean isUseCustom() {
return useCustom;
}

public String getDefaultBaseURI() {
return defaultBaseURI;
}
}
19 changes: 12 additions & 7 deletions src/main/java/org/jabref/model/entry/identifier/DOI.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,15 @@
import org.slf4j.LoggerFactory;

/**
* Class for working with <a href="https://en.wikipedia.org/wiki/Digital_object_identifier">Digital object identifiers
* (DOIs)</a> and <a href="http://shortdoi.org">Short DOIs</a>
* Class for working with <a href="https://en.wikipedia.org/wiki/Digital_object_identifier">Digital object identifiers (DOIs)</a> and <a href="http://shortdoi.org">Short DOIs</a>
*/
public class DOI implements Identifier {

public static final URI AGENCY_RESOLVER = URI.create("https://doi.org/doiRA");

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

// DOI/Short DOI resolver
private static final URI RESOLVER = URI.create("https://doi.org");
private static final URI RESOLVER = URI.create("https://doi.org/");

// Regex
// (see http://www.doi.org/doi_handbook/2_Numbering.html)
Expand Down Expand Up @@ -147,8 +145,7 @@ public DOI(String doi) {
/**
* Creates an Optional&lt;DOI> from various schemes including URL, URN, and plain DOIs.
* <p>
* Useful for suppressing the <c>IllegalArgumentException</c> of the Constructor and checking for
* Optional.isPresent() instead.
* Useful for suppressing the <c>IllegalArgumentException</c> of the Constructor and checking for Optional.isPresent() instead.
*
* @param doi the DOI/Short DOI string
* @return an Optional containing the DOI or an empty Optional
Expand Down Expand Up @@ -233,8 +230,16 @@ public boolean isShortDoi() {
*/
@Override
public Optional<URI> getExternalURI() {
return getExternalURIFromBase(RESOLVER);
}

public Optional<URI> getExternalURIWithCustomBase(String customBase) {
return getExternalURIFromBase(URI.create(customBase));
}

private Optional<URI> getExternalURIFromBase(URI base) {
try {
URI uri = new URI(RESOLVER.getScheme(), RESOLVER.getHost(), "/" + doi, null);
URI uri = new URI(base.getScheme(), base.getHost(), "/" + doi, null);
return Optional.of(uri);
} catch (URISyntaxException e) {
// should never happen
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/org/jabref/preferences/JabRefPreferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
import org.jabref.logic.net.ProxyPreferences;
import org.jabref.logic.openoffice.OpenOfficePreferences;
import org.jabref.logic.openoffice.StyleLoader;
import org.jabref.logic.preferences.DOIPreferences;
import org.jabref.logic.preferences.OwnerPreferences;
import org.jabref.logic.preferences.TimestampPreferences;
import org.jabref.logic.preview.PreviewLayout;
Expand Down Expand Up @@ -201,6 +202,9 @@ public class JabRefPreferences implements PreferencesService {
public static final String SHOW_ADVANCED_HINTS = "showAdvancedHints";
public static final String DEFAULT_ENCODING = "defaultEncoding";

public static final String BASE_DOI_URI = "baseDOIURI";
public static final String USE_CUSTOM_DOI_URI = "useCustomDOIURI";

public static final String USE_OWNER = "useOwner";
public static final String DEFAULT_OWNER = "defaultOwner";
public static final String OVERWRITE_OWNER = "overwriteOwner";
Expand Down Expand Up @@ -445,6 +449,9 @@ private JabRefPreferences() {
// Set DOI to be the default ID entry generator
defaults.put(ID_ENTRY_GENERATOR, DoiFetcher.NAME);

defaults.put(USE_CUSTOM_DOI_URI, Boolean.FALSE);
defaults.put(BASE_DOI_URI, "https://doi.org");

if (OS.OS_X) {
defaults.put(FONT_FAMILY, "SansSerif");
defaults.put(PUSH_EMACS_PATH, "emacsclient");
Expand Down Expand Up @@ -1361,6 +1368,19 @@ public void storeTelemetryPreferences(TelemetryPreferences preferences) {
putBoolean(ALREADY_ASKED_TO_COLLECT_TELEMETRY, !preferences.shouldAskToCollectTelemetry()); // mind the !
}

@Override
public DOIPreferences getDOIPreferences() {
return new DOIPreferences(
getBoolean(USE_CUSTOM_DOI_URI),
get(BASE_DOI_URI));
}

@Override
public void storeDOIPreferences(DOIPreferences preferences) {
putBoolean(USE_CUSTOM_DOI_URI, preferences.isUseCustom());
put(BASE_DOI_URI, preferences.getDefaultBaseURI());
}

@Override
public OwnerPreferences getOwnerPreferences() {
return new OwnerPreferences(
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/org/jabref/preferences/PreferencesService.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.jabref.logic.layout.format.NameFormatterPreferences;
import org.jabref.logic.net.ProxyPreferences;
import org.jabref.logic.openoffice.OpenOfficePreferences;
import org.jabref.logic.preferences.DOIPreferences;
import org.jabref.logic.preferences.OwnerPreferences;
import org.jabref.logic.preferences.TimestampPreferences;
import org.jabref.logic.protectedterms.ProtectedTermsPreferences;
Expand Down Expand Up @@ -144,6 +145,10 @@ public interface PreferencesService {

void storeTelemetryPreferences(TelemetryPreferences preferences);

DOIPreferences getDOIPreferences();

void storeDOIPreferences(DOIPreferences preferences);

OwnerPreferences getOwnerPreferences();

void storeOwnerPreferences(OwnerPreferences preferences);
Expand Down
Loading