diff --git a/CHANGELOG.md b/CHANGELOG.md index cfe8ebc7708..ed83bb94f8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,11 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - The field `issue` is now always exported to the corresponding `issue` field in MS-Office XML. - We fixed an issue with repeated escaping of the %-sign when running the LaTeXCleanup more than once. [#2451](https://github.com/JabRef/jabref/issues/2451) - We fixed the import of MS-Office XML files, when the `month` field contained an invalid value. + - ArXiV fetcher now checks similarity of entry when using DOI retrieval to avoid false positives [#2575](https://github.com/JabRef/jabref/issues/2575) + - Sciencedirect/Elsevier fetcher is now able to scrape new HTML structure [#2576](https://github.com/JabRef/jabref/issues/2576) + - Fixed the synchronization logic of keywords and special fields and vice versa [#2580](https://github.com/JabRef/jabref/issues/2580) + + ### Removed diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index b53fab464e3..a163d9c6db1 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -206,7 +206,7 @@ public BasePanel(JabRefFrame frame, BibDatabaseContext bibDatabaseContext) { this.tableModel = new MainTableDataModel(getBibDatabaseContext()); citationStyleCache = new CitationStyleCache(bibDatabaseContext); - annotationCache = new FileAnnotationCache(); + annotationCache = new FileAnnotationCache(bibDatabaseContext); setupMainPanel(); diff --git a/src/main/java/org/jabref/gui/FileDialog.java b/src/main/java/org/jabref/gui/FileDialog.java index 5b22f554534..c1e3e0d9359 100644 --- a/src/main/java/org/jabref/gui/FileDialog.java +++ b/src/main/java/org/jabref/gui/FileDialog.java @@ -35,7 +35,6 @@ */ @Deprecated public class FileDialog { - private static final Log LOGGER = LogFactory.getLog(FileDialog.class); private final FileChooser fileChooser; diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index 401590ec466..a6fc2a3b5d9 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -26,6 +26,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; import javax.swing.AbstractAction; @@ -128,30 +129,50 @@ public class EntryEditor extends JPanel implements EntryContainer { private static final Log LOGGER = LogFactory.getLog(EntryEditor.class); - /** A reference to the entry this object works on. */ + /** + * A reference to the entry this object works on. + */ private final BibEntry entry; - /** The currently displayed type */ + /** + * The currently displayed type + */ private final String displayedBibEntryType; - /** The action concerned with closing the window. */ + /** + * The action concerned with closing the window. + */ private final CloseAction closeAction = new CloseAction(); - /** The action that deletes the current entry, and closes the editor. */ + /** + * The action that deletes the current entry, and closes the editor. + */ private final DeleteAction deleteAction = new DeleteAction(); - /** The action for switching to the next entry. */ + /** + * The action for switching to the next entry. + */ private final AbstractAction nextEntryAction = new NextEntryAction(); - /** The action for switching to the previous entry. */ + /** + * The action for switching to the previous entry. + */ private final AbstractAction prevEntryAction = new PrevEntryAction(); - /** The action concerned with storing a field value. */ + /** + * The action concerned with storing a field value. + */ private final StoreFieldAction storeFieldAction = new StoreFieldAction(); - /** The action for switching to the next tab */ + /** + * The action for switching to the next tab + */ private final SwitchLeftAction switchLeftAction = new SwitchLeftAction(); - /** The action for switching to the previous tab */ + /** + * The action for switching to the previous tab + */ private final SwitchRightAction switchRightAction = new SwitchRightAction(); - /** The action which generates a BibTeX key for this entry. */ + /** + * The action which generates a BibTeX key for this entry. + */ private final GenerateKeyAction generateKeyAction = new GenerateKeyAction(); // UGLY HACK to have a pointer to the fileListEditor to call autoSetLinks() @@ -160,8 +181,6 @@ public class EntryEditor extends JPanel implements EntryContainer { private final AbstractAction writeXmp; - private final SaveDatabaseAction saveDatabaseAction = new SaveDatabaseAction(); - private final JPanel srcPanel = new JPanel(); private final JPanel relatedArticlePanel = new JPanel(); @@ -184,7 +203,9 @@ public class EntryEditor extends JPanel implements EntryContainer { * source couldn't be parsed, and the user is given the option to edit it. */ private boolean updateSource = true; - /** Indicates that we are about to go to the next or previous entry */ + /** + * Indicates that we are about to go to the next or previous entry + */ private boolean movingToDifferentEntry; private boolean validEntry = true; @@ -194,26 +215,29 @@ public class EntryEditor extends JPanel implements EntryContainer { private boolean lastFieldAccepted = true; /** - * This indicates whether the last attempt at parsing the source was successful. It is used to determine whether - * the dialog should close; it should stay open if the user received an error message about the source, - * whatever he or she chose to do about it. + * This indicates whether the last attempt at parsing the source was successful. It is used to determine whether + * the dialog should close; it should stay open if the user received an error message about the source, + * whatever he or she chose to do about it. */ private boolean lastSourceAccepted = true; - /** This is used to prevent double updates after editing source. */ + /** + * This is used to prevent double updates after editing source. + */ private String lastSourceStringAccepted; - /** The index the source panel has in tabbed. */ + /** + * The index the source panel has in tabbed. + */ private int sourceIndex = -1; private final HelpAction helpAction = new HelpAction(HelpFile.ENTRY_EDITOR, IconTheme.JabRefIcon.HELP.getIcon()); - private final UndoAction undoAction = new UndoAction(); - private final RedoAction redoAction = new RedoAction(); + private Action saveDatabaseAction; - private final TabListener tabListener = new TabListener(); + private final TabListener tabListener = new TabListener(); private final List searchListeners = new ArrayList<>(); public EntryEditor(JabRefFrame frame, BasePanel panel, BibEntry entry) { @@ -331,7 +355,7 @@ private void setupFieldPanels() { addSpecialTabs(); // pdf annotations tab - addPdfTab(); + addPDFAnnotationTab(); //related articles if (Globals.prefs.getBoolean(JabRefPreferences.SHOW_RECOMMENDATIONS)) { @@ -439,27 +463,24 @@ private void addOptionalTab(EntryType type) { fileListEditor = optionalPanel.fileListEditor; } tabbed.addTab(Localization.lang("Optional fields"), IconTheme.JabRefIcon.OPTIONAL.getSmallIcon(), - optionalPanel - .getPane(), - Localization.lang("Show optional fields")); + optionalPanel.getPane(), Localization.lang("Show optional fields")); tabs.add(optionalPanel); } /** * Add a tab for displaying comments from a PDF */ - private void addPdfTab() { + private void addPDFAnnotationTab() { tabbed.remove(fileAnnotationTab); tabs.remove(fileAnnotationTab); Optional field = entry.getField(FieldName.FILE); if (field.isPresent()) { - fileAnnotationTab = new FileAnnotationTab(this, panel, tabbed); - tabbed.addTab(Localization.lang("File annotations"), IconTheme.JabRefIcon.COMMENT.getSmallIcon(), - fileAnnotationTab, + fileAnnotationTab = new FileAnnotationTab(this); + tabbed.addTab(Localization.lang("File annotations"), IconTheme.JabRefIcon.OPTIONAL.getSmallIcon(), fileAnnotationTab, + Localization.lang("Show file annotations")); tabs.add(fileAnnotationTab); } - } public String getDisplayedBibEntryType() { @@ -495,21 +516,21 @@ private void setupToolBar() { inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.CLOSE_ENTRY_EDITOR), "close"); actionMap.put("close", closeAction); inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.ENTRY_EDITOR_STORE_FIELD), "store"); - actionMap.put("store", getStoreFieldAction()); + actionMap.put("store", storeFieldAction); inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.AUTOGENERATE_BIBTEX_KEYS), "generateKey"); - actionMap.put("generateKey", getGenerateKeyAction()); + actionMap.put("generateKey", generateKeyAction); inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.AUTOMATICALLY_LINK_FILES), "autoLink"); actionMap.put("autoLink", autoLinkAction); inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.ENTRY_EDITOR_PREVIOUS_ENTRY), "prev"); - actionMap.put("prev", getPrevEntryAction()); + actionMap.put("prev", prevEntryAction); inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.ENTRY_EDITOR_NEXT_ENTRY), "next"); - actionMap.put("next", getNextEntryAction()); + actionMap.put("next", nextEntryAction); inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.UNDO), "undo"); actionMap.put("undo", undoAction); inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.REDO), "redo"); actionMap.put("redo", redoAction); inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.HELP), "help"); - actionMap.put("help", getHelpAction()); + actionMap.put("help", helpAction); toolBar.setFloatable(false); @@ -526,12 +547,13 @@ private void setupToolBar() { TypeButton typeButton = new TypeButton(); toolBar.add(typeButton); - toolBar.add(getGenerateKeyAction()); + toolBar.add(generateKeyAction); toolBar.add(autoLinkAction); toolBar.add(writeXmp); JPopupMenu fetcherPopup = new JPopupMenu(); + for (EntryBasedFetcher fetcher : EntryFetchers .getEntryBasedFetchers(Globals.prefs.getImportFormatPreferences())) { fetcherPopup.add(new JMenuItem(new AbstractAction(fetcher.getName()) { @@ -556,12 +578,12 @@ public void mousePressed(MouseEvent e) { toolBar.addSeparator(); toolBar.add(deleteAction); - toolBar.add(getPrevEntryAction()); - toolBar.add(getNextEntryAction()); + toolBar.add(prevEntryAction); + toolBar.add(nextEntryAction); toolBar.addSeparator(); - toolBar.add(getHelpAction()); + toolBar.add(helpAction); Component[] comps = toolBar.getComponents(); @@ -614,11 +636,10 @@ public Optional getExtra(final FieldEditor editor) { // Add controls for switching between abbreviated and full journal names. // If this field also has a FieldContentSelector, we need to combine these. return FieldExtraComponents.getJournalExtraComponent(frame, panel, editor, entry, contentSelectors, - getStoreFieldAction()); + storeFieldAction); } else if (!panel.getBibDatabaseContext().getMetaData().getContentSelectorValuesForField(fieldName).isEmpty()) { return FieldExtraComponents.getSelectorExtraComponent(frame, panel, editor, contentSelectors, - getStoreFieldAction()); - + storeFieldAction); } else if (fieldExtras.contains(FieldProperty.DOI)) { return FieldExtraComponents.getDoiExtraComponent(panel, this, editor); } else if (fieldExtras.contains(FieldProperty.EPRINT)) { @@ -626,7 +647,7 @@ public Optional getExtra(final FieldEditor editor) { } else if (fieldExtras.contains(FieldProperty.ISBN)) { return FieldExtraComponents.getIsbnExtraComponent(panel, this, editor); } else if (fieldExtras.contains(FieldProperty.OWNER)) { - return FieldExtraComponents.getSetOwnerExtraComponent(editor, getStoreFieldAction()); + return FieldExtraComponents.getSetOwnerExtraComponent(editor, storeFieldAction); } else if (fieldExtras.contains(FieldProperty.YES_NO)) { return FieldExtraComponents.getYesNoExtraComponent(editor, this); } else if (fieldExtras.contains(FieldProperty.MONTH)) { @@ -692,7 +713,6 @@ public void updateSource() { source.setEditable(false); LOGGER.debug("Incorrect entry", ex); } - } } @@ -716,18 +736,18 @@ private void setupJTextComponent(JTextComponent textComponent) { ActionMap actionMap = textComponent.getActionMap(); inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.ENTRY_EDITOR_STORE_FIELD), "store"); - actionMap.put("store", getStoreFieldAction()); + actionMap.put("store", storeFieldAction); inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.ENTRY_EDITOR_NEXT_PANEL), "right"); inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.ENTRY_EDITOR_NEXT_PANEL_2), "right"); - actionMap.put("right", getSwitchRightAction()); + actionMap.put("right", switchRightAction); inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.ENTRY_EDITOR_PREVIOUS_PANEL), "left"); inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.ENTRY_EDITOR_PREVIOUS_PANEL_2), "left"); - actionMap.put("left", getSwitchLeftAction()); + actionMap.put("left", switchLeftAction); inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.HELP), "help"); - actionMap.put("help", getHelpAction()); + actionMap.put("help", helpAction); inputMap.put(Globals.getKeyPrefs().getKey(KeyBinding.NEXT_TAB), "nexttab"); actionMap.put("nexttab", frame.nextTab); @@ -783,7 +803,6 @@ public void setEnabled(boolean enabled) { } } source.setEnabled(enabled); - } /** @@ -795,7 +814,7 @@ public void storeCurrentEdit() { if (comp instanceof FieldEditor) { ((FieldEditor) comp).clearAutoCompleteSuggestion(); } - getStoreFieldAction().actionPerformed(new ActionEvent(comp, 0, "")); + storeFieldAction.actionPerformed(new ActionEvent(comp, 0, "")); } } @@ -975,7 +994,6 @@ public void updateAllContentSelectors() { for (FieldContentSelector contentSelector : contentSelectors) { contentSelector.rebuildComboBox(); } - } } @@ -994,7 +1012,7 @@ public void listen(FieldChangedEvent fieldChangedEvent) { } public void updateField(final Object sourceObject) { - getStoreFieldAction().actionPerformed(new ActionEvent(sourceObject, 0, "")); + storeFieldAction.actionPerformed(new ActionEvent(sourceObject, 0, "")); } public void setMovingToDifferentEntry() { @@ -1007,9 +1025,40 @@ private void unregisterListeners() { removeSearchListeners(); } - private class TypeButton extends JButton { + public GenerateKeyAction getGenerateKeyAction() { + return generateKeyAction; + } + + public AbstractAction getPrevEntryAction() { + return prevEntryAction; + } + + public AbstractAction getNextEntryAction() { + return nextEntryAction; + } + + public StoreFieldAction getStoreFieldAction() { + return storeFieldAction; + } + + public SwitchLeftAction getSwitchLeftAction() { + return switchLeftAction; + } + + public SwitchRightAction getSwitchRightAction() { + return switchRightAction; + } - public TypeButton() { + public HelpAction getHelpAction() { + return helpAction; + } + + public Action getSaveDatabaseAction() { + return saveDatabaseAction; + } + + private class TypeButton extends JButton { + private TypeButton() { super(IconTheme.JabRefIcon.EDIT.getIcon()); setToolTipText(Localization.lang("Change entry type")); addActionListener(e -> showChangeEntryTypePopupMenu()); @@ -1022,8 +1071,7 @@ private void showChangeEntryTypePopupMenu() { } private class TypeLabel extends JLabel { - - public TypeLabel(String type) { + private TypeLabel(String type) { super(type); setUI(new VerticalLabelUI(false)); setForeground(GUIGlobals.ENTRY_EDITOR_LABEL_COLOR); @@ -1084,9 +1132,14 @@ public void stateChanged(ChangeEvent event) { Object activeTab = tabs.get(tabbed.getSelectedIndex()); if ((activeTab instanceof FileAnnotationTab) && !((FileAnnotationTab) activeTab).isInitialized()) { //Initialize by getting notes from cache if they are cached - FileAnnotationTab.initializeTab((FileAnnotationTab) activeTab, - panel.getAnnotationCache().getFromCache(Optional.of(entry))); - panel.getAnnotationCache().addToCache(entry, ((FileAnnotationTab) activeTab).getAllNotes()); + + FileAnnotationTab tab = (FileAnnotationTab) activeTab; + try { + tab.initializeTab(tab, + panel.getAnnotationCache().getFromCache(entry)); + } catch (ExecutionException e) { + tab.initializeTab((FileAnnotationTab) activeTab); + } } if (activeTab instanceof EntryEditorTab) { @@ -1102,9 +1155,9 @@ public void stateChanged(ChangeEvent event) { } } - class DeleteAction extends AbstractAction { - public DeleteAction() { + private class DeleteAction extends AbstractAction { + private DeleteAction() { super(Localization.lang("Delete"), IconTheme.JabRefIcon.DELETE_ENTRY.getIcon()); putValue(Action.SHORT_DESCRIPTION, Localization.lang("Delete entry")); } @@ -1145,9 +1198,10 @@ public void close() { } } - class CloseAction extends AbstractAction { - public CloseAction() { + private class CloseAction extends AbstractAction { + + private CloseAction() { super(Localization.lang("Close window"), IconTheme.JabRefIcon.CLOSE.getSmallIcon()); putValue(Action.SHORT_DESCRIPTION, Localization.lang("Close window")); } @@ -1158,7 +1212,7 @@ public void actionPerformed(ActionEvent e) { } } - class StoreFieldAction extends AbstractAction { + public class StoreFieldAction extends AbstractAction { public StoreFieldAction() { super("Store field value"); @@ -1292,7 +1346,6 @@ public void actionPerformed(ActionEvent event) { ce.end(); panel.getUndoManager().addEdit(ce); - } else { panel.getUndoManager().addEdit(undoableFieldChange); } @@ -1324,9 +1377,10 @@ public void actionPerformed(ActionEvent event) { } } - class SwitchLeftAction extends AbstractAction { - public SwitchLeftAction() { + private class SwitchLeftAction extends AbstractAction { + + private SwitchLeftAction() { super("Switch to the panel to the left"); } @@ -1339,9 +1393,10 @@ public void actionPerformed(ActionEvent e) { } } - class SwitchRightAction extends AbstractAction { - public SwitchRightAction() { + private class SwitchRightAction extends AbstractAction { + + private SwitchRightAction() { super("Switch to the panel to the right"); } @@ -1350,13 +1405,13 @@ public void actionPerformed(ActionEvent e) { int i = tabbed.getSelectedIndex(); tabbed.setSelectedIndex(i < (tabbed.getTabCount() - 1) ? i + 1 : 0); activateVisible(); - } } - class NextEntryAction extends AbstractAction { - public NextEntryAction() { + private class NextEntryAction extends AbstractAction { + + private NextEntryAction() { super(Localization.lang("Next entry"), IconTheme.JabRefIcon.DOWN.getIcon()); putValue(Action.SHORT_DESCRIPTION, Localization.lang("Next entry")); @@ -1368,9 +1423,10 @@ public void actionPerformed(ActionEvent e) { } } - class PrevEntryAction extends AbstractAction { - public PrevEntryAction() { + private class PrevEntryAction extends AbstractAction { + + private PrevEntryAction() { super(Localization.lang("Previous entry"), IconTheme.JabRefIcon.UP.getIcon()); putValue(Action.SHORT_DESCRIPTION, Localization.lang("Previous entry")); @@ -1382,13 +1438,12 @@ public void actionPerformed(ActionEvent e) { } } - class GenerateKeyAction extends AbstractAction { + private class GenerateKeyAction extends AbstractAction { - public GenerateKeyAction() { + private GenerateKeyAction() { super(Localization.lang("Generate BibTeX key"), IconTheme.JabRefIcon.MAKE_KEY.getIcon()); putValue(Action.SHORT_DESCRIPTION, Localization.lang("Generate BibTeX key")); - } @Override @@ -1443,9 +1498,9 @@ public void actionPerformed(ActionEvent e) { } } - class UndoAction extends AbstractAction { - public UndoAction() { + private class UndoAction extends AbstractAction { + private UndoAction() { super("Undo", IconTheme.JabRefIcon.UNDO.getIcon()); putValue(Action.SHORT_DESCRIPTION, "Undo"); } @@ -1456,9 +1511,9 @@ public void actionPerformed(ActionEvent e) { } } - class RedoAction extends AbstractAction { + private class RedoAction extends AbstractAction { - public RedoAction() { + private RedoAction() { super("Redo", IconTheme.JabRefIcon.REDO.getIcon()); putValue(Action.SHORT_DESCRIPTION, "Redo"); } @@ -1469,9 +1524,10 @@ public void actionPerformed(ActionEvent e) { } } - class SaveDatabaseAction extends AbstractAction { - public SaveDatabaseAction() { + private class SaveDatabaseAction extends AbstractAction { + + private SaveDatabaseAction() { super("Save library"); } @@ -1505,41 +1561,10 @@ private void warnEmptyBibtexkey() { + Localization.lang("Grouping may not work for this entry.")); } - public AbstractAction getNextEntryAction() { - return nextEntryAction; - } - - public AbstractAction getPrevEntryAction() { - return prevEntryAction; - } - - public SwitchLeftAction getSwitchLeftAction() { - return switchLeftAction; - } - - public SwitchRightAction getSwitchRightAction() { - return switchRightAction; - } - - public SaveDatabaseAction getSaveDatabaseAction() { - return saveDatabaseAction; - } - - public HelpAction getHelpAction() { - return helpAction; - } - - public GenerateKeyAction getGenerateKeyAction() { - return generateKeyAction; - } - - public StoreFieldAction getStoreFieldAction() { - return storeFieldAction; - } private class AutoLinkAction extends AbstractAction { - public AutoLinkAction() { + private AutoLinkAction() { putValue(Action.SMALL_ICON, IconTheme.JabRefIcon.AUTO_FILE_LINK.getIcon()); putValue(Action.SHORT_DESCRIPTION, Localization.lang("Automatically set file links for this entry") + " (Alt-F)"); @@ -1570,5 +1595,4 @@ private Optional doUpdateTimeStamp() { String timestamp = DateTimeFormatter.ofPattern(timeStampFormat).format(LocalDateTime.now()); return UpdateField.updateField(entry, timeStampField, timestamp); } - } diff --git a/src/main/java/org/jabref/gui/entryeditor/FileAnnotationTab.java b/src/main/java/org/jabref/gui/entryeditor/FileAnnotationTab.java index 46d51b228a6..b0ba6a6b9a7 100644 --- a/src/main/java/org/jabref/gui/entryeditor/FileAnnotationTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/FileAnnotationTab.java @@ -3,15 +3,11 @@ import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; -import java.io.IOException; import java.util.Arrays; import java.util.Comparator; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.StringJoiner; -import java.util.stream.Collectors; import javax.swing.BoxLayout; import javax.swing.DefaultListCellRenderer; @@ -22,30 +18,27 @@ import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; -import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; -import org.jabref.gui.BasePanel; import org.jabref.gui.ClipBoardManager; import org.jabref.gui.GUIGlobals; import org.jabref.gui.IconTheme; import org.jabref.logic.l10n.Localization; -import org.jabref.logic.pdf.PdfAnnotationImporterImpl; +import org.jabref.logic.pdf.EntryAnnotationImporter; import org.jabref.model.entry.FieldName; -import org.jabref.model.entry.FileField; -import org.jabref.model.entry.ParsedFileField; import org.jabref.model.pdf.FileAnnotation; import com.jgoodies.forms.builder.FormBuilder; import com.jgoodies.forms.factories.Paddings; import org.apache.pdfbox.pdmodel.fdf.FDFAnnotationHighlight; -public class FileAnnotationTab extends JPanel { - private final JList commentList = new JList<>(); - private final JScrollPane commentScrollPane = new JScrollPane(); +class FileAnnotationTab extends JPanel { + + private final JList annotationList = new JList<>(); + private final JScrollPane annotationScrollPane = new JScrollPane(); private final JLabel fileNameLabel = new JLabel(Localization.lang("Filename"),JLabel.CENTER); private final JComboBox fileNameComboBox = new JComboBox<>(); private final JScrollPane fileNameScrollPane = new JScrollPane(); @@ -58,104 +51,93 @@ public class FileAnnotationTab extends JPanel { private final JLabel pageLabel = new JLabel(Localization.lang("Page"), JLabel.CENTER); private final JTextArea pageArea = new JTextArea("page"); private final JScrollPane pageScrollPane = new JScrollPane(); - private final JLabel commentTxtLabel = new JLabel(Localization.lang("Content"),JLabel.CENTER); + private final JLabel annotationTextLabel = new JLabel(Localization.lang("Content"), JLabel.CENTER); private final JTextArea contentTxtArea = new JTextArea(); private final JLabel highlightTxtLabel = new JLabel(Localization.lang("Highlight"), JLabel.CENTER); private final JTextArea highlightTxtArea = new JTextArea(); - private final JScrollPane commentTxtScrollPane = new JScrollPane(); + private final JScrollPane annotationTextScrollPane = new JScrollPane(); private final JScrollPane highlightScrollPane = new JScrollPane(); private final JButton copyToClipboardButton = new JButton(); private final JButton reloadAnnotationsButton = new JButton(); - DefaultListModel listModel; + private DefaultListModel listModel; private final EntryEditor parent; - private final BasePanel basePanel; - private final JTabbedPane tabbed; - private int commentListSelectedIndex = 0; + private Map> annotationsOfFiles; private boolean isInitialized; - private Map> allNotes = new HashMap<>(); - - public FileAnnotationTab(EntryEditor parent, BasePanel basePanel, JTabbedPane tabbed) { + FileAnnotationTab(EntryEditor parent) { this.parent = parent; - this.basePanel = basePanel; - this.tabbed = tabbed; setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); listModel = new DefaultListModel<>(); this.isInitialized = false; } - public static FileAnnotationTab initializeTab(FileAnnotationTab tab, Optional>> notes){ + public FileAnnotationTab initializeTab(FileAnnotationTab tab) { + if (tab.isInitialized) { + return tab; + } - if(!tab.isInitialized) { + tab.setUpGui(); + tab.isInitialized = true; + tab.parent.repaint(); + return tab; + } - try { - tab.addComments(notes); - } catch (IOException e) { - e.printStackTrace(); - } - tab.setUpGui(); + public FileAnnotationTab initializeTab(FileAnnotationTab tab, Map> cachedFileAnnotations) { + this.annotationsOfFiles = cachedFileAnnotations; - tab.isInitialized = true; - tab.parent.repaint(); + if (tab.isInitialized) { return tab; } + + tab.addAnnotations(); + tab.setUpGui(); + tab.isInitialized = true; + tab.parent.repaint(); return tab; + } /** - * Adds pdf comments from all attached pdf files belonging to the entry selected in the main table and - * shows those from the first file in the comments tab - * @throws IOException + * Adds pdf annotations from all attached pdf files belonging to the entry selected in the main table and + * shows those from the first file in the file annotations tab */ - public void addComments(Optional>> notes) throws IOException { - Optional field = parent.getEntry().getField(FieldName.FILE); - if (field.isPresent()) { - if (!commentList.getModel().equals(listModel)) { - commentList.setModel(listModel); - commentList.addListSelectionListener(new CommentListSelectionListener()); - commentList.setCellRenderer(new CommentsListCellRenderer()); + private void addAnnotations() { + if (parent.getEntry().getField(FieldName.FILE).isPresent()) { + if (!annotationList.getModel().equals(listModel)) { + annotationList.setModel(listModel); + annotationList.addListSelectionListener(new AnnotationListSelectionListener()); + annotationList.setCellRenderer(new AnnotationListCellRenderer()); } - PdfAnnotationImporterImpl annotationImporter; - - if(notes.isPresent()) { - allNotes = notes.get(); - } else { - annotationImporter = new PdfAnnotationImporterImpl(); - //import notes if the selected file is a pdf - getFilteredFileList().forEach(parsedFileField -> allNotes.put( - parsedFileField.getLink(), - annotationImporter.importAnnotations(parsedFileField.getLink(), basePanel.getDatabaseContext()))); - } //set up the comboBox for representing the selected file fileNameComboBox.removeAllItems(); - getFilteredFileList() - .forEach(((parsedField) -> fileNameComboBox.addItem(parsedField.getLink()))); - //show the annotations attached to the selected file - updateShownAnnotations(allNotes.get(fileNameComboBox.getSelectedItem() == null ? - fileNameComboBox.getItemAt(0).toString() : fileNameComboBox.getSelectedItem().toString())); + new EntryAnnotationImporter(parent.getEntry()).getFilteredFileList(). + forEach(((parsedField) -> fileNameComboBox.addItem(parsedField.getLink()))); + //show the annotationsOfFiles attached to the selected file + updateShownAnnotations(annotationsOfFiles.get(fileNameComboBox.getSelectedItem() == null ? + fileNameComboBox.getItemAt(0) : fileNameComboBox.getSelectedItem().toString())); //select the first annotation - if(commentList.isSelectionEmpty()){ - commentList.setSelectedIndex(0); + if (annotationList.isSelectionEmpty()) { + annotationList.setSelectedIndex(0); } } } /** * Updates the list model to show the given notes without those with no content - * @param importedNotes value is the comments name and the value is a pdfComment object to add to the list model + * @param annotations value is the annotation name and the value is a pdfAnnotation object to add to the list model */ - private void updateShownAnnotations(List importedNotes){ + private void updateShownAnnotations(List annotations) { listModel.clear(); - if(importedNotes.isEmpty()){ + if (annotations.isEmpty()) { listModel.addElement(new FileAnnotation("", "", "", 0, Localization.lang("File has no attached annotations"), "")); } else { - Comparator byPage = (annotation1, annotation2) -> Integer.compare(annotation1.getPage(), annotation2.getPage()); - importedNotes.stream() + Comparator byPage = Comparator.comparingInt(FileAnnotation::getPage); + annotations.stream() .filter(annotation -> !(null == annotation.getContent())) .filter(annotation -> annotation.getAnnotationType().equals(FDFAnnotationHighlight.SUBTYPE) || (null == annotation.getLinkedFileAnnotation())) @@ -165,15 +147,14 @@ private void updateShownAnnotations(List importedNotes){ } /** - * Updates the text fields showing meta data and the content from the selected comment - * @param comment pdf comment which data should be shown in the text fields + * Updates the text fields showing meta data and the content from the selected annotation + * @param annotation pdf annotation which data should be shown in the text fields */ - private void updateTextFields(FileAnnotation comment) { - authorArea.setText(comment.getAuthor()); - dateArea.setText(comment.getDate()); - pageArea.setText(String.valueOf(comment.getPage())); - updateContentAndHighlightTextfields(comment); - + private void updateTextFields(FileAnnotation annotation) { + authorArea.setText(annotation.getAuthor()); + dateArea.setText(annotation.getDate()); + pageArea.setText(String.valueOf(annotation.getPage())); + updateContentAndHighlightTextfields(annotation); } /** @@ -187,22 +168,22 @@ private void updateFileNameComboBox() { indexSelectedByComboBox = fileNameComboBox.getSelectedIndex(); } fileNameComboBox.removeAllItems(); - getFilteredFileList().stream().filter(parsedFileField -> parsedFileField.getLink().toLowerCase().endsWith(".pdf") ) + new EntryAnnotationImporter(parent.getEntry()).getFilteredFileList().stream().filter(parsedFileField -> parsedFileField.getLink().toLowerCase().endsWith(".pdf")) .forEach(((parsedField) -> fileNameComboBox.addItem(parsedField.getLink()))); fileNameComboBox.setSelectedIndex(indexSelectedByComboBox); - updateShownAnnotations(allNotes.get(fileNameComboBox.getSelectedItem().toString())); + updateShownAnnotations(annotationsOfFiles.get(fileNameComboBox.getSelectedItem().toString())); } private void setUpGui() { - JPanel commentListPanel = FormBuilder.create() + JPanel annotationPanel = FormBuilder.create() .columns("pref, $lcgap, pref:grow") .rows("pref, $lg, fill:pref:grow, $lg, pref") .padding(Paddings.DIALOG) .add(fileNameLabel).xy(1,1, "left, top") .add(fileNameScrollPane).xyw(2, 1, 2) - .add(commentScrollPane).xyw(1, 3, 3) + .add(annotationScrollPane).xyw(1, 3, 3) .build(); - commentScrollPane.setViewportView(commentList); + annotationScrollPane.setViewportView(annotationList); JPanel informationPanel = FormBuilder.create() .columns("pref, $lcgap, pref:grow") @@ -214,8 +195,8 @@ private void setUpGui() { .add(dateScrollPane).xy(3,5) .add(pageLabel).xy(1,7, "left, top") .add(pageScrollPane).xy(3,7) - .add(commentTxtLabel).xy(1,9, "left, top") - .add(commentTxtScrollPane).xywh(3,9, 1, 2) + .add(annotationTextLabel).xy(1, 9, "left, top") + .add(annotationTextScrollPane).xywh(3, 9, 1, 2) .add(highlightTxtLabel).xy(1, 11, "left, top") .add(highlightScrollPane).xywh(3, 11, 1, 2) .add(this.setUpButtons()).xyw(1, 13, 3) @@ -226,7 +207,7 @@ private void setUpGui() { authorLabel.setForeground(GUIGlobals.ENTRY_EDITOR_LABEL_COLOR); dateLabel.setForeground(GUIGlobals.ENTRY_EDITOR_LABEL_COLOR); pageLabel.setForeground(GUIGlobals.ENTRY_EDITOR_LABEL_COLOR); - commentTxtLabel.setForeground(GUIGlobals.ENTRY_EDITOR_LABEL_COLOR); + annotationTextLabel.setForeground(GUIGlobals.ENTRY_EDITOR_LABEL_COLOR); highlightTxtLabel.setForeground(GUIGlobals.ENTRY_EDITOR_LABEL_COLOR); fileNameScrollPane.setBorder(null); authorScrollPane.setViewportView(authorArea); @@ -235,7 +216,7 @@ private void setUpGui() { dateScrollPane.setBorder(null); pageScrollPane.setViewportView(pageArea); pageScrollPane.setBorder(null); - commentTxtScrollPane.setViewportView(contentTxtArea); + annotationTextScrollPane.setViewportView(contentTxtArea); highlightScrollPane.setViewportView(highlightTxtArea); authorArea.setEditable(false); dateArea.setEditable(false); @@ -250,7 +231,7 @@ private void setUpGui() { this.add(FormBuilder.create() .columns("0:grow, $lcgap, 0:grow") .rows("fill:pref:grow") - .add(commentListPanel).xy(1, 1) + .add(annotationPanel).xy(1, 1) .add(informationPanel).xy(3, 1) .build()); } @@ -293,99 +274,90 @@ private void copyToClipboard(){ private void reloadAnnotations() { isInitialized = false; - Arrays.stream(this.getComponents()).forEach(component -> this.remove(component)); - initializeTab(this, Optional.empty()); + Arrays.stream(this.getComponents()).forEach(this::remove); + initializeTab(this); this.repaint(); } + /** - * Fills the highlight and comment texts and enables/disables the highlight area if there is no highlighted text + * Fills the highlight and annotation texts and enables/disables the highlight area if there is no highlighted text * - * @param comment either a text comment or a highlighting from a pdf + * @param annotation either a text annotation or a highlighting from a pdf */ - private void updateContentAndHighlightTextfields(final FileAnnotation comment){ + private void updateContentAndHighlightTextfields(final FileAnnotation annotation) { - if(comment.hasLinkedComment()){ - String textComment = ""; - String highlightedText = ""; + if (annotation.hasLinkedAnnotation()) { + String annotationText; + String highlightedText; - if(comment.getAnnotationType().equals(FDFAnnotationHighlight.SUBTYPE)){ - highlightedText = comment.getContent(); - textComment = comment.getLinkedFileAnnotation().getContent(); + if (annotation.getAnnotationType().equals(FDFAnnotationHighlight.SUBTYPE)) { + highlightedText = annotation.getContent(); + annotationText = annotation.getLinkedFileAnnotation().getContent(); } else { - highlightedText = comment.getLinkedFileAnnotation().getContent(); - textComment = comment.getContent(); + highlightedText = annotation.getLinkedFileAnnotation().getContent(); + annotationText = annotation.getContent(); } highlightTxtArea.setEnabled(true); - contentTxtArea.setText(textComment); + contentTxtArea.setText(annotationText); highlightTxtArea.setText(highlightedText); } else { - contentTxtArea.setText(comment.getContent()); + contentTxtArea.setText(annotation.getContent()); highlightTxtArea.setText("N/A"); highlightTxtArea.setEnabled(false); } } - /** - * Filter files with a web address containing "www." - * @return a list of file parsed files - */ - private List getFilteredFileList(){ - return FileField.parse(parent.getEntry().getField(FieldName.FILE).get()).stream() - .filter(parsedFileField -> parsedFileField.getLink().toLowerCase().endsWith(".pdf")) - .filter(parsedFileField -> !parsedFileField.getLink().contains("www.")).collect(Collectors.toList()); - } - private class CommentListSelectionListener implements ListSelectionListener { + private class AnnotationListSelectionListener implements ListSelectionListener { @Override public void valueChanged(ListSelectionEvent e) { int index; - if (commentList.getSelectedIndex() >= 0) { - index = commentList.getSelectedIndex(); + int annotationListSelectedIndex = 0; + if (annotationList.getSelectedIndex() >= 0) { + index = annotationList.getSelectedIndex(); updateTextFields(listModel.get(index)); - commentListSelectedIndex = index; - } else { - commentListSelectedIndex = 0; + annotationListSelectedIndex = index; } - commentList.setSelectedIndex(commentListSelectedIndex); + annotationList.setSelectedIndex(annotationListSelectedIndex); //repaint the list to refresh the linked annotation highlighting - commentList.repaint(); + annotationList.repaint(); } } /** * Cell renderer that shows different icons dependent on the annotation subtype */ - class CommentsListCellRenderer extends DefaultListCellRenderer { + class AnnotationListCellRenderer extends DefaultListCellRenderer { JLabel label; - CommentsListCellRenderer() { + AnnotationListCellRenderer() { this.label = new JLabel(); } @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - FileAnnotation comment = (FileAnnotation) value; + FileAnnotation annotation = (FileAnnotation) value; //call the super method so that the cell selection is done as usual label = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - //If more different comment types should be reflected by icons in the list, add them here - switch(comment.getAnnotationType()){ + //If more different annotation types should be reflected by icons in the list, add them here + switch (annotation.getAnnotationType()) { case FDFAnnotationHighlight.SUBTYPE: label.setIcon(IconTheme.JabRefIcon.MARKER.getSmallIcon()); break; default: - label.setIcon(IconTheme.JabRefIcon.COMMENT.getSmallIcon()); + label.setIcon(IconTheme.JabRefIcon.OPTIONAL.getSmallIcon()); break; } - label.setToolTipText(comment.getAnnotationType()); - label.setText(comment.toString()); + label.setToolTipText(annotation.getAnnotationType()); + label.setText(annotation.toString()); return label; } @@ -394,8 +366,4 @@ public Component getListCellRendererComponent(JList list, Object value, int i public boolean isInitialized() { return isInitialized; } - - public Map> getAllNotes() { - return allNotes; - } } diff --git a/src/main/java/org/jabref/gui/specialfields/SpecialFieldDatabaseChangeListener.java b/src/main/java/org/jabref/gui/specialfields/SpecialFieldDatabaseChangeListener.java index 0c49f90a3d4..1ede5e8007e 100644 --- a/src/main/java/org/jabref/gui/specialfields/SpecialFieldDatabaseChangeListener.java +++ b/src/main/java/org/jabref/gui/specialfields/SpecialFieldDatabaseChangeListener.java @@ -26,19 +26,19 @@ public static SpecialFieldDatabaseChangeListener getInstance() { @Subscribe public void listen(EntryAddedEvent event) { - if (Globals.prefs.isKeywordSyncEnabled()) { - final BibEntry entry = event.getBibEntry(); - // NamedCompount code similar to SpecialFieldUpdateListener - NamedCompound nc = new NamedCompound(Localization.lang("Synchronized special fields based on keywords")); - List changes = SpecialFieldsUtils.syncSpecialFieldsFromKeywords(entry, Globals.prefs.getKeywordDelimiter()); - for(FieldChange change: changes) { - nc.addEdit(new UndoableFieldChange(change)); - } - - // Don't insert the compound into the undoManager, - // it would be added before the component which undoes the insertion of the entry and creates heavy problems - // (which prohibits the undo the deleting multiple entries) + if (!Globals.prefs.isKeywordSyncEnabled()) { + return; } - } + final BibEntry entry = event.getBibEntry(); + // NamedCompount code similar to SpecialFieldUpdateListener + NamedCompound nc = new NamedCompound(Localization.lang("Synchronized special fields based on keywords")); + List changes = SpecialFieldsUtils.syncSpecialFieldsFromKeywords(entry, Globals.prefs.getKeywordDelimiter()); + for(FieldChange change: changes) { + nc.addEdit(new UndoableFieldChange(change)); + } + // Don't insert the compound into the undoManager, + // it would be added before the component which undoes the insertion of the entry and creates heavy problems + // (which prohibits the undo the deleting multiple entries) + } } diff --git a/src/main/java/org/jabref/gui/specialfields/SpecialFieldUpdateListener.java b/src/main/java/org/jabref/gui/specialfields/SpecialFieldUpdateListener.java index 46f3fb5c540..30abd646262 100644 --- a/src/main/java/org/jabref/gui/specialfields/SpecialFieldUpdateListener.java +++ b/src/main/java/org/jabref/gui/specialfields/SpecialFieldUpdateListener.java @@ -23,6 +23,11 @@ public class SpecialFieldUpdateListener { @Subscribe public void listen(FieldChangedEvent fieldChangedEvent) { + // only sync if keyword sync is enabled + if (!Globals.prefs.isKeywordSyncEnabled()) { + return; + } + final BibEntry entry = fieldChangedEvent.getBibEntry(); final String fieldName = fieldChangedEvent.getFieldName(); // Source editor cycles through all entries @@ -32,15 +37,10 @@ public void listen(FieldChangedEvent fieldChangedEvent) { SwingUtilities.invokeLater(() -> { if (FieldName.KEYWORDS.equals(fieldName)) { SpecialFieldsUtils.syncSpecialFieldsFromKeywords(entry, Globals.prefs.getKeywordDelimiter()); - SwingUtilities - .invokeLater(() -> JabRefGUI.getMainFrame().getCurrentBasePanel().updateEntryEditorIfShowing()); - } else { - if (SpecialField.isSpecialField(fieldName)) { - SpecialFieldsUtils.syncKeywordsFromSpecialFields(entry, Globals.prefs.isKeywordSyncEnabled(), Globals.prefs.getKeywordDelimiter()); - SwingUtilities.invokeLater( - () -> JabRefGUI.getMainFrame().getCurrentBasePanel().updateEntryEditorIfShowing()); - } + } else if (SpecialField.isSpecialField(fieldName)) { + SpecialFieldsUtils.syncKeywordsFromSpecialFields(entry, Globals.prefs.getKeywordDelimiter()); } + SwingUtilities.invokeLater(() -> JabRefGUI.getMainFrame().getCurrentBasePanel().updateEntryEditorIfShowing()); }); } diff --git a/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java b/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java index 2b37771aade..ef0037a131e 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java @@ -25,6 +25,7 @@ import org.jabref.logic.importer.util.OAI2Handler; import org.jabref.logic.util.DOI; import org.jabref.logic.util.io.XMLUtil; +import org.jabref.logic.util.strings.StringSimilarity; import org.jabref.model.entry.ArXivIdentifier; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BibtexEntryTypes; @@ -63,13 +64,14 @@ public ArXiv(ImportFormatPreferences importFormatPreferences) { @Override public Optional findFullText(BibEntry entry) throws IOException { Objects.requireNonNull(entry); + Optional pdfUrl = Optional.empty(); // 1. Eprint Optional identifier = entry.getField(FieldName.EPRINT); if (StringUtil.isNotBlank(identifier)) { try { // Get pdf of entry with the specified id - Optional pdfUrl = searchForEntryById(identifier.get()).flatMap(ArXivEntry::getPdfUrl); + pdfUrl = searchForEntryById(identifier.get()).flatMap(ArXivEntry::getPdfUrl); if (pdfUrl.isPresent()) { LOGGER.info("Fulltext PDF found @ arXiv."); return pdfUrl; @@ -85,17 +87,28 @@ public Optional findFullText(BibEntry entry) throws IOException { String doiString = doi.get().getDOI(); // Search for an entry in the ArXiv which is linked to the doi try { - Optional pdfUrl = searchForEntry("doi:" + doiString).flatMap(ArXivEntry::getPdfUrl); - if (pdfUrl.isPresent()) { - LOGGER.info("Fulltext PDF found @ arXiv."); - return pdfUrl; + Optional arxivEntry = searchForEntry("doi:" + doiString); + + if (arxivEntry.isPresent()) { + // Check if entry is a match + StringSimilarity match = new StringSimilarity(); + String arxivTitle = arxivEntry.get().title.orElse(""); + String entryTitle = entry.getField(FieldName.TITLE).orElse(""); + + if (match.isSimilar(arxivTitle, entryTitle)) { + pdfUrl = arxivEntry.get().getPdfUrl(); + if (pdfUrl.isPresent()) { + LOGGER.info("Fulltext PDF found @ arXiv."); + return pdfUrl; + } + } } } catch (FetcherException e) { LOGGER.warn("arXiv DOI API request failed", e); } } - return Optional.empty(); + return pdfUrl; } private Optional searchForEntry(String searchQuery) throws FetcherException { diff --git a/src/main/java/org/jabref/logic/importer/fetcher/CrossRef.java b/src/main/java/org/jabref/logic/importer/fetcher/CrossRef.java index a73361056fc..7f2eb496947 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/CrossRef.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/CrossRef.java @@ -1,11 +1,11 @@ package org.jabref.logic.importer.fetcher; -import java.util.Locale; import java.util.Objects; import java.util.Optional; import org.jabref.logic.formatter.bibtexfields.RemoveBracesFormatter; import org.jabref.logic.util.DOI; +import org.jabref.logic.util.strings.StringSimilarity; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; @@ -13,7 +13,6 @@ import com.mashape.unirest.http.JsonNode; import com.mashape.unirest.http.Unirest; import com.mashape.unirest.http.exceptions.UnirestException; -import info.debatty.java.stringsimilarity.Levenshtein; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.json.JSONArray; @@ -32,10 +31,6 @@ public class CrossRef { // number of results to lookup from crossref API private static final int API_RESULTS = 5; - private static final Levenshtein METRIC_DISTANCE = new Levenshtein(); - // edit distance threshold for entry title comnparison - private static final int METRIC_THRESHOLD = 4; - private static final RemoveBracesFormatter REMOVE_BRACES_FORMATTER = new RemoveBracesFormatter(); public static Optional findDOI(BibEntry entry) { @@ -92,6 +87,7 @@ private static String enhanceQuery(String query, BibEntry entry) { private static Optional findMatchingEntry(BibEntry entry, JSONArray results) { final String entryTitle = REMOVE_BRACES_FORMATTER.format(entry.getLatexFreeField(FieldName.TITLE).orElse("")); + final StringSimilarity stringSimilarity = new StringSimilarity(); for (int i = 0; i < results.length(); i++) { // currently only title-based @@ -102,7 +98,7 @@ private static Optional findMatchingEntry(BibEntry entry, JSONArray resu JSONObject data = results.getJSONObject(i); String dataTitle = data.getJSONArray("title").getString(0); - if (editDistanceIgnoreCase(entryTitle, dataTitle) <= METRIC_THRESHOLD) { + if (stringSimilarity.isSimilar(entryTitle, dataTitle)) { return Optional.of(data.getString("DOI")); } @@ -111,7 +107,7 @@ private static Optional findMatchingEntry(BibEntry entry, JSONArray resu if (data.getJSONArray("subtitle").length() > 0) { String dataWithSubTitle = dataTitle + " " + data.getJSONArray("subtitle").getString(0); - if (editDistanceIgnoreCase(entryTitle, dataWithSubTitle) <= METRIC_THRESHOLD) { + if (stringSimilarity.isSimilar(entryTitle, dataWithSubTitle)) { return Optional.of(data.getString("DOI")); } } @@ -123,9 +119,4 @@ private static Optional findMatchingEntry(BibEntry entry, JSONArray resu return Optional.empty(); } - - private static double editDistanceIgnoreCase(String a, String b) { - // TODO: locale is dependent on the language of the strings?! - return METRIC_DISTANCE.distance(a.toLowerCase(Locale.ENGLISH), b.toLowerCase(Locale.ENGLISH)); - } } diff --git a/src/main/java/org/jabref/logic/importer/fetcher/ScienceDirect.java b/src/main/java/org/jabref/logic/importer/fetcher/ScienceDirect.java index bb041776c9d..ce63112b1c0 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/ScienceDirect.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/ScienceDirect.java @@ -36,7 +36,6 @@ public class ScienceDirect implements FulltextFetcher { @Override public Optional findFullText(BibEntry entry) throws IOException { Objects.requireNonNull(entry); - Optional pdfLink = Optional.empty(); // Try unique DOI first Optional doi = entry.getField(FieldName.DOI).flatMap(DOI::build); @@ -46,21 +45,35 @@ public Optional findFullText(BibEntry entry) throws IOException { try { String sciLink = getUrlByDoi(doi.get().getDOI()); + // scrape the web page not as mobile client! if (!sciLink.isEmpty()) { - // Retrieve PDF link - Document html = Jsoup.connect(sciLink).ignoreHttpErrors(true).get(); + Document html = Jsoup.connect(sciLink) + .userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6") + .referrer("http://www.google.com") + .ignoreHttpErrors(true).get(); + + // Retrieve PDF link (old page) Element link = html.getElementById("pdfLink"); if (link != null) { - LOGGER.info("Fulltext PDF found @ ScienceDirect."); - pdfLink = Optional.of(new URL(link.attr("pdfurl"))); + LOGGER.info("Fulltext PDF found @ ScienceDirect (old page)."); + Optional pdfLink = Optional.of(new URL(link.attr("pdfurl"))); + return pdfLink; + } + // Retrieve PDF link (new page) + String url = html.getElementsByClass("pdf-download-btn-link").attr("href"); + + if (url != null) { + LOGGER.info("Fulltext PDF found @ ScienceDirect (new page)."); + Optional pdfLink = Optional.of(new URL("http://www.sciencedirect.com" + url)); + return pdfLink; } } } catch(UnirestException e) { LOGGER.warn("ScienceDirect API request failed", e); } } - return pdfLink; + return Optional.empty(); } private String getUrlByDoi(String doi) throws UnirestException { diff --git a/src/main/java/org/jabref/logic/pdf/AnnotationImporter.java b/src/main/java/org/jabref/logic/pdf/AnnotationImporter.java new file mode 100644 index 00000000000..ac52e0edac3 --- /dev/null +++ b/src/main/java/org/jabref/logic/pdf/AnnotationImporter.java @@ -0,0 +1,11 @@ +package org.jabref.logic.pdf; + +import java.util.List; + +import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.pdf.FileAnnotation; + +public interface AnnotationImporter { + + List importAnnotations(final String path, final BibDatabaseContext context); +} diff --git a/src/main/java/org/jabref/logic/pdf/EntryAnnotationImporter.java b/src/main/java/org/jabref/logic/pdf/EntryAnnotationImporter.java new file mode 100644 index 00000000000..49ce9c196d2 --- /dev/null +++ b/src/main/java/org/jabref/logic/pdf/EntryAnnotationImporter.java @@ -0,0 +1,54 @@ +package org.jabref.logic.pdf; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.FieldName; +import org.jabref.model.entry.FileField; +import org.jabref.model.entry.ParsedFileField; +import org.jabref.model.pdf.FileAnnotation; + + +/** + * Here all PDF files attached to a BibEntry are scanned for annotations using a PdfAnnotationImporter. + */ +public class EntryAnnotationImporter { + + private final BibEntry entry; + + /** + * @param entry The BibEntry whose attached files are scanned for annotations. + */ + public EntryAnnotationImporter(BibEntry entry) { + this.entry = entry; + } + + /** + * Filter files with a web address containing "www." + * + * @return a list of file parsed files + */ + public List getFilteredFileList() { + return FileField.parse(this.entry.getField(FieldName.FILE).get()).stream() + .filter(parsedFileField -> parsedFileField.getLink().toLowerCase().endsWith(".pdf")) + .filter(parsedFileField -> !parsedFileField.getLink().contains("www.")).collect(Collectors.toList()); + } + + /** + * Reads the annotations from the files that are attached to a BibEntry. + * + * @param context The context is needed for the importer. + * @return Map from each PDF to a list of file annotations + */ + public Map> importAnnotationsFromFiles(BibDatabaseContext context) { + Map> annotations = new HashMap<>(); + AnnotationImporter importer = new PdfAnnotationImporter(); + //import annotationsOfFiles if the selected files are valid which is checked in getFilteredFileList() + this.getFilteredFileList().forEach(parsedFileField -> annotations.put(parsedFileField.getLink(), importer.importAnnotations(parsedFileField.getLink(), context))); + return annotations; + } +} diff --git a/src/main/java/org/jabref/logic/pdf/FileAnnotationCache.java b/src/main/java/org/jabref/logic/pdf/FileAnnotationCache.java index 5f1da00058d..44bbdb633d0 100644 --- a/src/main/java/org/jabref/logic/pdf/FileAnnotationCache.java +++ b/src/main/java/org/jabref/logic/pdf/FileAnnotationCache.java @@ -1,11 +1,10 @@ package org.jabref.logic.pdf; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.ExecutionException; +import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.pdf.FileAnnotation; @@ -13,6 +12,7 @@ import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; + public class FileAnnotationCache { //cache size in entries @@ -20,35 +20,22 @@ public class FileAnnotationCache { //the inner list holds the annotations per file, the outer collection maps this to a BibEntry. private LoadingCache>> annotationCache; - public FileAnnotationCache() { + public FileAnnotationCache(BibDatabaseContext context) { annotationCache = CacheBuilder.newBuilder().maximumSize(CACHE_SIZE).build(new CacheLoader>>() { @Override - public Map> load(BibEntry notUsed) throws Exception { - // Automated reloading of entries is not supported. - return new HashMap<>(); + public Map> load(BibEntry entry) throws Exception { + return new EntryAnnotationImporter(entry).importAnnotationsFromFiles(context); } }); } - public void addToCache(BibEntry entry, final Map> annotations) { - annotationCache.put(entry, annotations); - } - /** * Note that entry becomes the most recent entry in the cache * * @param entry entry for which to get the annotations * @return Map containing a list of annotations in a list for each file */ - public Optional>> getFromCache(Optional entry) { - Optional>> emptyAnnotation = Optional.empty(); - try { - if (entry.isPresent() && annotationCache.get(entry.get()).size() > 0) { - return Optional.of(annotationCache.get(entry.get())); - } - } catch (ExecutionException failure) { - return emptyAnnotation; - } - return emptyAnnotation; + public Map> getFromCache(BibEntry entry) throws ExecutionException { + return annotationCache.get(entry); } } diff --git a/src/main/java/org/jabref/logic/pdf/PdfAnnotationImporterImpl.java b/src/main/java/org/jabref/logic/pdf/PdfAnnotationImporter.java similarity index 88% rename from src/main/java/org/jabref/logic/pdf/PdfAnnotationImporterImpl.java rename to src/main/java/org/jabref/logic/pdf/PdfAnnotationImporter.java index bf03ba19ec6..6489dfa174b 100644 --- a/src/main/java/org/jabref/logic/pdf/PdfAnnotationImporterImpl.java +++ b/src/main/java/org/jabref/logic/pdf/PdfAnnotationImporter.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Optional; import org.jabref.logic.util.io.FileUtil; @@ -24,14 +25,10 @@ import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation; import org.apache.pdfbox.util.PDFTextStripperByArea; -public class PdfAnnotationImporterImpl implements AnnotationImporterInterface { +import static org.jabref.gui.importer.actions.OpenDatabaseAction.LOGGER; - private List pdfPages; - private PDPage page; +public class PdfAnnotationImporter implements AnnotationImporter { - public PdfAnnotationImporterImpl() { - - } /** * Imports the comments from a pdf specified by its path @@ -62,12 +59,12 @@ public List importAnnotations(final String path, final BibDataba } } catch (IOException e) { - e.printStackTrace(); + LOGGER.error(String.format("Failed to read file %s.", path) , e); } - pdfPages = document.getDocumentCatalog().getAllPages(); + List pdfPages = document.getDocumentCatalog().getAllPages(); for (int i = 0; i < pdfPages.size(); i++) { - page = (PDPage) pdfPages.get(i); + PDPage page = (PDPage) pdfPages.get(i); try { for (PDAnnotation annotation : page.getAnnotations()) { @@ -82,7 +79,10 @@ public List importAnnotations(final String path, final BibDataba PDFTextStripperByArea stripperByArea = new PDFTextStripperByArea(); COSArray quadsArray = (COSArray) annotation.getDictionary().getDictionaryObject(COSName.getPDFName("QuadPoints")); String highlightedText = null; - for (int j = 1, k = 0; j <= (quadsArray.size() / 8); j++) { + for (int j = 1, + k = 0; + j <= (quadsArray.size() / 8); + j++) { COSFloat upperLeftX = (COSFloat) quadsArray.get(k); COSFloat upperLeftY = (COSFloat) quadsArray.get(1 + k); @@ -124,14 +124,13 @@ public List importAnnotations(final String path, final BibDataba annotationsList.add(new FileAnnotation(annotation, i + 1)); } } - } catch (IOException e1) { - e1.printStackTrace(); + } catch (IOException e) { + LOGGER.error(String.format("Failed to read file %s.", path) , e); } } try { document.close(); - } catch (IOException e) { - e.printStackTrace(); + } catch (IOException ignored) { } return annotationsList; } @@ -144,7 +143,7 @@ public List importAnnotations(final String path, final BibDataba */ public PDDocument importPdfFile(final String path) throws IOException { - if(path.toLowerCase().endsWith(".pdf")){ + if(path.toLowerCase(Locale.ROOT).endsWith(".pdf")){ return PDDocument.load("/"+ path); } return null; diff --git a/src/main/java/org/jabref/logic/specialfields/SpecialFieldsUtils.java b/src/main/java/org/jabref/logic/specialfields/SpecialFieldsUtils.java index bb6870c5b25..125a153c710 100644 --- a/src/main/java/org/jabref/logic/specialfields/SpecialFieldsUtils.java +++ b/src/main/java/org/jabref/logic/specialfields/SpecialFieldsUtils.java @@ -35,18 +35,16 @@ public static List updateField(SpecialField field, String value, Bi UpdateField.updateField(entry, field.getFieldName(), value, nullFieldIfValueIsTheSame) .ifPresent(fieldChange -> fieldChanges.add(fieldChange)); // we cannot use "value" here as updateField has side effects: "nullFieldIfValueIsTheSame" nulls the field if value is the same - fieldChanges.addAll(SpecialFieldsUtils.exportFieldToKeywords(field, entry, isKeywordSyncEnabled, keywordDelimiter)); + if (isKeywordSyncEnabled) { + fieldChanges.addAll(SpecialFieldsUtils.exportFieldToKeywords(field, entry, keywordDelimiter)); + } return fieldChanges; } - private static List exportFieldToKeywords(SpecialField specialField, BibEntry entry, boolean isKeywordSyncEnabled, Character keywordDelimiter) { + private static List exportFieldToKeywords(SpecialField specialField, BibEntry entry, Character keywordDelimiter) { List fieldChanges = new ArrayList<>(); - if (!isKeywordSyncEnabled) { - return fieldChanges; - } - Optional newValue = entry.getField(specialField.getFieldName()).map(Keyword::new); KeywordList keyWords = specialField.getKeyWords(); @@ -59,11 +57,11 @@ private static List exportFieldToKeywords(SpecialField specialField /** * Update keywords according to values of special fields */ - public static List syncKeywordsFromSpecialFields(BibEntry entry, boolean isKeywordSyncEnabled, Character keywordDelimiter) { + public static List syncKeywordsFromSpecialFields(BibEntry entry, Character keywordDelimiter) { List fieldChanges = new ArrayList<>(); for(SpecialField field: SpecialField.values()) { - fieldChanges.addAll(SpecialFieldsUtils.exportFieldToKeywords(field, entry, isKeywordSyncEnabled, keywordDelimiter)); + fieldChanges.addAll(SpecialFieldsUtils.exportFieldToKeywords(field, entry, keywordDelimiter)); } return fieldChanges; @@ -71,6 +69,7 @@ public static List syncKeywordsFromSpecialFields(BibEntry entry, bo private static List importKeywordsForField(KeywordList keywordList, SpecialField field, BibEntry entry) { List fieldChanges = new ArrayList<>(); + KeywordList values = field.getKeyWords(); Optional newValue = Optional.empty(); for (Keyword keyword : values) { @@ -88,7 +87,7 @@ private static List importKeywordsForField(KeywordList keywordList, } /** - * updates field values according to keywords + * Updates special field values according to keywords */ public static List syncSpecialFieldsFromKeywords(BibEntry entry, Character keywordDelimiter) { List fieldChanges = new ArrayList<>(); diff --git a/src/main/java/org/jabref/logic/util/strings/StringSimilarity.java b/src/main/java/org/jabref/logic/util/strings/StringSimilarity.java new file mode 100644 index 00000000000..c17443f07fb --- /dev/null +++ b/src/main/java/org/jabref/logic/util/strings/StringSimilarity.java @@ -0,0 +1,27 @@ +package org.jabref.logic.util.strings; + +import java.util.Locale; + +import info.debatty.java.stringsimilarity.Levenshtein; + +public class StringSimilarity { + private final Levenshtein METRIC_DISTANCE = new Levenshtein(); + // edit distance threshold for entry title comnparison + private final int METRIC_THRESHOLD = 4; + + /** + * String similarity based on Levenshtein, ignoreCase, and fixed metric threshold of 4. + * + * @param a String to compare + * @param b String to compare + * @return true if Strings are considered as similar by the algorithm + */ + public boolean isSimilar(String a, String b) { + return editDistanceIgnoreCase(a, b) <= METRIC_THRESHOLD; + } + + private double editDistanceIgnoreCase(String a, String b) { + // TODO: locale is dependent on the language of the strings?! + return METRIC_DISTANCE.distance(a.toLowerCase(Locale.ENGLISH), b.toLowerCase(Locale.ENGLISH)); + } +} diff --git a/src/main/java/org/jabref/model/pdf/FileAnnotation.java b/src/main/java/org/jabref/model/pdf/FileAnnotation.java index 62a764954fe..eb0c33dda5e 100644 --- a/src/main/java/org/jabref/model/pdf/FileAnnotation.java +++ b/src/main/java/org/jabref/model/pdf/FileAnnotation.java @@ -16,7 +16,7 @@ public class FileAnnotation { private FileAnnotation linkedFileAnnotation; private final static int ABBREVIATED_ANNOTATION_NAME_LENGTH = 45; - private boolean linkedComment; + private boolean linkedAnnotation; public FileAnnotation(final String commentId, final String author, final String date, final int page, final String content, final String annotationType) { @@ -56,8 +56,8 @@ private String abbreviateAnnotationName(final String annotationName ){ public void linkComments(FileAnnotation commentToLinkTo){ linkedFileAnnotation = commentToLinkTo; commentToLinkTo.setLinkedFileAnnotation(this); - commentToLinkTo.setLinkedComment(true); - linkedComment = true; + commentToLinkTo.setLinkedAnnotation(true); + linkedAnnotation = true; } @Override @@ -117,11 +117,11 @@ public String getAnnotationType() { return annotationType; } - public boolean hasLinkedComment() { - return linkedComment; + public boolean hasLinkedAnnotation() { + return linkedAnnotation; } - public void setLinkedComment(boolean linkedComment) { - this.linkedComment = linkedComment; + public void setLinkedAnnotation(boolean linkedAnnotation) { + this.linkedAnnotation = linkedAnnotation; } } diff --git a/src/main/resources/journals/IEEEJournalListCode.txt b/src/main/resources/journals/IEEEJournalListCode.txt index 804a82ff730..c448f17599f 100644 --- a/src/main/resources/journals/IEEEJournalListCode.txt +++ b/src/main/resources/journals/IEEEJournalListCode.txt @@ -1,9 +1,13 @@ +# list compiled from http://tug.ctan.org/tex-archive/macros/latex/contrib/IEEEtran/bibtex/IEEEfull.bib (2015/08/26 V1.14) Canadian Journal of Electrical and Computer Engineering=#IEEE_J_CJECE# +China Communications Magazine=#IEEE_M_CHINAC# +Computer=#IEEE_M_C# +IEEE ASSP Magazine=#IEEE_M_ASSP# +IEEE Access=#IEEE_O_ACC# IEEE Aerospace and Electronics Systems Magazine=#IEEE_M_AES# IEEE Annals of the History of Computing=#IEEE_M_HIST# IEEE Antennas and Propagation Magazine=#IEEE_M_AP# IEEE Antennas and Wireless Propagation Letters=#IEEE_J_AWPL# -IEEE ASSP Magazine=#IEEE_M_ASSP# IEEE Circuits and Devices Magazine=#IEEE_M_CD# IEEE Circuits and Systems Magazine=#IEEE_M_CAS# IEEE Communications Letters=#IEEE_J_COML# @@ -15,76 +19,105 @@ IEEE Computational Science and Engineering Magazine=#IEEE_M_CSEM# IEEE Computer Applications in Power=#IEEE_M_CAP# IEEE Computer Architecture Letters=#IEEE_J_CAL# IEEE Computer Graphics and Applications=#IEEE_M_CGA# -IEEE Computer=#IEEE_M_C# IEEE Computing in Science and Engineering=#IEEE_M_CSE# IEEE Concurrency=#IEEE_M_CONC# IEEE Control Systems Magazine=#IEEE_M_CS# -IEEE Control Systems=#IEEE_M_CS# +IEEE Design & Test=#IEEE_M_DT# IEEE Design and Test of Computers=#IEEE_M_DTC# IEEE Distributed Systems Online=#IEEE_O_DSO# IEEE Electrical Insulation Magazine=#IEEE_M_EI# -IEEE Electron Device Letters=#IEEE_J_EDL# +IEEE Electrification Magazine=#IEEE_M_ETF# IEEE ElectroTechnology Review=#IEEE_M_ETR# -IEEE Engineering in Medicine and Biology Magazine=#IEEE_M_EMB# +IEEE Electromagnetic Compatibility Magazine=#IEEE_M_EMC# +IEEE Electron Device Letters=#IEEE_J_EDL# +IEEE Embedded Systems Letters=#IEEE_J_ES# IEEE Engineering Management Review=#IEEE_M_EMR# +IEEE Engineering in Medicine and Biology Magazine=#IEEE_M_EMB# IEEE Expert=#IEEE_M_EXP# IEEE Geoscience and Remote Sensing Letters=#IEEE_J_GRSL# +IEEE Geoscience and Remote Sensing Magazine=#IEEE_M_GRS# +IEEE IT Professional=#IEEE_M_ITP# IEEE Industrial Electronics Magazine=#IEEE_M_IE# IEEE Industry Applications Magazine=#IEEE_M_IA# IEEE Instrumentation and Measurement Magazine=#IEEE_M_IM# IEEE Intelligent Systems=#IEEE_M_IS# IEEE Intelligent Transportation Systems Magazine=#IEEE_M_ITS# IEEE Internet Computing=#IEEE_M_IC# -IEEE IT Professional=#IEEE_M_ITP# +IEEE Internet of Things Journal=#IEEE_J_IOT# +IEEE Journal of Biomedical and Health Informatics=#IEEE_J_BHI# +IEEE Journal of Electron Devices Society=#IEEE_J_EDS# +IEEE Journal of Microelectromechanical Systems=#IEEE_J_MEMSI# IEEE Journal of Oceanic Engineering=#IEEE_J_OE# +IEEE Journal of Optical Communications and Networking=#IEEE_J_OCN# +IEEE Journal of Photovoltaics=#IEEE_J_PHOT# IEEE Journal of Product Safety Engineering=#IEEE_J_PSE# IEEE Journal of Quantum Electronics=#IEEE_J_JQE# IEEE Journal of Robotics and Automation=#IEEE_J_JRA# +IEEE Journal of Selected Topics in Applied Earth Observations and Remote Sensing=#IEEE_J_STARS# IEEE Journal of Selected Topics in Quantum Electronics=#IEEE_J_JSTQE# IEEE Journal of Selected Topics in Signal Processing=#IEEE_J_STSP# -IEEE Journal of Selected Topics on Applied Observations and Remote Sensing=#IEEE_J_STARS# IEEE Journal of Solid-State Circuits=#IEEE_J_JSSC# +IEEE Journal of Translational Engineering in Health and Medicine=#IEEE_J_TEHM# +IEEE Journal on Exploratory Solid-State Computational Devices and Circuits=#IEEE_J_XCDC# +IEEE Journal on Multiscale and Multiphysics Computational Techniques=#IEEE_J_MMCT# IEEE Journal on Selected Areas in Communications=#IEEE_J_JSAC# IEEE Journal on Technology in Computer Aided Design=#IEEE_J_TCAD# +IEEE Life Sciences Letters=#IEEE_J_LS# +IEEE Magnetics Letters=#IEEE_J_MAGL# IEEE Micro=#IEEE_M_MICRO# +IEEE Microwave Magazine=#IEEE_M_MW# IEEE Microwave and Guided Wave Letters=#IEEE_J_MGWL# IEEE Microwave and Wireless Components Letters=#IEEE_J_MWCL# -IEEE Microwave Magazine=#IEEE_M_MW# IEEE Multimedia=#IEEE_M_MM# +IEEE Nanotechnology Express=#IEEE_J_ENANO# IEEE Nanotechnology Magazine=#IEEE_M_NANO# IEEE Network=#IEEE_M_NET# IEEE Personal Communications Magazine=#IEEE_M_PCOM# IEEE Pervasive Computing=#IEEE_M_PVC# +IEEE Photonics Journal=#IEEE_J_PJ# IEEE Photonics Technology Letters=#IEEE_J_PTL# IEEE Potentials=#IEEE_M_POT# -IEEE Power and Energy Magazine=#IEEE_M_PE# IEEE Power Electronics Letters=#IEEE_J_PEL# +IEEE Power Electronics Magazine=#IEEE_M_PEL# IEEE Power Engineering Review=#IEEE_M_PER# +IEEE Power and Energy Magazine=#IEEE_M_PE# +IEEE Power and Energy Technology Systems Journal=#IEEE_J_PETS# +IEEE Pulse=#IEEE_M_PULSE# +IEEE RFIC Journal=#IEEE_J_RFIC# +IEEE RFID Journal=#IEEE_J_RFID# IEEE Reviews in Biomedical Engineering=#IEEE_J_RBME# +IEEE Revista Iberoamericana de Technolog'ias del Aprendizaje=#IEEE_J_RITA# +IEEE Robotics and Automation Letters=#IEEE_J_RAL# IEEE Robotics and Automation Magazine=#IEEE_M_RA# IEEE Security and Privacy=#IEEE_M_SAP# IEEE Sensors Journal=#IEEE_J_SENSOR# IEEE Signal Processing Letters=#IEEE_J_SPL# IEEE Signal Processing Magazine=#IEEE_M_SP# IEEE Software=#IEEE_M_S# +IEEE Solid-State Circuits Magazine=#IEEE_M_SSC# IEEE Spectrum=#IEEE_M_SPECT# +IEEE Sustainable Computing=#IEEE_J_SUSC# IEEE Systems Journal=#IEEE_J_SYST# +IEEE Systems, Man, and Cybernetics Magazine=#IEEE_M_SMC# IEEE Technology and Society Magazine=#IEEE_M_TS# -IEEE Transactions on Acoustics, Speech and Signal Processing=#IEEE_J_ASSP# IEEE Transactions on Acoustics, Speech, and Signal Processing=#IEEE_J_ASSP# IEEE Transactions on Advanced Packaging=#IEEE_J_ADVP# IEEE Transactions on Aeronautical and Navigational Electronics=#IEEE_J_ANNE# +IEEE Transactions on Aerospace=#IEEE_J_AS# IEEE Transactions on Aerospace and Electronic Systems=#IEEE_J_AES# IEEE Transactions on Aerospace and Navigational Electronics=#IEEE_J_ANE# -IEEE Transactions on Aerospace=#IEEE_J_AS# +IEEE Transactions on Affective Computing=#IEEE_J_AFFC# IEEE Transactions on Airborne Electronics=#IEEE_J_AIRE# IEEE Transactions on Antennas and Propagation=#IEEE_J_AP# IEEE Transactions on Applications and Industry=#IEEE_J_APPIND# IEEE Transactions on Applied Superconductivity=#IEEE_J_ASC# -IEEE Transactions on Audio and Electroacoustics=#IEEE_J_AUEA# IEEE Transactions on Audio=#IEEE_J_AU# +IEEE Transactions on Audio and Electroacoustics=#IEEE_J_AUEA# +IEEE Transactions on Audio, Speech, and Language Processing=#IEEE_J_ASL# IEEE Transactions on Automatic Control=#IEEE_J_AC# IEEE Transactions on Automation Science and Engineering=#IEEE_J_ASE# +IEEE Transactions on Autonomous Mental Development=#IEEE_J_AMD# +IEEE Transactions on Big Data=#IEEE_J_BD# IEEE Transactions on Bio-Medical Electronics=#IEEE_J_BMELC# IEEE Transactions on Bio-Medical Engineering=#IEEE_J_B-ME# IEEE Transactions on Biomedical Circuits and Systems=#IEEE_J_BCAS# @@ -92,25 +125,33 @@ IEEE Transactions on Biomedical Engineering=#IEEE_J_BME# IEEE Transactions on Broadcast and Television Receivers=#IEEE_J_BCTV# IEEE Transactions on Broadcasting=#IEEE_J_BC# IEEE Transactions on Circuit Theory=#IEEE_J_CT# -IEEE Transactions on Circuits and Systems for Video Technology=#IEEE_J_CASVT# +IEEE Transactions on Circuits and Systems=#IEEE_J_CAS# IEEE Transactions on Circuits and Systems I: Fundamental Theory and Applications=#IEEE_J_CASI# IEEE Transactions on Circuits and Systems I: Regular Papers=#IEEE_J_CASI_RP# IEEE Transactions on Circuits and Systems II: Analog and Digital Signal Processing=#IEEE_J_CASII# IEEE Transactions on Circuits and Systems II: Express Briefs=#IEEE_J_CASII_EB# -IEEE Transactions on Circuits and Systems=#IEEE_J_CAS# +IEEE Transactions on Circuits and Systems for Video Technology=#IEEE_J_CASVT# +IEEE Transactions on Cloud Computing=#IEEE_J_CC# +IEEE Transactions on Cognitive Communications and Networking=#IEEE_J_CCN# +IEEE Transactions on Cognitive and Developmental Systems=#IEEE_J_CDS# IEEE Transactions on Communication Technology=#IEEE_J_COMT# IEEE Transactions on Communications=#IEEE_J_COM# IEEE Transactions on Component Parts=#IEEE_J_CPART# IEEE Transactions on Components and Packaging Technologies=#IEEE_J_CAPTS# IEEE Transactions on Components and Packaging Technology=#IEEE_J_CAPT# IEEE Transactions on Components, Hybrids and Manufacturing Technology=#IEEE_J_CHMT# -IEEE Transactions on Components, Packaging and Manufacturing Technology, Part A=#IEEE_J_CPMTA# -IEEE Transactions on Components, Packaging and Manufacturing Technology, Part B: Advanced Packaging=#IEEE_J_CPMTB# -IEEE Transactions on Components, Packaging and Manufacturing Technology, Part C: Manufacturing=#IEEE_J_CPMTC# +IEEE Transactions on Components, Packaging and Manufacturing Technology=#IEEE_J_CPMT# +IEEE Transactions on Components, Packaging and Manufacturing Technology A=#IEEE_J_CPMTA# +IEEE Transactions on Components, Packaging and Manufacturing Technology B: Advanced Packaging=#IEEE_J_CPMTB# +IEEE Transactions on Components, Packaging and Manufacturing Technology C: Manufacturing=#IEEE_J_CPMTC# +IEEE Transactions on Computational Intelligence and AI in Games=#IEEE_J_CIAIG# +IEEE Transactions on Computational Social Systems=#IEEE_J_CSS# IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems=#IEEE_J_CAD# IEEE Transactions on Computers=#IEEE_J_C# IEEE Transactions on Consumer Electronics=#IEEE_J_CE# IEEE Transactions on Control Systems Technology=#IEEE_J_CST# +IEEE Transactions on Control of Network Systems=#IEEE_J_CNS# +IEEE Transactions on Cybernetics=#IEEE_J_CYB# IEEE Transactions on Dependable and Secure Computing=#IEEE_J_DSC# IEEE Transactions on Device and Materials Reliability=#IEEE_J_DMR# IEEE Transactions on Dielectrics and Electrical Insulation=#IEEE_J_DEI# @@ -120,26 +161,31 @@ IEEE Transactions on Electromagnetic Compatibility=#IEEE_J_EMC# IEEE Transactions on Electron Devices=#IEEE_J_ED# IEEE Transactions on Electronic Computers=#IEEE_J_ECOMP# IEEE Transactions on Electronics Packaging Manufacturing=#IEEE_J_EPM# +IEEE Transactions on Emerging Topics in Computing=#IEEE_J_ETC# +IEEE Transactions on Emerging and Selected Topics in Circuits and Systems=#IEEE_J_ETCAS# +IEEE Transactions on Emerging and Selected Topics in Power Electronics=#IEEE_J_ESTPE# IEEE Transactions on Energy Conversion=#IEEE_J_EC# IEEE Transactions on Engineering Management=#IEEE_J_EM# IEEE Transactions on Engineering Writing and Speech=#IEEE_J_EWS# IEEE Transactions on Evolutionary Computation=#IEEE_J_EVC# IEEE Transactions on Fuzzy Systems=#IEEE_J_FUZZ# -IEEE Transactions on Geoscience and Remote Sensing=#IEEE_J_GRS# IEEE Transactions on Geoscience Electronics=#IEEE_J_GE# +IEEE Transactions on Geoscience and Remote Sensing=#IEEE_J_GRS# IEEE Transactions on Haptics=#IEEE_J_H# IEEE Transactions on Human Factors in Electronics=#IEEE_J_HFE# +IEEE Transactions on Human-Machine Systems=#IEEE_J_HMS# IEEE Transactions on Image Processing=#IEEE_J_IP# -IEEE Transactions on Industrial Electronics and Control Instrumentation=#IEEE_J_IECI# IEEE Transactions on Industrial Electronics=#IEEE_J_IE# +IEEE Transactions on Industrial Electronics and Control Instrumentation=#IEEE_J_IECI# IEEE Transactions on Industrial Informatics=#IEEE_J_IINF# -IEEE Transactions on Industry and General Applications=#IEEE_J_IGA# IEEE Transactions on Industry Applications=#IEEE_J_IA# +IEEE Transactions on Industry and General Applications=#IEEE_J_IGA# IEEE Transactions on Information Forensics and Security=#IEEE_J_IFS# IEEE Transactions on Information Technology in Biomedicine=#IEEE_J_ITBM# IEEE Transactions on Information Theory=#IEEE_J_IT# IEEE Transactions on Instrumentation and Measurement=#IEEE_J_IM# IEEE Transactions on Intelligent Transportation Systems=#IEEE_J_ITS# +IEEE Transactions on Intelligent Vehicles=#IEEE_J_IV# IEEE Transactions on Knowledge and Data Engineering=#IEEE_J_KDE# IEEE Transactions on Learning Technologies=#IEEE_J_LT# IEEE Transactions on Magnetics=#IEEE_J_MAG# @@ -150,11 +196,15 @@ IEEE Transactions on Medical Imaging=#IEEE_J_MI# IEEE Transactions on Microwave Theory and Techniques=#IEEE_J_MTT# IEEE Transactions on Military Electronics=#IEEE_J_MIL# IEEE Transactions on Mobile Computing=#IEEE_J_MC# +IEEE Transactions on Molecular, Biological and Multi-Scale Communications=#IEEE_J_MBSC# +IEEE Transactions on Multi-Scale Computing Systems=#IEEE_J_MSCS# IEEE Transactions on Multimedia=#IEEE_J_MM# IEEE Transactions on NanoBioscience=#IEEE_J_NB# IEEE Transactions on Nanotechnology=#IEEE_J_NANO# +IEEE Transactions on Network Science and Engineering=#IEEE_J_NSE# IEEE Transactions on Network and Service Management=#IEEE_J_NSM# IEEE Transactions on Neural Networks=#IEEE_J_NN# +IEEE Transactions on Neural Networks and Learning Systems=#IEEE_J_NNLS# IEEE Transactions on Neural Systems and Rehabilitation Engineering=#IEEE_J_NSRE# IEEE Transactions on Nuclear Science=#IEEE_J_NS# IEEE Transactions on Parallel and Distributed Systems=#IEEE_J_PDS# @@ -170,22 +220,26 @@ IEEE Transactions on Professional Communication=#IEEE_J_PC# IEEE Transactions on Radio Frequency Interference=#IEEE_J_RFI# IEEE Transactions on Rehabilitation Engineering=#IEEE_J_RE# IEEE Transactions on Reliability=#IEEE_J_R# -IEEE Transactions on Robotics and Automation=#IEEE_J_RA# IEEE Transactions on Robotics=#IEEE_J_RO# +IEEE Transactions on Robotics and Automation=#IEEE_J_RA# IEEE Transactions on Semiconductor Manufacturing=#IEEE_J_SM# IEEE Transactions on Services Computing=#IEEE_J_SC# IEEE Transactions on Signal Processing=#IEEE_J_SP# +IEEE Transactions on Signal and Information Processing over Networks=#IEEE_J_SIPN# +IEEE Transactions on Smart Grid=#IEEE_J_SG# IEEE Transactions on Software Engineering=#IEEE_J_SE# IEEE Transactions on Sonics and Ultrasonics=#IEEE_J_SU# IEEE Transactions on Speech and Audio Processing=#IEEE_J_SAP# +IEEE Transactions on Sustainable Energy=#IEEE_J_STE# IEEE Transactions on Systems Science and Cybernetics=#IEEE_J_SSC# -IEEE Transactions on Systems, Man and Cybernetics=#IEEE_J_SMC# -IEEE Transactions on Systems, Man, and Cybernetics, Part A: Systems and Humans=#IEEE_J_SMCA# -IEEE Transactions on Systems, Man, and Cybernetics, Part B: Cybernetics=#IEEE_J_SMCB# -IEEE Transactions on Systems, Man, and Cybernetics, Part C: Applications and Reviews=#IEEE_J_SMCC# IEEE Transactions on Systems, Man, and Cybernetics=#IEEE_J_SMC# +IEEE Transactions on Systems, Man, and Cybernetics A: Systems and Humans=#IEEE_J_SMCA# +IEEE Transactions on Systems, Man, and Cybernetics B: Cybernetics=#IEEE_J_SMCB# +IEEE Transactions on Systems, Man, and Cybernetics C: Applications and Reviews=#IEEE_J_SMCC# +IEEE Transactions on Systems, Man, and Cybernetics: Systems=#IEEE_J_SMCS# +IEEE Transactions on Terahertz Science and Technology=#IEEE_J_TTHZ# +IEEE Transactions on Transportation Electrification=#IEEE_J_TTE# IEEE Transactions on Ultrasonics Engineering=#IEEE_J_UE# -IEEE Transactions on Ultrasonics, Ferroelectrics and Frequency Control=#IEEE_J_UFFC# IEEE Transactions on Ultrasonics, Ferroelectrics, and Frequency Control=#IEEE_J_UFFC# IEEE Transactions on Vehicular Communications=#IEEE_J_VC# IEEE Transactions on Vehicular Technology=#IEEE_J_VT# @@ -194,19 +248,17 @@ IEEE Transactions on Visualization and Computer Graphics=#IEEE_J_VCG# IEEE Transactions on Wireless Communications=#IEEE_J_WCOM# IEEE Translation Journal on Magnetics in Japan=#IEEE_J_TJMJ# IEEE Vehicular Technology Magazine=#IEEE_M_VT# -IEEE Wireless Communications Magazine=#IEEE_M_WC# IEEE Wireless Communications=#IEEE_M_WC# +IEEE Wireless Communications Letters=#IEEE_J_WCOML# +IEEE/ACM Transactions on Audio, Speech, and Language Processing=#IEEE_J_ASLP# IEEE/ACM Transactions on Computational Biology and Bioinformatics=#IEEE_J_CBB# IEEE/ACM Transactions on Networking=#IEEE_J_NET# IEEE/ASME Journal of Microelectromechanical Systems=#IEEE_J_MEMS# IEEE/ASME Transactions on Mechatronics=#IEEE_J_MECH# +IEEE/CAA Journal of Automatica Sinica=#IEEE_J_JAS# IEEE/ECS Electrochemical and Solid-State Letters=#IEEE_J_ESSL# IEEE/OSA Journal of Display Technology=#IEEE_J_JDT# IEEE/OSA Journal of Lightwave Technology=#IEEE_J_JLT# IEEE/TMS Journal of Electronic Materials=#IEEE_J_JEM# -Journal of Lightwave Technology=#IEEE_J_JLT# -Journal of Microelectromechanical Systems=#IEEE_J_MEMS# Proceedings of the IEEE=#IEEE_J_PROC# Today's Engineer=#IEEE_M_TODAY# -Transactions on Computers=#IEEE_J_C# - diff --git a/src/main/resources/journals/IEEEJournalListText.txt b/src/main/resources/journals/IEEEJournalListText.txt index e83b72547c6..6bc31a3ea59 100644 --- a/src/main/resources/journals/IEEEJournalListText.txt +++ b/src/main/resources/journals/IEEEJournalListText.txt @@ -1,269 +1,264 @@ -Canadian Journal of Electrical and Computer Engineering = Can. J. Electr. Comput. Eng. +# list compiled from http://tug.ctan.org/tex-archive/macros/latex/contrib/IEEEtran/bibtex/IEEEabrv.bib (2015/08/26 V1.14) +Canadian Journal of Electrical and Computer Engineering = Canadian J. Elect. Comput. Eng. +China Communications = China Commun. +Computer = Computer +IEEE ASSP Magazine = IEEE ASSP Mag. IEEE Access = IEEE Access -IEEE Aerospace and Electronic Systems Magazine = IEEE Aerosp. Electron. Syst. Mag. +IEEE Aerospace and Electronics Systems Magazine = IEEE Aerosp. Electron. Syst. Mag. IEEE Annals of the History of Computing = IEEE Ann. Hist. Comput. -IEEE Antennas and Propagation Magazine = IEEE Antennas. Propag. -IEEE Antennas and Wireless Propagation Letters = IEEE Antennas Wirel. Propag. Lett. -IEEE Biometrics Compendium = IEEE Biometrics Compend. -IEEE Circuits & Devices = IEEE Circuits. Device. +IEEE Antennas and Propagation Magazine = IEEE Antennas Propag. Mag. +IEEE Antennas and Wireless Propagation Letters = IEEE Antennas Wireless Propag. Lett. IEEE Circuits and Devices Magazine = IEEE Circuits Devices Mag. IEEE Circuits and Systems Magazine = IEEE Circuits Syst. Mag. -IEEE Cloud Computing = IEEE Cloud Comput. IEEE Communications Letters = IEEE Commun. Lett. IEEE Communications Magazine = IEEE Commun. Mag. -IEEE Communications Surveys and Tutorials = IEEE Commun. Surv. Tutorials +IEEE Communications Society Magazine = IEEE Commun. Soc. Mag. +IEEE Communications Surveys and Tutorials = IEEE Commun. Surveys Tuts. IEEE Computational Intelligence Magazine = IEEE Comput. Intell. Mag. -IEEE Computational Science & Engineering = IEEE Comput. Sci. Eng. +IEEE Computational Science and Engineering Magazine = IEEE Comput. Sci. Eng. Mag. IEEE Computer Applications in Power = IEEE Comput. Appl. Power IEEE Computer Architecture Letters = IEEE Comput. Archit. Lett. -IEEE Computer Graphics and Applications = IEEE Comput. Graphics Appl. -IEEE Computer Group News = IEEE Comput. Group. N. +IEEE Computer Graphics and Applications = IEEE Comput. Graph. Appl. +IEEE Computing in Science and Engineering = IEEE Comput. Sci. Eng. IEEE Concurrency = IEEE Concurrency -IEEE Consumer Electronics Magazine = IEEE Consum. Electron. Mag. -IEEE Control Systems = IEEE Control Syst. IEEE Control Systems Magazine = IEEE Control Syst. Mag. IEEE Design & Test = IEEE Des. Test -IEEE Design & Test of Computers = IEEE Des. Test. Comput. -IEEE Design and Test of Computers = IEEE Des. Test Comput. +IEEE Design and Test of Computers = IEEE Des. Test. Comput. IEEE Distributed Systems Online = IEEE Distrib. Syst. Online IEEE Electrical Insulation Magazine = IEEE Electr. Insul. Mag. -IEEE Electrification Magazine = IEEE Electrif. Mag. -IEEE Electromagnetic Compatibility Magazine = IEEE Electromagn. Compat. Mag. -IEEE Electromagnetic Compatibility Symposium Record = IEEE Electroman. Comp. +IEEE Electrification Magazine = IEEE Electrific. Mag. +IEEE ElectroTechnology Review = IEEE ElectroTechnol. Rev. +IEEE Electromagnetic Compatibility Magazine = IEEE Electromagn. Compat. IEEE Electron Device Letters = IEEE Electron Device Lett. -IEEE Embedded Systems Letters = IEEE Embedded Sys. Lett. +IEEE Embedded Systems Letters = IEEE Embedded Syst. Lett. +IEEE Engineering Management Review = IEEE Eng. Manag. Rev. IEEE Engineering in Medicine and Biology Magazine = IEEE Eng. Med. Biol. Mag. -IEEE Engineering Management Review = IEEE Eng. Manage. Rev. -IEEE Expert-intelligent Systems & their Applications = IEEE Expert. -IEEE Geoscience and Remote Sensing Letters = IEEE Geosci. Remote. S. +IEEE Expert = IEEE Expert +IEEE Geoscience and Remote Sensing Letters = IEEE Geosci. Remote Sens. Lett. IEEE Geoscience and Remote Sensing Magazine = IEEE Geosci. Remote Sens. Mag. +IEEE IT Professional = IEEE IT Prof. IEEE Industrial Electronics Magazine = IEEE Ind. Electron. Mag. IEEE Industry Applications Magazine = IEEE Ind. Appl. Mag. -IEEE Instrumentation & Measurement Magazine = IEEE Instru. Meas. Mag. IEEE Instrumentation and Measurement Magazine = IEEE Instrum. Meas. Mag. -IEEE Intelligent Systems & their Applications = IEEE Intell. Syst. App. IEEE Intelligent Systems = IEEE Intell. Syst. IEEE Intelligent Transportation Systems Magazine = IEEE Intell. Transp. Syst. Mag. -IEEE Internet Computing = IEEE Internet. Comput. -IEEE Internet of Things Journal = IEEE IoT J. -IEEE Journal of Biomedical and Health Informatics = IEEE J. Biomed. Health. Inf. -IEEE Journal of Oceanic Engineering = IEEE J. Oceanic. Eng. -IEEE Journal of Photovoltaics = IEEE J. Photovoltaics -IEEE Journal of Quantum Electronics = IEEE J. Quantum. Electron. -IEEE Journal of Robotics and Automation = IEEE T. Robotic. Autom. -IEEE Journal of Selected Topics in Applied Earth Observations and Remote Sensing = IEEE J. Sel. Top. Appl. Earth Obs. Remote Sens. -IEEE Journal of Selected Topics in Quantum Electronics = IEEE J. Sel. Topics in Quantum Electron. -IEEE Journal of Selected Topics in Signal Processing = IEEE J. Sel. Top. Signal Process. +IEEE Internet Computing = IEEE Internet Comput. +IEEE Internet of Things Journal = IEEE Internet Things J. +IEEE Journal of Biomedical and Health Informatics = IEEE J. Biomed. Health Inform. +IEEE Journal of Electron Devices Society = IEEE J. Electron Devices Soc. +IEEE Journal of Microelectromechanical Systems = J. Microelectromech. Syst. +IEEE Journal of Oceanic Engineering = IEEE J. Ocean. Eng. +IEEE Journal of Optical Communications and Networking = IEEE J. Opt. Commun. Netw. +IEEE Journal of Photovoltaics = IEEE J. Photovolt. +IEEE Journal of Product Safety Engineering = IEEE J. Product Safety Eng. +IEEE Journal of Quantum Electronics = IEEE J. Quantum Electron. +IEEE Journal of Robotics and Automation = IEEE J. Robot. Autom. +IEEE Journal of Selected Topics in Applied Earth Observations and Remote Sensing = IEEE J. Sel. Topics Appl. Earth Observ. Remote Sens. +IEEE Journal of Selected Topics in Quantum Electronics = IEEE J. Sel. Topics Quantum Electron. +IEEE Journal of Selected Topics in Signal Processing = IEEE J. Sel. Topics Signal Process. IEEE Journal of Solid-State Circuits = IEEE J. Solid-State Circuits -IEEE Journal of the Electron Devices Society = IEEE J. Electron Devices Soc. -IEEE Journal on Electronic Circuits and Systems = IEE J. Electron. Circuits Syst. -IEEE Journal on Emerging and Selected Topics in Circuits and Systems = IEEE J. Emerging Sel. Top. Circuits Syst. -IEEE Journal on Emerging and Selected Topics in Power Electronics = IEEE J. Emerging Sel. Top. Power Electron. +IEEE Journal of Translational Engineering in Health and Medicine = IEEE J. Transl. Eng. Health Med. +IEEE Journal on Exploratory Solid-State Computational Devices and Circuits = IEEE J. Explor. Solid-State Computat. Devices Circuits +IEEE Journal on Multiscale and Multiphysics Computational Techniques = IEEE J. Multiscale and Multiphys. Comput. Techn. IEEE Journal on Selected Areas in Communications = IEEE J. Sel. Areas Commun. -IEEE Latin America Transactions = IEEE Lat. Am. Trans. -IEEE Learning Technology = IEEE Learn. Technol. +IEEE Journal on Technology in Computer Aided Design = IEEE J. Technol. Comput. Aided Design IEEE Life Sciences Letters = IEEE Life Sci. Lett. IEEE Magnetics Letters = IEEE Magn. Lett. -IEEE Micro = IEEE Micro. -IEEE Microwave and Guided Wave Letters = IEEE Microw. Guided. W. -IEEE Microwave and Wireless Components Letters = IEEE Microwave Wireless Compon. Lett. -IEEE Microwave Magazine = IEEE Microwave Mag. -IEEE Multimedia = IEEE Multimedia. -IEEE Nanotechnology Magazine = IEEE Nanatechnol. Mag. -IEEE Network = IEEE Network. -IEEE Parallel & Distributed Technology = IEEE Parall. Distrib. -IEEE Personal Communications = IEEE Pers. Commun. +IEEE Micro = IEEE Micro +IEEE Microwave Magazine = IEEE Microw. Mag. +IEEE Microwave and Guided Wave Letters = IEEE Microw. Guided Wave Lett. +IEEE Microwave and Wireless Components Letters = IEEE Microw. Wireless Compon. Lett. +IEEE Multimedia = IEEE Multimedia +IEEE Nanotechnology Express = IEEE Nanotechnol. Express +IEEE Nanotechnology Magazine = IEEE Nanotechnol. Mag. +IEEE Network = IEEE Netw. +IEEE Personal Communications Magazine = IEEE Personal Commun. Mag. IEEE Pervasive Computing = IEEE Pervasive Comput. -IEEE Photonics Journal = IEEE Photonics J. -IEEE Photonics Technology Letters = IEEE Photonics Technol. Lett. -IEEE Potentials = IEEE Potentials. -IEEE Power and Energy Magazine = IEEE Power Energy Mag. -IEEE Power and Energy Technology Systems Journal = IEEE Power Energy Technol. Syst. J. +IEEE Photonics Journal = IEEE Photon. J. +IEEE Photonics Technology Letters = IEEE Photon. Technol. Lett. +IEEE Potentials = IEEE Potentials IEEE Power Electronics Letters = IEEE Power Electron. Lett. IEEE Power Electronics Magazine = IEEE Power Electron. Mag. IEEE Power Engineering Review = IEEE Power Eng. Rev. +IEEE Power and Energy Magazine = IEEE Power Energy Mag. +IEEE Power and Energy Technology Systems Journal = IEEE Power Energy Technol. Syst. J. IEEE Pulse = IEEE Pulse +IEEE RFIC Journal = IEEE RFIC J. +IEEE RFID Journal = IEEE RFID J. IEEE Reviews in Biomedical Engineering = IEEE Rev. Biomed. Eng. -IEEE RFIC Virtual Journal = IEEE RFIC Virtual J. -IEEE RFID Virtual Journal = IEEE RFID Virtual J. -IEEE Robotics & Automation Magazine = IEEE Robot. Autom. Mag. -IEEE Robotics and Automation Magazine = IEEE Rob. Autom Mag. -IEEE Security & Privacy = IEEE Secur. Priv. -IEEE Security and Privacy = IEEE Secur. Privacy -IEEE Sensors Journal = IEEE Sens. J. -IEEE Signal Processing Letters = IEEE Signal. Proc. Let. -IEEE Signal Processing Magazine = IEEE Signal. Proc. Mag. -IEEE Software = IEEE Software. +IEEE Revista Iberoamericana de Technolog'ias del Aprendizaje = IEEE Revista Iberoamericana de Technolog'ias del Aprendizaje +IEEE Robotics and Automation Letters = IEEE Robot. Autom. Lett. +IEEE Robotics and Automation Magazine = IEEE Robot. Autom. Mag. +IEEE Security and Privacy = IEEE Security Privacy +IEEE Sensors Journal = IEEE Sensors J. +IEEE Signal Processing Letters = IEEE Signal Process. Lett. +IEEE Signal Processing Magazine = IEEE Signal Process. Mag. +IEEE Software = IEEE Softw. IEEE Solid-State Circuits Magazine = IEEE Solid-State Circuits Mag. -IEEE Spectrum = IEEE Spectrum. +IEEE Spectrum = IEEE Spectr. +IEEE Sustainable Computing = IEEE Sustain. Comput. IEEE Systems Journal = IEEE Syst. J. +IEEE Systems, Man, and Cybernetics Magazine = IEEE Syst., Man, Cybern. Mag. IEEE Technology and Society Magazine = IEEE Technol. Soc. Mag. -IEEE Transactions on Acoustics Speech and Signal Processing = IEEE T. Acoust. Speech. -IEEE Transactions on Acoustics, Speech, and Signal Processing = IEEE Trans. Acoust. Speech Signal Process. +IEEE Transactions on Acoustics, Speech, and Signal Processing = IEEE Trans. Acoust., Speech, Signal Process. IEEE Transactions on Advanced Packaging = IEEE Trans. Adv. Packag. -IEEE Transactions on Aerospace = IEEE T. Aerosp. +IEEE Transactions on Aeronautical and Navigational Electronics = IEEE Trans. Aeronaut. Navig. Electron. +IEEE Transactions on Aerospace = IEEE Trans. Aerosp. IEEE Transactions on Aerospace and Electronic Systems = IEEE Trans. Aerosp. Electron. Syst. -IEEE Transactions on Aerospace and Naval Electronics = IEEE T. Aero. Nav. Elec. -IEEE Transactions on Aerospace and Navigation Electronics = IEEE Trans. Aerosp. Navig. Electron. -IEEE Transactions on Aerospace and Navigational Electronics = IEEE Trans. Aerosp. N. -IEEE Transactions on Affective Computing = IEEE Trans. Affective Comput. +IEEE Transactions on Aerospace and Navigational Electronics = IEEE Trans. Aerosp. Navig. Electron. +IEEE Transactions on Affective Computing = IEEE Trans. Affect. Comput. +IEEE Transactions on Airborne Electronics = IEEE Trans. Airborne Electron. IEEE Transactions on Antennas and Propagation = IEEE Trans. Antennas Propag. -IEEE Transactions on Applications and Industry = IEEE Trans. Appl. Indus. +IEEE Transactions on Applications and Industry = IEEE Trans. Appl. Ind. IEEE Transactions on Applied Superconductivity = IEEE Trans. Appl. Supercond. -IEEE Transactions on Audio = IEEE Trans. Audio. +IEEE Transactions on Audio = IEEE Trans. Audio IEEE Transactions on Audio and Electroacoustics = IEEE Trans. Audio Electroacoust. -IEEE Transactions on Audio Speech and Language Processing = IEEE T. Audio. Speech. -IEEE Transactions on Audio, Speech and Language Processing = IEEE Trans. Audio Speech Lang. Process. +IEEE Transactions on Audio, Speech, and Language Processing = IEEE Audio, Speech, Language Process. IEEE Transactions on Automatic Control = IEEE Trans. Autom. Control IEEE Transactions on Automation Science and Engineering = IEEE Trans. Autom. Sci. Eng. -IEEE Transactions on Autonomous Mental Development = IEEE Trans. Auton. Ment. Dev. -IEEE Transactions on Bio-Medical Electronics = IEEE Trans. Bio-med. Electron. +IEEE Transactions on Autonomous Mental Development = IEEE Trans. Auton. Mental Develop. +IEEE Transactions on Big Data = IEEE Trans. Big Data +IEEE Transactions on Bio-Medical Electronics = IEEE Trans. Bio-Med. Electron. +IEEE Transactions on Bio-Medical Engineering = IEEE Trans. Bio-Med. Eng. IEEE Transactions on Biomedical Circuits and Systems = IEEE Trans. Biomed. Circuits Syst. IEEE Transactions on Biomedical Engineering = IEEE Trans. Biomed. Eng. -IEEE Transactions on Broadcast and Television Receivers = IEEE Trans. Broadcast Telev. Receivers +IEEE Transactions on Broadcast and Television Receivers = IEEE Trans. Broadcast Television Receivers IEEE Transactions on Broadcasting = IEEE Trans. Broadcast. -IEEE Transactions on Cable Television = IEEE Trans. Cable Telev. -IEEE Transactions on Circuit Theory = IEEE T. Circuits. Syst. -IEEE Transactions on Circuits and Systems = IEEE T. Circuits. Syst. +IEEE Transactions on Circuit Theory = IEEE Trans. Circuit Theory +IEEE Transactions on Circuits and Systems = IEEE Trans. Circuits Syst. +IEEE Transactions on Circuits and Systems I: Fundamental Theory and Applications = IEEE Trans. Circuits Syst. I +IEEE Transactions on Circuits and Systems I: Regular Papers = IEEE Trans. Circuits Syst. I +IEEE Transactions on Circuits and Systems II: Analog and Digital Signal Processing = IEEE Trans. Circuits Syst. II +IEEE Transactions on Circuits and Systems II: Express Briefs = IEEE Trans. Circuits Syst. II IEEE Transactions on Circuits and Systems for Video Technology = IEEE Trans. Circuits Syst. Video Technol. -IEEE Transactions on Circuits and Systems I-Fundamental Theory and Applications = IEEE T. Circuits-I. -IEEE Transactions on Circuits and Systems I-Regular Papers = IEEE T. Circuits-I. -IEEE Transactions on Circuits and Systems I: Regular Papers = IEEE Trans. Circuits Syst. I Regul. Pap. -IEEE Transactions on Circuits and Systems Ii-Analog and Digital Signal Processing = IEEE T. Circuits-Ii. -IEEE Transactions on Circuits and Systems Ii-Express Briefs = IEEE T. Circuits-Ii. -IEEE Transactions on Circuits and Systems II: Express Briefs = IEEE Trans. Circuits Syst. II Express Briefs -IEEE Transactions on Cloud Computing = IEEE Trans. Cloud Comput. -IEEE Transactions on Communication and Electronics = IEEE T. Commun. Electr. -IEEE Transactions on Communication Technology = IEEE T. Commun. Techn. +IEEE Transactions on Cloud Computing = IEEE Trans. on Cloud Comput. +IEEE Transactions on Cognitive Communications and Networking = IEEE Trans. on Cogn. Commun. Netw. +IEEE Transactions on Cognitive and Developmental Systems = IEEE Trans. Cogn. Develop. Syst. +IEEE Transactions on Communication Technology = IEEE Trans. Commun. Technol. IEEE Transactions on Communications = IEEE Trans. Commun. -IEEE Transactions on Communications Systems = IEEE T. Commun. Syst. -IEEE Transactions on Component Parts = IEEE T. Compon. Parts. +IEEE Transactions on Component Parts = IEEE Trans. Compon. Parts IEEE Transactions on Components and Packaging Technologies = IEEE Trans. Compon. Packag. Technol. -IEEE Transactions on Components Hybrids and Manufacturing Technology = IEEE T. Compon. Hybr. -IEEE Transactions on Components Packaging and Manufacturing Technology Part A = IEEE T. Compon. Pack. A. -IEEE Transactions on Components Packaging and Manufacturing Technology Part B-Advanced Packaging = IEEE T. Compon. Pack. B. +IEEE Transactions on Components and Packaging Technology = IEEE Trans. Compon. Packag. Technol. +IEEE Transactions on Components, Hybrids and Manufacturing Technology = IEEE Trans. Compon., Hybrids, Manuf. Technol. IEEE Transactions on Components, Packaging and Manufacturing Technology = IEEE Trans. Compon. Packag. Manuf. Technol. -IEEE Transactions on Components, Packaging, and Manufacturing Technology, Part A: = IEEE Trans. Compon. Packag. Manuf. Technol. Part A: -IEEE Transactions on Components, Packaging, and Manufacturing Technology, Part B: = IEEE Trans. Compon. Packag. Manuf. Technol. Part B: -IEEE Transactions on Components, Packaging, and Manufacturing Technology, Part C: = IEEE Trans. Compon. Packag. Manuf. Technol. Part C: -IEEE Transactions on Computational Imaging = IEEE Trans. Comput. Imaging -IEEE Transactions on Computational Intelligence and AI in Games = IEEE Trans. Comput. Intell. AI Games +IEEE Transactions on Components, Packaging and Manufacturing Technology A = IEEE Trans. Compon., Packag., Manuf. Technol. A +IEEE Transactions on Components, Packaging and Manufacturing Technology B: Advanced Packaging = IEEE Trans. Compon., Packag., Manuf. Technol. B +IEEE Transactions on Components, Packaging and Manufacturing Technology C: Manufacturing = IEEE Trans. Compon., Packag., Manuf. Technol. C +IEEE Transactions on Computational Intelligence and AI in Games = IEEE Trans. Comput. Intell. AI in Games IEEE Transactions on Computational Social Systems = IEEE Trans. Comput. Social Syst. -IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems = IEEE Trans. Comput. Aided Des. Integr. Circuits Syst. +IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems = IEEE Trans. Comput.-Aided Design Integr. Circuits Syst. IEEE Transactions on Computers = IEEE Trans. Comput. IEEE Transactions on Consumer Electronics = IEEE Trans. Consum. Electron. -IEEE Transactions on Control of Network Systems = IEEE Trans. Control Network Syst. IEEE Transactions on Control Systems Technology = IEEE Trans. Control Syst. Technol. +IEEE Transactions on Control of Network Systems = IEEE Trans. Control Netw. Syst. IEEE Transactions on Cybernetics = IEEE Trans. Cybern. -IEEE Transactions on Dependable and Secure Computing = IEEE Trans. Dependable Secure Comput. -IEEE Transactions on Device and Materials Reliability = IEEE Trans. Device Mater. Reliab. +IEEE Transactions on Dependable and Secure Computing = IEEE Trans. Depend. Sec. Comput. +IEEE Transactions on Device and Materials Reliability = IEEE Trans. Device Mater. Rel. IEEE Transactions on Dielectrics and Electrical Insulation = IEEE Trans. Dielectr. Electr. Insul. IEEE Transactions on Education = IEEE Trans. Educ. -IEEE Transactions on Electrical Insulation = IEEE T. Electr. Insul. +IEEE Transactions on Electrical Insulation = IEEE Trans. Electr. Insul. IEEE Transactions on Electromagnetic Compatibility = IEEE Trans. Electromagn. Compat. IEEE Transactions on Electron Devices = IEEE Trans. Electron Devices -IEEE Transactions on Electronic Computers = IEEE Trans. Electron. +IEEE Transactions on Electronic Computers = IEEE Trans. Electron. Comput. IEEE Transactions on Electronics Packaging Manufacturing = IEEE Trans. Electron. Packag. Manuf. -IEEE Transactions on Emerging Topics in Computing = IEEE Trans. Emerging Top. Comput. +IEEE Transactions on Emerging Topics in Computing = IEEE Trans. Emerg. Topics Comput. +IEEE Transactions on Emerging and Selected Topics in Circuits and Systems = IEEE Trans. Emerg. Sel. Topics Circuits Syst. +IEEE Transactions on Emerging and Selected Topics in Power Electronics = IEEE Trans. Emerg. Sel. Topics Power Electron. IEEE Transactions on Energy Conversion = IEEE Trans. Energy Convers. -IEEE Transactions on Engineering Management = IEEE Trans. Eng. Manage. -IEEE Transactions on Engineering Writing and Speech = IEEE T. Prof. Commun. +IEEE Transactions on Engineering Management = IEEE Trans. Eng. Manag. +IEEE Transactions on Engineering Writing and Speech = IEEE Trans. Eng. Writing Speech IEEE Transactions on Evolutionary Computation = IEEE Trans. Evol. Comput. IEEE Transactions on Fuzzy Systems = IEEE Trans. Fuzzy Syst. +IEEE Transactions on Geoscience Electronics = IEEE Trans. Geosci. Electron. IEEE Transactions on Geoscience and Remote Sensing = IEEE Trans. Geosci. Remote Sens. -IEEE Transactions on Geoscience Electronics = IEEE T. Geosci. Elect. -IEEE Transactions on Haptics = IEEE Trans. Haptic -IEEE Transactions on Human Factors in Electronics = IEEE Trans. Hum. Fact. -IEEE Transactions on Human Factors in Engineering = IEEE T. Hum. Fact. Eng. -IEEE Transactions on Human-Machine Systems = IEEE Trans. Hum.-Mach. Syst. +IEEE Transactions on Haptics = IEEE Trans. Haptics +IEEE Transactions on Human Factors in Electronics = IEEE Trans. Hum. Factors Electron. +IEEE Transactions on Human-Machine Systems = IEEE Trans. Human-Mach. Syst. IEEE Transactions on Image Processing = IEEE Trans. Image Process. IEEE Transactions on Industrial Electronics = IEEE Trans. Ind. Electron. -IEEE Transactions on Industrial Electronics and Control Instrumentation = IEEE T. Ind. El. Con. In. -IEEE Transactions on Industrial Informatics = IEEE Trans. Ind. Inf. -IEEE Transactions on Industry and General Applications = IEEE Trans. Ind. Gen. A. +IEEE Transactions on Industrial Electronics and Control Instrumentation = IEEE Trans. Ind. Electron. Contr. Instrum. +IEEE Transactions on Industrial Informatics = IEEE Trans. Ind. Informat. IEEE Transactions on Industry Applications = IEEE Trans. Ind. Appl. -IEEE Transactions on Information Forensics and Security = IEEE Trans. Inf. Forensics Secur. +IEEE Transactions on Industry and General Applications = IEEE Trans. Ind. Gen. Appl. +IEEE Transactions on Information Forensics and Security = IEEE Trans. Inf. Forensics Security IEEE Transactions on Information Technology in Biomedicine = IEEE Trans. Inf. Technol. Biomed. IEEE Transactions on Information Theory = IEEE Trans. Inf. Theory IEEE Transactions on Instrumentation and Measurement = IEEE Trans. Instrum. Meas. IEEE Transactions on Intelligent Transportation Systems = IEEE Trans. Intell. Transp. Syst. +IEEE Transactions on Intelligent Vehicles = IEEE Trans. Intell. Veh. IEEE Transactions on Knowledge and Data Engineering = IEEE Trans. Knowl. Data Eng. IEEE Transactions on Learning Technologies = IEEE Trans. Learn. Technol. IEEE Transactions on Magnetics = IEEE Trans. Magn. -IEEE Transactions on Man-Machine Systems = IEEE T. Man. Machine. -IEEE Transactions on Manufacturing Technology = IEEE T. Manuf. Tech. -IEEE Transactions on Medical Imaging = IEEE Trans. Med. Imaging -IEEE Transactions on Microwave Theory and Techniques = IEEE Trans. Microwave Theory Tech. -IEEE Transactions on Military Electronics = IEEE T. Mil. Electron. -IEEE Transactions on Mobile Computing = IEEE Trans. Mob. Comput. +IEEE Transactions on Man-Machine Systems = IEEE Trans. Man-Mach. Syst. +IEEE Transactions on Manufacturing Technology = IEEE Trans. Manuf. Technol. +IEEE Transactions on Medical Electronics = IEEE Trans. Med. Electron. +IEEE Transactions on Medical Imaging = IEEE Trans. Med. Imag. +IEEE Transactions on Microwave Theory and Techniques = IEEE Trans. Microw. Theory Techn. +IEEE Transactions on Military Electronics = IEEE Trans. Mil. Electron. +IEEE Transactions on Mobile Computing = IEEE Trans. Mobile Comput. +IEEE Transactions on Molecular, Biological and Multi-Scale Communications = IEEE Trans. Mol. Biol. Multi-Scale Commun. +IEEE Transactions on Multi-Scale Computing Systems = IEEE Trans. Multi-Scale Comput. Syst. IEEE Transactions on Multimedia = IEEE Trans. Multimedia -IEEE Transactions on Nanobioscience = IEEE Trans. Nanobioscience +IEEE Transactions on NanoBioscience = IEEE Trans. Nanobiosci. IEEE Transactions on Nanotechnology = IEEE Trans. Nanotechnol. -IEEE Transactions on Network and Service Management = IEEE Trans. Netw. Serv. Manage. -IEEE Transactions on Network Science and Engineering = IEEE Trans. Network Sci. Eng. -IEEE Transactions on Neural Networks = IEEE Trans. Neural Networks -IEEE Transactions on Neural Networks and Learning Systems = IEEE Trans. Neural Networks Learn. Syst. +IEEE Transactions on Network Science and Engineering = IEEE Trans. Netw. Sci. Eng. +IEEE Transactions on Network and Service Management = IEEE Trans. Netw. Service Manag. +IEEE Transactions on Neural Networks = IEEE Trans. Neural Netw. +IEEE Transactions on Neural Networks and Learning Systems = IEEE Trans. Neural Netw. Learn. Syst. IEEE Transactions on Neural Systems and Rehabilitation Engineering = IEEE Trans. Neural Syst. Rehabil. Eng. IEEE Transactions on Nuclear Science = IEEE Trans. Nucl. Sci. IEEE Transactions on Parallel and Distributed Systems = IEEE Trans. Parallel Distrib. Syst. -IEEE Transactions on Parts Hybrids and Packaging = IEEE T. Parts. Hyb. Pac. -IEEE Transactions on Parts Materials and Packaging = IEEE Tr. Parts. Mater. +IEEE Transactions on Parts, Hybrids and Packaging = IEEE Trans. Parts, Hybrids, Packag. +IEEE Transactions on Parts, Materials and Packaging = IEEE Trans. Parts, Mater., Packag. IEEE Transactions on Pattern Analysis and Machine Intelligence = IEEE Trans. Pattern Anal. Mach. Intell. IEEE Transactions on Plasma Science = IEEE Trans. Plasma Sci. -IEEE Transactions on Power Apparatus and Systems = IEEE T. Power. Ap. Syst. -IEEE Transactions on Power Delivery = IEEE Trans. Power Delivery +IEEE Transactions on Power Apparatus and Systems = IEEE Trans. Power App. Syst. +IEEE Transactions on Power Delivery = IEEE Trans. Power Del. IEEE Transactions on Power Electronics = IEEE Trans. Power Electron. IEEE Transactions on Power Systems = IEEE Trans. Power Syst. -IEEE Transactions on Product Engineering and Production = IEEE T. Prod. Eng. Prod. IEEE Transactions on Professional Communication = IEEE Trans. Prof. Commun. +IEEE Transactions on Radio Frequency Interference = IEEE Trans. Radio Freq. Interference IEEE Transactions on Rehabilitation Engineering = IEEE Trans. Rehabil. Eng. -IEEE Transactions on Reliability = IEEE Trans. Reliab. -IEEE Transactions on Robotics = IEEE Trans. Rob. -IEEE Transactions on Robotics and Automation = IEEE T. Robotic. Autom. +IEEE Transactions on Reliability = IEEE Trans. Rel. +IEEE Transactions on Robotics = IEEE Trans. Robot. +IEEE Transactions on Robotics and Automation = IEEE Trans. Robot. Autom. IEEE Transactions on Semiconductor Manufacturing = IEEE Trans. Semicond. Manuf. IEEE Transactions on Services Computing = IEEE Trans. Serv. Comput. IEEE Transactions on Signal Processing = IEEE Trans. Signal Process. +IEEE Transactions on Signal and Information Processing over Networks = IEEE Trans. Signal Inf. Process. Netw. IEEE Transactions on Smart Grid = IEEE Trans. Smart Grid -IEEE Transactions on Software Engineering = IEEE Trans. Software Eng. -IEEE Transactions on Sonics and Ultrasonics = IEEE T. Son. Ultrason. -IEEE Transactions on Space Electronics and Telemetry = IEEE Trans. Space Electron. Telem. -IEEE Transactions on Speech and Audio Processing = IEEE T. Speech. Audi. P. -IEEE Transactions on Sustainable Energy = IEEE Trans. Sustainable Energy -IEEE Transactions on Systems Man and Cybernetics = IEEE T. Syst. Man. Cyb. -IEEE Transactions on Systems Man and Cybernetics Part A-Systems and Humans = IEEE T. Syst. Man. Cy. A. -IEEE Transactions on Systems Man and Cybernetics Part B-Cybernetics = IEEE T. Syst. Man. Cy. B. -IEEE Transactions on Systems Man and Cybernetics Part C-Applications and Reviews = IEEE T. Syst. Man. Cy. C. -IEEE Transactions on Systems Science and Cybernetics = IEEE T. Syst. Sci. Cyb. -IEEE Transactions on Systems, Man and Cybernetics = IEEE Trans. Syst. Man Cybern. -IEEE Transactions on Systems, Man, and Cybernetics Part A: Systems and Humans = IEEE Trans. Syst. Man Cybern. Part A Syst. Humans -IEEE Transactions on Systems, Man, and Cybernetics Part B: Cybernetics = IEEE Trans. Syst. Man Cybern. Part B Cybern. -IEEE Transactions on Systems, Man, and Cybernetics Part C: Applications and Reviews = IEEE Trans. Syst. Man Cybern. Part C Appl. Rev. -IEEE Transactions on Terahertz Science and Technology = IEEE Trans. Terahertz Sci. Technol. -IEEE Transactions on Ultrasonics Ferroelectrics and Frequency Control = IEEE T. Ultrason. Ferr. -IEEE Transactions on Ultrasonics, Ferroelectrics, and Frequency Control = IEEE Trans. Ultrason. Ferroelectr. Freq. Control -IEEE Transactions on Vehicular Communications = IEEE T. Veh. Commun. +IEEE Transactions on Software Engineering = IEEE Trans. Softw. Eng. +IEEE Transactions on Sonics and Ultrasonics = IEEE Trans. Sonics Ultrason. +IEEE Transactions on Speech and Audio Processing = IEEE Trans. Speech Audio Process. +IEEE Transactions on Sustainable Energy = IEEE Trans. Sustain. Energy +IEEE Transactions on Systems Science and Cybernetics = IEEE Trans. Syst. Sci. Cybern. +IEEE Transactions on Systems, Man, and Cybernetics = IEEE Trans. Syst., Man, Cybern. +IEEE Transactions on Systems, Man, and Cybernetics A: Systems and Humans = IEEE Trans. Syst., Man, Cybern. A +IEEE Transactions on Systems, Man, and Cybernetics B: Cybernetics = IEEE Trans. Syst., Man, Cybern. B +IEEE Transactions on Systems, Man, and Cybernetics C: Applications and Reviews = IEEE Trans. Syst., Man, Cybern. C +IEEE Transactions on Systems, Man, and Cybernetics: Systems = IEEE Trans. Syst., Man, Cybern., Syst. +IEEE Transactions on Terahertz Science and Technology = IEEE Trans. THz Sci. Technol. +IEEE Transactions on Transportation Electrification = IEEE Trans. Transport. Electrific. +IEEE Transactions on Ultrasonics Engineering = IEEE Trans. Ultrason. Eng. +IEEE Transactions on Ultrasonics, Ferroelectrics, and Frequency Control = IEEE Trans. Ultrason., Ferroelectr., Freq. Control +IEEE Transactions on Vehicular Communications = IEEE Trans. Veh. Commun. IEEE Transactions on Vehicular Technology = IEEE Trans. Veh. Technol. -IEEE Transactions on Very Large Scale Integration (VLSI) Systems = IEEE Trans. Very Large Scale Integr. VLSI Syst. -IEEE Transactions on Very Large Scale Integration Vlsi Systems = IEEE T. Vlsi. Syst. -IEEE Transactions on Visualization and Computer Graphics = IEEE Trans. Visual Comput. Graphics +IEEE Transactions on Very Large Scale Integration (VLSI) Systems = IEEE Trans. VLSI Syst. +IEEE Transactions on Visualization and Computer Graphics = IEEE Trans. Vis. Comput. Graphics IEEE Transactions on Wireless Communications = IEEE Trans. Wireless Commun. IEEE Translation Journal on Magnetics in Japan = IEEE Transl. J. Magn. Jpn. -IEEE Vehicular Technology Group-Annual Conference = IEEE Veh. Technol. Gr. IEEE Vehicular Technology Magazine = IEEE Veh. Technol. Mag. IEEE Wireless Communications = IEEE Wireless Commun. IEEE Wireless Communications Letters = IEEE Wireless Commun. Lett. -IEEE Women in Engineering Magazine = IEEE Women Eng. Mag. -IEEE-ACM Transactions on Computational Biology and Bioinformatics = IEEE-ACM T. Comput. Bi. -IEEE-ACM Transactions on Computational Biology and Bioinformatiocs = IEEE-ACM T. Comput. Bi. -IEEE-ACM Transactions on Networking = IEEE ACM T. Network. -IEEE-ASMETransactions on Mechatronics = IEEE-ASME T. Mech. -IEEE/ACM Transactions on Audio, Speech and Language Processing = IEEE/ACM Trans. Audio Speech Lang. Process. -IEEE/ACM Transactions on Computational Biology and Bioinformatics = IEEE/ACM Trans. Comput. Biol. Bioinform. -IEEE/ACM Transactions on Networking = IEEE/ACM Trans. Networking -IEEE/ASME Transactions on Mechatronics = IEEE/ASME Trans. Mechatron. -IEEE/CAA Journal of Automatica Sinica = IEEE/CAA J. Autom. Sin. -IEEE/OSA Journal of Display Technology = IEEE/OSA J. Disp. Technol. -IEEE/OSA Journal of Optical Communications and Networking = IEEE/OSA J. Opt. Commun. Networking -Journal of Lightwave Technology = J. Lightwave Technol. -Journal of Microelectromechanical Systems = J. Microelectromech. Syst. +IEEE/ACM Transactions on Audio, Speech, and Language Processing = IEEE/ACM Trans. Audio, Speech, Language Process. +IEEE/ACM Transactions on Computational Biology and Bioinformatics = IEEE/ACM Trans. Comput. Biol. Bioinformatics +IEEE/ACM Transactions on Networking = IEEE/ACM Trans. Netw. +IEEE/ASME Journal of Microelectromechanical Systems = J. Microelectromech. Syst. +IEEE/ASME Transactions on Mechatronics = IEEE/ASME Trans. Mechatronics +IEEE/CAA Journal of Automatica Sinica = IEEE/CAA J. Autom. Sinica +IEEE/ECS Electrochemical and Solid-State Letters = IEEE/ECS Electrochem. Solid-State Lett. +IEEE/OSA Journal of Display Technology = IEEE/OSA J. Display Technol. +IEEE/OSA Journal of Lightwave Technology = J. Lightw. Technol. +IEEE/TMS Journal of Electronic Materials = IEEE/TMS J. Electron. Mater. Proceedings of the IEEE = Proc. IEEE +Today's Engineer = Today's Engineer diff --git a/src/main/resources/journals/journalList.txt b/src/main/resources/journals/journalList.txt index 1a7a8e17d61..26fa5ac15e2 100644 --- a/src/main/resources/journals/journalList.txt +++ b/src/main/resources/journals/journalList.txt @@ -3211,7 +3211,6 @@ Chimica e l'Industria = Chim. Ind. Chimica Oggi = Chim. Oggi Chimie et Industrie, Genie Chimique = Chim. Ind. Genie Chim. Chimie Nouvelle = Chim. Nouv. -China Communications = China Commun. China's Medicine = Chinas Med. Chinese Astronomy and Astrophysics = Chin. Astron. Astrophy Chinese Chemical Letters = Chin. Chem. Lett. diff --git a/src/test/java/org/jabref/logic/importer/fetcher/ArXivTest.java b/src/test/java/org/jabref/logic/importer/fetcher/ArXivTest.java index e43528c4537..47af5898eea 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/ArXivTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/ArXivTest.java @@ -9,6 +9,7 @@ import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BiblatexEntryTypes; +import org.jabref.model.entry.FieldName; import org.jabref.testutils.category.FetcherTests; import org.junit.Assert; @@ -51,7 +52,7 @@ public void setUp() { } @Test - public void doiNotPresent() throws IOException { + public void noIdentifierPresent() throws IOException { assertEquals(Optional.empty(), finder.findFullText(entry)); } @@ -63,7 +64,8 @@ public void rejectNullParameter() throws IOException { @Test public void findByDOI() throws IOException { - entry.setField("doi", "10.1529/biophysj.104.047340"); + entry.setField(FieldName.DOI, "10.1529/biophysj.104.047340"); + entry.setField(FieldName.TITLE, "Pause Point Spectra in DNA Constant-Force Unzipping"); assertEquals(Optional.of(new URL("http://arxiv.org/pdf/cond-mat/0406246v1")), finder.findFullText(entry)); } @@ -103,6 +105,15 @@ public void notFoundByUnknownId() throws IOException { assertEquals(Optional.empty(), finder.findFullText(entry)); } + @Test + public void findByDOINotAvailableInCatalog() throws IOException { + entry.setField(FieldName.DOI, "10.1016/0370-2693(77)90015-6"); + entry.setField(FieldName.TITLE, "Superspace formulation of supergravity"); + + + assertEquals(Optional.empty(), finder.findFullText(entry)); + } + @Test public void searchEntryByPartOfTitle() throws Exception { assertEquals(Collections.singletonList(sliceTheoremPaper), diff --git a/src/test/java/org/jabref/logic/importer/fetcher/ScienceDirectTest.java b/src/test/java/org/jabref/logic/importer/fetcher/ScienceDirectTest.java index 56d8e9a114f..b2202167687 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/ScienceDirectTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/ScienceDirectTest.java @@ -38,7 +38,7 @@ public void doiNotPresent() throws IOException { } @Test - public void findByDOI() throws IOException { + public void findByDOIOldPage() throws IOException { // CI server is blocked Assume.assumeFalse(DevEnvironment.isCIServer()); @@ -50,6 +50,19 @@ public void findByDOI() throws IOException { ); } + @Test + public void findByDOINewPage() throws IOException { + // CI server is blocked + Assume.assumeFalse(DevEnvironment.isCIServer()); + + entry.setField("doi", "10.1016/j.aasri.2014.09.002"); + + Assert.assertEquals( + Optional.of(new URL("http://www.sciencedirect.com/science/article/pii/S2212671614001024/pdf?md5=4e2e9a369b4d5b3db5100aba599bef8b&pid=1-s2.0-S2212671614001024-main.pdf")), + finder.findFullText(entry) + ); + } + @Test public void notFoundByDOI() throws IOException { // CI server is blocked diff --git a/src/test/java/org/jabref/logic/l10n/LocalizationConsistencyTest.java b/src/test/java/org/jabref/logic/l10n/LocalizationConsistencyTest.java index 8f066201e03..52bdb1e755b 100644 --- a/src/test/java/org/jabref/logic/l10n/LocalizationConsistencyTest.java +++ b/src/test/java/org/jabref/logic/l10n/LocalizationConsistencyTest.java @@ -16,6 +16,7 @@ import org.junit.Test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class LocalizationConsistencyTest { @@ -168,4 +169,23 @@ public void findObsoleteMenuLocalizationKeys() throws IOException { Collections.emptySet(), obsoleteKeys); } + @Test + public void localizationParameterMustIncludeAString() throws IOException { + // Must start or end with " + // Localization.lang("test"), Localization.lang("test" + var), Localization.lang(var + "test") + // TODO: Localization.lang(var1 + "test" + var2) not covered + // Localization.lang("Problem downloading from %1", address) + Set keys = LocalizationParser.findLocalizationParametersStringsInJavaFiles(LocalizationBundleForTest.LANG); + for(LocalizationEntry e : keys) { + assertTrue("Illegal localization parameter found. Must include a String with potential concatenation or replacement parameters. Illegal parameter: Localization.lang(" + e.getKey(), + e.getKey().startsWith("\"") || e.getKey().endsWith("\"")); + } + + keys = LocalizationParser.findLocalizationParametersStringsInJavaFiles(LocalizationBundleForTest.MENU); + for(LocalizationEntry e : keys) { + assertTrue("Illegal localization parameter found. Must include a String with potential concatenation or replacement parameters. Illegal parameter: Localization.lang(" + e.getKey(), + e.getKey().startsWith("\"") || e.getKey().endsWith("\"")); + } + } + } diff --git a/src/test/java/org/jabref/logic/l10n/LocalizationParser.java b/src/test/java/org/jabref/logic/l10n/LocalizationParser.java index 428fe8c129c..a02bee4d0eb 100644 --- a/src/test/java/org/jabref/logic/l10n/LocalizationParser.java +++ b/src/test/java/org/jabref/logic/l10n/LocalizationParser.java @@ -75,6 +75,14 @@ private static Set findLocalizationEntriesInFiles(Localizatio } } + public static Set findLocalizationParametersStringsInJavaFiles(LocalizationBundleForTest type) + throws IOException { + return Files.walk(Paths.get("src/main")) + .filter(LocalizationParser::isJavaFile) + .flatMap(path -> getLocalizationParametersInJavaFile(path, type).stream()) + .collect(Collectors.toSet()); + } + private static Set findLocalizationEntriesInJavaFiles(LocalizationBundleForTest type) throws IOException { return Files.walk(Paths.get("src/main")) @@ -141,6 +149,26 @@ private static List getLanguageKeysInJavaFile(Path path, Loca return result; } + private static List getLocalizationParametersInJavaFile(Path path, LocalizationBundleForTest type) { + List result = new LinkedList<>(); + + try { + List lines = Files.readAllLines(path, StandardCharsets.UTF_8); + String content = String.join("\n", lines); + + List keys = JavaLocalizationEntryParser.getLocalizationParameter(content, type); + + for (String key : keys) { + result.add(new LocalizationEntry(path, key, type)); + } + + } catch (IOException ignore) { + ignore.printStackTrace(); + } + + return result; + } + /** * Loads the fxml file and returns all used language resources. */ @@ -192,31 +220,13 @@ static class JavaLocalizationEntryParser { private static final Pattern QUOTATION_SYMBOL = Pattern.compile("QUOTATIONPLACEHOLDER"); public static List getLanguageKeysInString(String content, LocalizationBundleForTest type) { + List parameters = getLocalizationParameter(content, type); + List result = new LinkedList<>(); - Matcher matcher; - if (type == LocalizationBundleForTest.LANG) { - matcher = LOCALIZATION_START_PATTERN.matcher(content); - } else { - matcher = LOCALIZATION_MENU_START_PATTERN.matcher(content); - } - while (matcher.find()) { - // find contents between the brackets, covering multi-line strings as well - int index = matcher.end(); - int brackets = 1; - StringBuilder buffer = new StringBuilder(); - while (brackets != 0) { - char c = content.charAt(index); - if (c == '(') { - brackets++; - } else if (c == ')') { - brackets--; - } - buffer.append(c); - index++; - } + for (String param : parameters) { - String parsedContentsOfLangMethod = ESCAPED_QUOTATION_SYMBOL.matcher(buffer.toString()).replaceAll("QUOTATIONPLACEHOLDER"); + String parsedContentsOfLangMethod = ESCAPED_QUOTATION_SYMBOL.matcher(param).replaceAll("QUOTATIONPLACEHOLDER"); // only retain what is within quotation StringBuilder b = new StringBuilder(); @@ -259,6 +269,39 @@ public static List getLanguageKeysInString(String content, LocalizationB return result; } + public static List getLocalizationParameter(String content, LocalizationBundleForTest type) { + List result = new LinkedList<>(); + + Matcher matcher; + if (type == LocalizationBundleForTest.LANG) { + matcher = LOCALIZATION_START_PATTERN.matcher(content); + } else { + matcher = LOCALIZATION_MENU_START_PATTERN.matcher(content); + } + while (matcher.find()) { + // find contents between the brackets, covering multi-line strings as well + int index = matcher.end(); + int brackets = 1; + StringBuilder buffer = new StringBuilder(); + while (brackets != 0) { + char c = content.charAt(index); + if (c == '(') { + brackets++; + } else if (c == ')') { + brackets--; + } + // skip closing brackets + if (brackets != 0) { + buffer.append(c); + } + index++; + } + // trim newlines and whitespace + result.add(buffer.toString().trim()); + } + + return result; + } } } diff --git a/src/test/java/org/jabref/logic/l10n/LocalizationParserTest.java b/src/test/java/org/jabref/logic/l10n/LocalizationParserTest.java index 54b6e6bdc27..dd781a9599b 100644 --- a/src/test/java/org/jabref/logic/l10n/LocalizationParserTest.java +++ b/src/test/java/org/jabref/logic/l10n/LocalizationParserTest.java @@ -11,27 +11,44 @@ public class LocalizationParserTest { @Test - public void testParsingCode() { - assertLocalizationParsing("Localization.lang(\"one per line\")", "one_per_line"); - assertLocalizationParsing("Localization.lang(\n \"Copy \\\\cite{BibTeX key}\")", "Copy_\\cite{BibTeX_key}"); - assertLocalizationParsing("Localization.lang(\"two per line\") Localization.lang(\"two per line\")", Arrays.asList("two_per_line", "two_per_line")); - assertLocalizationParsing("Localization.lang(\"multi \" + \n\"line\")", "multi_line"); - assertLocalizationParsing("Localization.lang(\"one per line with var\", var)", "one_per_line_with_var"); - assertLocalizationParsing("Localization.lang(\"Search %0\", \"Springer\")", "Search_%0"); - assertLocalizationParsing("Localization.lang(\"Reset preferences (key1,key2,... or 'all')\")", "Reset_preferences_(key1,key2,..._or_'all')"); - assertLocalizationParsing("Localization.lang(\"Multiple entries selected. Do you want to change the type of all these to '%0'?\")", + public void testKeyParsingCode() { + assertLocalizationKeyParsing("Localization.lang(\"one per line\")", "one_per_line"); + assertLocalizationKeyParsing("Localization.lang(\n \"Copy \\\\cite{BibTeX key}\")", "Copy_\\cite{BibTeX_key}"); + assertLocalizationKeyParsing("Localization.lang(\"two per line\") Localization.lang(\"two per line\")", Arrays.asList("two_per_line", "two_per_line")); + assertLocalizationKeyParsing("Localization.lang(\"multi \" + \n\"line\")", "multi_line"); + assertLocalizationKeyParsing("Localization.lang(\"one per line with var\", var)", "one_per_line_with_var"); + assertLocalizationKeyParsing("Localization.lang(\"Search %0\", \"Springer\")", "Search_%0"); + assertLocalizationKeyParsing("Localization.lang(\"Reset preferences (key1,key2,... or 'all')\")", "Reset_preferences_(key1,key2,..._or_'all')"); + assertLocalizationKeyParsing("Localization.lang(\"Multiple entries selected. Do you want to change the type of all these to '%0'?\")", "Multiple_entries_selected._Do_you_want_to_change_the_type_of_all_these_to_'%0'?"); - assertLocalizationParsing("Localization.lang(\"Run fetcher, e.g. \\\"--fetch=Medline:cancer\\\"\");", + assertLocalizationKeyParsing("Localization.lang(\"Run fetcher, e.g. \\\"--fetch=Medline:cancer\\\"\");", "Run_fetcher,_e.g._\"--fetch\\=Medline\\:cancer\""); } - private void assertLocalizationParsing(String code, String expectedLanguageKeys) { - assertLocalizationParsing(code, Collections.singletonList(expectedLanguageKeys)); + @Test + public void testParameterParsingCode() { + assertLocalizationParameterParsing("Localization.lang(\"one per line\")", "\"one per line\""); + assertLocalizationParameterParsing("Localization.lang(\"one per line\" + var)", "\"one per line\" + var"); + assertLocalizationParameterParsing("Localization.lang(var + \"one per line\")", "var + \"one per line\""); + assertLocalizationParameterParsing("Localization.lang(\"Search %0\", \"Springer\")", "\"Search %0\", \"Springer\""); + } + + private void assertLocalizationKeyParsing(String code, String expectedLanguageKeys) { + assertLocalizationKeyParsing(code, Collections.singletonList(expectedLanguageKeys)); } - private void assertLocalizationParsing(String code, List expectedLanguageKeys) { + private void assertLocalizationKeyParsing(String code, List expectedLanguageKeys) { List languageKeysInString = LocalizationParser.JavaLocalizationEntryParser.getLanguageKeysInString(code, LocalizationBundleForTest.LANG); assertEquals(expectedLanguageKeys, languageKeysInString); } + private void assertLocalizationParameterParsing(String code, List expectedParameter) { + List languageKeysInString = LocalizationParser.JavaLocalizationEntryParser.getLocalizationParameter(code, LocalizationBundleForTest.LANG); + assertEquals(expectedParameter, languageKeysInString); + } + + private void assertLocalizationParameterParsing(String code, String expectedParameter) { + assertLocalizationParameterParsing(code, Collections.singletonList(expectedParameter)); + } + } diff --git a/src/test/java/org/jabref/logic/specialfields/SpecialFieldsUtilsTest.java b/src/test/java/org/jabref/logic/specialfields/SpecialFieldsUtilsTest.java index d99c1e0219e..26ea98db537 100644 --- a/src/test/java/org/jabref/logic/specialfields/SpecialFieldsUtilsTest.java +++ b/src/test/java/org/jabref/logic/specialfields/SpecialFieldsUtilsTest.java @@ -19,7 +19,7 @@ public class SpecialFieldsUtilsTest { public void syncKeywordsFromSpecialFieldsWritesToKeywords() { BibEntry entry = new BibEntry(); entry.setField("ranking", "rank2"); - SpecialFieldsUtils.syncKeywordsFromSpecialFields(entry, true, ','); + SpecialFieldsUtils.syncKeywordsFromSpecialFields(entry, ','); assertEquals(Optional.of("rank2"), entry.getField("keywords")); } @@ -27,7 +27,7 @@ public void syncKeywordsFromSpecialFieldsWritesToKeywords() { public void syncKeywordsFromSpecialFieldsCausesChange() { BibEntry entry = new BibEntry(); entry.setField("ranking", "rank2"); - List changes = SpecialFieldsUtils.syncKeywordsFromSpecialFields(entry, true, ','); + List changes = SpecialFieldsUtils.syncKeywordsFromSpecialFields(entry, ','); assertTrue(changes.size() > 0); } @@ -36,14 +36,14 @@ public void syncKeywordsFromSpecialFieldsOverwritesKeywords() { BibEntry entry = new BibEntry(); entry.setField("ranking", "rank2"); entry.setField("keywords", "rank3"); - SpecialFieldsUtils.syncKeywordsFromSpecialFields(entry, true, ','); + SpecialFieldsUtils.syncKeywordsFromSpecialFields(entry, ','); assertEquals(Optional.of("rank2"), entry.getField("keywords")); } @Test public void syncKeywordsFromSpecialFieldsForEmptyFieldCausesNoChange() { BibEntry entry = new BibEntry(); - List changes = SpecialFieldsUtils.syncKeywordsFromSpecialFields(entry, true, ','); + List changes = SpecialFieldsUtils.syncKeywordsFromSpecialFields(entry, ','); assertFalse(changes.size() > 0); }