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

Add "Look up DOIs" to Quality menu #2442

Merged
merged 5 commits into from
Mar 18, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- The `Move linked files to default file directory`-Cleanup operation respects the `File directory pattern` setting
- We separated the `Move file` and `Rename Pdfs` logic and context menu entries in the `General`-Tab for the Field `file` to improve the semantics
- A scrollbar was added to the cleanup panel, as a result of issue [#2501](https://github.com/JabRef/jabref/issues/2501)
- Using "Look up DOIs" in the quality menu, it is possible to look up DOIs for multiple entries.
- Using "Look up document identifier" in the quality menu, it is possible to look up DOIs and other identifiers for multiple entries.
- F4 opens selected file in current JTable context not just from selected entry inside the main table [#2355](https://github.com/JabRef/jabref/issues/2355)
- We added an option to copy the title of BibTeX entries to the clipboard through `Edit -> Copy title` (implements [#210](https://github.com/koppor/jabref/issues/210))
- Several scrollbars were added to the preference dialog which show up when content is too large [#2559](https://github.com/JabRef/jabref/issues/2559)
Expand Down
40 changes: 21 additions & 19 deletions src/main/java/org/jabref/gui/BasePanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@
import org.jabref.gui.worker.AbstractWorker;
import org.jabref.gui.worker.CallBack;
import org.jabref.gui.worker.CitationStyleToClipboardWorker;
import org.jabref.gui.worker.LookupDOIsWorker;
import org.jabref.gui.worker.MarkEntriesAction;
import org.jabref.gui.worker.SendAsEMailAction;
import org.jabref.logic.autocompleter.AutoCompletePreferences;
Expand Down Expand Up @@ -676,7 +675,6 @@ public void update() {
actions.put(Actions.REMOVE_FROM_GROUP, new GroupAddRemoveDialog(this, false, false));
actions.put(Actions.MOVE_TO_GROUP, new GroupAddRemoveDialog(this, true, true));

actions.put(Actions.LOOKUP_DOIS, new LookupDOIsWorker(frame));
actions.put(Actions.DOWNLOAD_FULL_TEXT, new FindFullTextAction(this));
}

Expand Down Expand Up @@ -990,23 +988,7 @@ public void runCommand(final String _command) {
if (o instanceof BaseAction) {
((BaseAction) o).action();
} else {
// This part uses Spin's features:
Runnable wrk = ((AbstractWorker) o).getWorker();
// The Worker returned by getWorker() has been wrapped
// by Spin.off(), which makes its methods be run in
// a different thread from the EDT.
CallBack clb = ((AbstractWorker) o).getCallBack();

((AbstractWorker) o).init(); // This method runs in this same thread, the EDT.
// Useful for initial GUI actions, like printing a message.

// The CallBack returned by getCallBack() has been wrapped
// by Spin.over(), which makes its methods be run on
// the EDT.
wrk.run(); // Runs the potentially time-consuming action
// without freezing the GUI. The magic is that THIS line
// of execution will not continue until run() is finished.
clb.update(); // Runs the update() method on the EDT.
runWorker((AbstractWorker) o);
}
} catch (Throwable ex) {
// If the action has blocked the JabRefFrame before crashing, we need to unblock it.
Expand All @@ -1017,6 +999,26 @@ public void runCommand(final String _command) {
}
}

public static void runWorker(AbstractWorker worker) throws Exception {
// This part uses Spin's features:
Runnable wrk = worker.getWorker();
// The Worker returned by getWorker() has been wrapped
// by Spin.off(), which makes its methods be run in
// a different thread from the EDT.
CallBack clb = worker.getCallBack();

worker.init(); // This method runs in this same thread, the EDT.
// Useful for initial GUI actions, like printing a message.

// The CallBack returned by getCallBack() has been wrapped
// by Spin.over(), which makes its methods be run on
// the EDT.
wrk.run(); // Runs the potentially time-consuming action
// without freezing the GUI. The magic is that THIS line
// of execution will not continue until run() is finished.
clb.update(); // Runs the update() method on the EDT.
}

private boolean saveDatabase(File file, boolean selectedOnly, Charset enc,
SavePreferences.DatabaseSaveType saveType) throws SaveException {
SaveSession session;
Expand Down
17 changes: 11 additions & 6 deletions src/main/java/org/jabref/gui/JabRefFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import org.jabref.gui.actions.ConnectToSharedDatabaseAction;
import org.jabref.gui.actions.ErrorConsoleAction;
import org.jabref.gui.actions.IntegrityCheckAction;
import org.jabref.gui.actions.LookupIdentifierAction;
import org.jabref.gui.actions.ManageKeywordsAction;
import org.jabref.gui.actions.MassSetFieldAction;
import org.jabref.gui.actions.MnemonicAwareAction;
Expand Down Expand Up @@ -110,8 +111,10 @@
import org.jabref.logic.autosaveandbackup.AutosaveManager;
import org.jabref.logic.autosaveandbackup.BackupManager;
import org.jabref.logic.help.HelpFile;
import org.jabref.logic.importer.IdFetcher;
import org.jabref.logic.importer.OutputPrinter;
import org.jabref.logic.importer.ParserResult;
import org.jabref.logic.importer.WebFetchers;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.search.SearchQuery;
import org.jabref.logic.undo.AddUndoableActionEvent;
Expand Down Expand Up @@ -405,9 +408,7 @@ public void actionPerformed(ActionEvent e) {
Localization.lang("Send as email"), IconTheme.JabRefIcon.EMAIL.getIcon());
private final MassSetFieldAction massSetField = new MassSetFieldAction(this);
private final ManageKeywordsAction manageKeywords = new ManageKeywordsAction(this);
private final AbstractAction lookupDOIs = new GeneralAction(Actions.LOOKUP_DOIS,
Localization.menuTitle("Look up DOIs"),
Localization.lang("Look up DOIs"));
private final JMenu lookupIdentifiers = JabRefFrame.subMenu(Localization.menuTitle("Look up document identifier..."));
private final GeneralAction findUnlinkedFiles = new GeneralAction(
FindUnlinkedFilesDialog.ACTION_COMMAND,
FindUnlinkedFilesDialog.ACTION_MENU_TITLE, FindUnlinkedFilesDialog.ACTION_SHORT_DESCRIPTION,
Expand Down Expand Up @@ -1176,7 +1177,11 @@ private void fillMenu() {
quality.add(autoSetFile);
quality.add(findUnlinkedFiles);
quality.add(autoLinkFile);
quality.add(lookupDOIs);

for (IdFetcher fetcher : WebFetchers.getIdFetchers()) {
lookupIdentifiers.add(new LookupIdentifierAction(this, fetcher));
}
quality.add(lookupIdentifiers);
quality.add(downloadFullText);
mb.add(quality);

Expand Down Expand Up @@ -1360,7 +1365,7 @@ private void initActions() {
saveAs, saveSelectedAs, saveSelectedAsPlain, editModeAction, undo, redo, cut, deleteEntry, copy, paste, mark, markSpecific, unmark,
unmarkAll, rankSubMenu, editEntry, selectAll, copyKey, copyCiteKey, copyKeyAndTitle, copyKeyAndLink, editPreamble, editStrings,
groupSelector.getToggleAction(), makeKeyAction, normalSearch, generalFetcher.getToggleAction(), mergeEntries, cleanupEntries, exportToClipboard, replaceAll,
sendAsEmail, downloadFullText, lookupDOIs, writeXmpAction, openOfficePanel.getToggleAction(), findUnlinkedFiles, addToGroup, removeFromGroup,
sendAsEmail, downloadFullText, lookupIdentifiers, writeXmpAction, openOfficePanel.getToggleAction(), findUnlinkedFiles, addToGroup, removeFromGroup,
moveToGroup, autoLinkFile, resolveDuplicateKeys, openUrl, openFolder, openFile, togglePreview,
dupliCheck, autoSetFile, newEntryAction, newSpec, customizeAction, plainTextImport, getMassSetField(), getManageKeywords(),
pushExternalButton.getMenuAction(), closeDatabaseAction, getNextPreviewStyleAction(), getPreviousPreviewStyleAction(), checkIntegrity,
Expand Down Expand Up @@ -1393,7 +1398,7 @@ dupliCheck, autoSetFile, newEntryAction, newSpec, customizeAction, plainTextImpo
twoEntriesOnlyActions.addAll(Arrays.asList(mergeEntries));

atLeastOneEntryActions.clear();
atLeastOneEntryActions.addAll(Arrays.asList(downloadFullText, lookupDOIs));
atLeastOneEntryActions.addAll(Arrays.asList(downloadFullText, lookupIdentifiers));

tabbedPane.addChangeListener(event -> updateEnabledState());

Expand Down
1 change: 0 additions & 1 deletion src/main/java/org/jabref/gui/actions/Actions.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public class Actions {
public static final String EXPORT_TO_CLIPBOARD = "exportToClipboard";
public static final String FOCUS_TABLE = "focusTable";
public static final String FORWARD = "forward";
public static final String LOOKUP_DOIS = "lookupDOIs";
public static final String MAKE_KEY = "makeKey";
public static final String MANAGE_SELECTORS = "manageSelectors";
public static final String MARK_ENTRIES = "markEntries";
Expand Down
38 changes: 38 additions & 0 deletions src/main/java/org/jabref/gui/actions/LookupIdentifierAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.jabref.gui.actions;

import java.awt.event.ActionEvent;

import javax.swing.Action;

import org.jabref.gui.BasePanel;
import org.jabref.gui.JabRefFrame;
import org.jabref.gui.worker.LookupIdentifiersWorker;
import org.jabref.logic.importer.IdFetcher;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class LookupIdentifierAction extends MnemonicAwareAction {

private static final Log LOGGER = LogFactory.getLog(LookupIdentifierAction.class);

private final JabRefFrame frame;
private final IdFetcher fetcher;

@Override
public void actionPerformed(ActionEvent actionEvent) {
try {
BasePanel.runWorker(new LookupIdentifiersWorker(frame, fetcher));
} catch (Exception e) {
LOGGER.error(e);
}
}

public LookupIdentifierAction(JabRefFrame frame, IdFetcher fetcher) {
super();
this.frame = frame;
this.fetcher = fetcher;

putValue(Action.NAME, fetcher.getIdentifierName());
}
}
19 changes: 1 addition & 18 deletions src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import org.jabref.gui.JabRefFrame;
import org.jabref.gui.autosaveandbackup.AutosaveUIManager;
import org.jabref.gui.worker.AbstractWorker;
import org.jabref.gui.worker.CallBack;
import org.jabref.logic.autosaveandbackup.AutosaveManager;
import org.jabref.logic.autosaveandbackup.BackupManager;
import org.jabref.logic.exporter.BibtexDatabaseWriter;
Expand Down Expand Up @@ -280,23 +279,7 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset encoding)
* still runs synchronously using Spin (the method returns only after completing the operation).
*/
public void runCommand() throws Exception {
// This part uses Spin's features:
Runnable worker = getWorker();
// The Worker returned by getWorker() has been wrapped
// by Spin.off(), which makes its methods be run in
// a different thread from the EDT.
CallBack callback = getCallBack();

init(); // This method runs in this same thread, the EDT.
// Useful for initial GUI actions, like printing a message.

// The CallBack returned by getCallBack() has been wrapped
// by Spin.over(), which makes its methods be run on
// the EDT.
worker.run(); // Runs the potentially time-consuming action
// without freezing the GUI. The magic is that THIS line
// of execution will not continue until run() is finished.
callback.update(); // Runs the update() method on the EDT.
BasePanel.runWorker(this);
}

public void save() throws Exception {
Expand Down
76 changes: 0 additions & 76 deletions src/main/java/org/jabref/gui/worker/LookupDOIsWorker.java

This file was deleted.

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

import java.util.List;
import java.util.Objects;
import java.util.Optional;

import org.jabref.gui.BasePanel;
import org.jabref.gui.JabRefFrame;
import org.jabref.gui.undo.NamedCompound;
import org.jabref.gui.undo.UndoableFieldChange;
import org.jabref.logic.importer.FetcherException;
import org.jabref.logic.importer.IdFetcher;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.FieldChange;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.identifier.Identifier;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class LookupIdentifiersWorker<T extends Identifier> extends AbstractWorker {

private final JabRefFrame frame;
private final IdFetcher<T> fetcher;
private String message;

private static final Log LOGGER = LogFactory.getLog(LookupIdentifiersWorker.class);

public LookupIdentifiersWorker(JabRefFrame frame, IdFetcher<T> fetcher) {
this.frame = Objects.requireNonNull(frame);
this.fetcher = Objects.requireNonNull(fetcher);
}

@Override
public void run() {
BasePanel basePanel = Objects.requireNonNull(frame.getCurrentBasePanel());
List<BibEntry> bibEntries = basePanel.getSelectedEntries();
if (!bibEntries.isEmpty()) {
String totalCount = Integer.toString(bibEntries.size());
NamedCompound namedCompound = new NamedCompound(Localization.lang("Look up %0", fetcher.getIdentifierName()));
int count = 0;
int foundCount = 0;
for (BibEntry bibEntry : bibEntries) {
count++;
frame.output(Localization.lang("Looking up %0... - entry %1 out of %2 - found %3",
fetcher.getIdentifierName(), Integer.toString(count), totalCount, Integer.toString(foundCount)));
Optional<T> identifier = Optional.empty();
try {
identifier = fetcher.findIdentifier(bibEntry);
} catch (FetcherException e) {
LOGGER.error("Could not fetch " + fetcher.getIdentifierName(), e);
}
if (identifier.isPresent() && !bibEntry.hasField(identifier.get().getDefaultField())) {
Optional<FieldChange> fieldChange = bibEntry.setField(identifier.get().getDefaultField(), identifier.get().getNormalized());
if (fieldChange.isPresent()) {
namedCompound.addEdit(new UndoableFieldChange(fieldChange.get()));
foundCount++;
frame.output(Localization.lang("Looking up %0... - entry %1 out of %2 - found %3",
Integer.toString(count), totalCount, Integer.toString(foundCount)));
}
}
}
namedCompound.end();
if (foundCount > 0) {
basePanel.getUndoManager().addEdit(namedCompound);
basePanel.markBaseChanged();
}
message = Localization.lang("Determined %0 for %1 entries", fetcher.getIdentifierName(), Integer.toString(foundCount));
}
}

@Override
public void update() {
frame.output(message);
}
}
8 changes: 7 additions & 1 deletion src/main/java/org/jabref/logic/importer/IdFetcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import java.util.Optional;

import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.identifier.Identifier;

/**
* Looks for article identifier based on already present bibliographic information.
*/
public interface IdFetcher<T> extends WebFetcher {
public interface IdFetcher<T extends Identifier> extends WebFetcher {

/**
* Looks for an identifier based on the information stored in the given {@link BibEntry}.
Expand All @@ -16,4 +17,9 @@ public interface IdFetcher<T> extends WebFetcher {
* @return the identifier (if an ID was found, otherwise an empty {@link Optional})
*/
Optional<T> findIdentifier(BibEntry entry) throws FetcherException;

/**
* Returns the name of the identifier that is returned by this fetcher.
*/
String getIdentifierName();
}
Loading