From c7e54ccc64edb5af2e33696d5697f67febd927ac Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sun, 20 Dec 2015 15:46:44 +0100 Subject: [PATCH] Refactor cleanup code --- .../java/net/sf/jabref/JabRefPreferences.java | 92 ++++- .../java/net/sf/jabref/gui/BasePanel.java | 4 +- .../net/sf/jabref/gui/CleanupPresetPanel.java | 143 +++++++ .../sf/jabref/gui/actions/CleanUpAction.java | 348 ++---------------- .../jabref/gui/actions/FileEntryCleaner.java | 50 --- .../gui/actions/RelativePathsCleanup.java | 59 --- .../jabref/gui/actions/RenamePdfCleanup.java | 119 ------ .../java/net/sf/jabref/logic/FieldChange.java | 54 +++ .../cleanup}/BiblatexCleanup.java | 34 +- .../net/sf/jabref/logic/cleanup/Cleaner.java | 15 - .../sf/jabref/logic/cleanup/CleanupJob.java | 29 ++ .../jabref/logic/cleanup/CleanupPreset.java | 210 +++++++++++ .../jabref/logic/cleanup/CleanupWorker.java | 115 ++++++ .../sf/jabref/logic/cleanup/DoiCleanup.java | 16 +- .../logic/cleanup/FieldFormatterCleanup.java | 34 +- .../logic/cleanup/FileLinksCleanup.java | 31 ++ .../logic/cleanup/FormatterCleanup.java | 16 +- .../logic/cleanup/RelativePathsCleanup.java | 37 ++ .../logic/cleanup/RemoveFieldCleanup.java | 20 +- .../logic/cleanup/RenamePdfCleanup.java | 45 +++ .../cleanup}/UnicodeCleanup.java | 19 +- .../cleanup/UpgradePdfPsToFileCleanup.java | 40 ++ .../logic/preferences/PreferenceStorage.java | 11 + .../migrations/FileLinksUpgradeWarning.java | 5 +- .../java/net/sf/jabref/util/CleanupUtil.java | 235 ++++++++++++ src/main/java/net/sf/jabref/util/Util.java | 59 +-- .../logic/cleanup/CleanupWorkerTest.java | 272 ++++++++++++++ 27 files changed, 1459 insertions(+), 653 deletions(-) create mode 100644 src/main/java/net/sf/jabref/gui/CleanupPresetPanel.java delete mode 100644 src/main/java/net/sf/jabref/gui/actions/FileEntryCleaner.java delete mode 100644 src/main/java/net/sf/jabref/gui/actions/RelativePathsCleanup.java delete mode 100644 src/main/java/net/sf/jabref/gui/actions/RenamePdfCleanup.java rename src/main/java/net/sf/jabref/{gui/actions => logic/cleanup}/BiblatexCleanup.java (54%) delete mode 100644 src/main/java/net/sf/jabref/logic/cleanup/Cleaner.java create mode 100644 src/main/java/net/sf/jabref/logic/cleanup/CleanupJob.java create mode 100644 src/main/java/net/sf/jabref/logic/cleanup/CleanupPreset.java create mode 100644 src/main/java/net/sf/jabref/logic/cleanup/CleanupWorker.java create mode 100644 src/main/java/net/sf/jabref/logic/cleanup/FileLinksCleanup.java create mode 100644 src/main/java/net/sf/jabref/logic/cleanup/RelativePathsCleanup.java create mode 100644 src/main/java/net/sf/jabref/logic/cleanup/RenamePdfCleanup.java rename src/main/java/net/sf/jabref/{gui/actions => logic/cleanup}/UnicodeCleanup.java (52%) create mode 100644 src/main/java/net/sf/jabref/logic/cleanup/UpgradePdfPsToFileCleanup.java create mode 100644 src/main/java/net/sf/jabref/logic/preferences/PreferenceStorage.java create mode 100644 src/main/java/net/sf/jabref/util/CleanupUtil.java create mode 100644 src/test/java/net/sf/jabref/logic/cleanup/CleanupWorkerTest.java diff --git a/src/main/java/net/sf/jabref/JabRefPreferences.java b/src/main/java/net/sf/jabref/JabRefPreferences.java index 8c41232faea..42094259115 100644 --- a/src/main/java/net/sf/jabref/JabRefPreferences.java +++ b/src/main/java/net/sf/jabref/JabRefPreferences.java @@ -36,14 +36,15 @@ import javax.swing.*; import net.sf.jabref.gui.*; -import net.sf.jabref.gui.actions.CleanUpAction; import net.sf.jabref.gui.entryeditor.EntryEditorTabList; import net.sf.jabref.gui.maintable.PersistenceTableColumnListener; import net.sf.jabref.gui.preftabs.ImportSettingsTab; import net.sf.jabref.importer.fileformat.ImportFormat; import net.sf.jabref.logic.autocompleter.AutoCompletePreferences; +import net.sf.jabref.logic.cleanup.CleanupPreset; import net.sf.jabref.logic.l10n.Localization; import net.sf.jabref.logic.labelPattern.GlobalLabelPattern; +import net.sf.jabref.logic.preferences.PreferenceStorage; import net.sf.jabref.logic.util.OS; import net.sf.jabref.model.entry.EntryUtil; import net.sf.jabref.model.entry.CustomEntryType; @@ -60,7 +61,7 @@ import net.sf.jabref.specialfields.SpecialFieldsUtils; import net.sf.jabref.logic.util.strings.StringUtil; -public class JabRefPreferences { +public class JabRefPreferences implements PreferenceStorage { private static final Log LOGGER = LogFactory.getLog(JabRefPreferences.class); /** @@ -317,6 +318,24 @@ public class JabRefPreferences { public static final String USE_CONVERT_TO_EQUATION = "useConvertToEquation"; public static final String USE_IEEE_ABRV = "useIEEEAbrv"; + public static final String AKS_AUTO_NAMING_PDFS_AGAIN = "AskAutoNamingPDFsAgain"; + private static final String CLEANUP_DOI = "CleanUpDOI"; + private static final String CLEANUP_MONTH = "CleanUpMonth"; + private static final String CLEANUP_PAGENUMBERS = "CleanUpPageNumbers"; + private static final String CLEANUP_DATE = "CleanUpDate"; + private static final String CLEANUP_MAKEPATHSRELATIVE = "CleanUpMakePathsRelative"; + private static final String CLEANUP_RENAMEPDF = "CleanUpRenamePDF"; + private static final String CLEANUP_RENAMEPDF_ONLYRELATIVE_PATHS = "CleanUpRenamePDFonlyRelativePaths"; + private static final String CLEANUP_UPGRADE_EXTERNAL_LINKS = "CleanUpUpgradeExternalLinks"; + private static final String CLEANUP_SUPERSCRIPTS = "CleanUpSuperscripts"; + private static final String CLEANUP_HTML = "CleanUpHTML"; + private static final String CLEANUP_CASE = "CleanUpCase"; + private static final String CLEANUP_LATEX = "CleanUpLaTeX"; + private static final String CLEANUP_UNITS = "CleanUpUnits"; + private static final String CLEANUP_UNICODE = "CleanUpUnicode"; + private static final String CLEANUP_CONVERTTOBIBLATEX = "CleanUpConvertToBiblatex"; + private static final String CLEANUP_FIX_FILE_LINKS = "CleanUpFixFileLinks"; + public static final String PUSH_TO_APPLICATION = "pushToApplication"; //non-default preferences @@ -332,6 +351,7 @@ public class JabRefPreferences { private static final char[][] VALUE_DELIMITERS = new char[][] { {'"', '"'}, {'{', '}'}}; + public String WRAPPED_USERNAME; public final String MARKING_WITH_NUMBER_PATTERN; @@ -747,7 +767,9 @@ private JabRefPreferences() { defaults.put(DB_CONNECT_HOSTNAME, "localhost"); defaults.put(DB_CONNECT_DATABASE, "jabref"); defaults.put(DB_CONNECT_USERNAME, "root"); - CleanUpAction.putDefaults(defaults); + + defaults.put(AKS_AUTO_NAMING_PDFS_AGAIN, Boolean.TRUE); + insertCleanupPreset(defaults, CleanupPreset.DEFAULT); // defaults for DroppedFileHandler UI defaults.put(DroppedFileHandler.DFH_LEAVE, Boolean.FALSE); @@ -1533,4 +1555,68 @@ public Charset getDefaultEncoding() { public void setDefaultEncoding(Charset encoding) { put(JabRefPreferences.DEFAULT_ENCODING, encoding.name()); } + + private static void insertCleanupPreset(HashMap storage, CleanupPreset preset) { + + storage.put(CLEANUP_SUPERSCRIPTS, preset.isCleanUpSuperscripts()); + storage.put(CLEANUP_DOI, preset.isCleanUpDOI()); + storage.put(CLEANUP_MONTH, preset.isCleanUpMonth()); + storage.put(CLEANUP_PAGENUMBERS, preset.isCleanUpPageNumbers()); + storage.put(CLEANUP_DATE, preset.isCleanUpDate()); + storage.put(CLEANUP_MAKEPATHSRELATIVE, preset.isMakePathsRelative()); + storage.put(CLEANUP_RENAMEPDF, preset.isRenamePDF()); + storage.put(CLEANUP_RENAMEPDF_ONLYRELATIVE_PATHS, preset.isRenamePdfOnlyRelativePaths()); + storage.put(CLEANUP_UPGRADE_EXTERNAL_LINKS, preset.isCleanUpUpgradeExternalLinks()); + storage.put(CLEANUP_HTML, preset.isConvertHTMLToLatex()); + storage.put(CLEANUP_CASE, preset.isConvertCase()); + storage.put(CLEANUP_LATEX, preset.isConvertLaTeX()); + storage.put(CLEANUP_UNITS, preset.isConvertUnits()); + storage.put(CLEANUP_UNICODE, preset.isConvertUnicodeToLatex()); + storage.put(CLEANUP_CONVERTTOBIBLATEX, preset.isConvertToBiblatex()); + storage.put(CLEANUP_FIX_FILE_LINKS, preset.isFixFileLinks()); + } + + @Override + public void storeCleanupPreset(CleanupPreset preset) { + + prefs.putBoolean(CLEANUP_SUPERSCRIPTS, preset.isCleanUpSuperscripts()); + prefs.putBoolean(CLEANUP_DOI, preset.isCleanUpDOI()); + prefs.putBoolean(CLEANUP_MONTH, preset.isCleanUpMonth()); + prefs.putBoolean(CLEANUP_PAGENUMBERS, preset.isCleanUpPageNumbers()); + prefs.putBoolean(CLEANUP_DATE, preset.isCleanUpDate()); + prefs.putBoolean(CLEANUP_MAKEPATHSRELATIVE, preset.isMakePathsRelative()); + prefs.putBoolean(CLEANUP_RENAMEPDF, preset.isRenamePDF()); + prefs.putBoolean(CLEANUP_RENAMEPDF_ONLYRELATIVE_PATHS, preset.isRenamePdfOnlyRelativePaths()); + prefs.putBoolean(CLEANUP_UPGRADE_EXTERNAL_LINKS, preset.isCleanUpUpgradeExternalLinks()); + prefs.putBoolean(CLEANUP_HTML, preset.isConvertHTMLToLatex()); + prefs.putBoolean(CLEANUP_CASE, preset.isConvertCase()); + prefs.putBoolean(CLEANUP_LATEX, preset.isConvertLaTeX()); + prefs.putBoolean(CLEANUP_UNITS, preset.isConvertUnits()); + prefs.putBoolean(CLEANUP_UNICODE, preset.isConvertUnicodeToLatex()); + prefs.putBoolean(CLEANUP_CONVERTTOBIBLATEX, preset.isConvertToBiblatex()); + prefs.putBoolean(CLEANUP_FIX_FILE_LINKS, preset.isFixFileLinks()); + } + + @Override + public CleanupPreset retrieveCleanupPreset() { + + CleanupPreset preset = new CleanupPreset(); + preset.setCleanUpSuperscripts(getBoolean(CLEANUP_SUPERSCRIPTS)); + preset.setCleanUpDOI(getBoolean(CLEANUP_DOI)); + preset.setCleanUpMonth(getBoolean(CLEANUP_MONTH)); + preset.setCleanUpPageNumbers(getBoolean(CLEANUP_PAGENUMBERS)); + preset.setCleanUpDate(getBoolean(CLEANUP_DATE)); + preset.setMakePathsRelative(getBoolean(CLEANUP_MAKEPATHSRELATIVE)); + preset.setRenamePDF(getBoolean(CLEANUP_RENAMEPDF)); + preset.setRenamePdfOnlyRelativePaths(getBoolean(CLEANUP_RENAMEPDF_ONLYRELATIVE_PATHS)); + preset.setCleanUpUpgradeExternalLinks(getBoolean(CLEANUP_UPGRADE_EXTERNAL_LINKS)); + preset.setConvertHTMLToLatex(getBoolean(CLEANUP_HTML)); + preset.setConvertCase(getBoolean(CLEANUP_CASE)); + preset.setConvertLaTeX(getBoolean(CLEANUP_LATEX)); + preset.setConvertUnits(getBoolean(CLEANUP_UNITS)); + preset.setConvertUnicodeToLatex(getBoolean(CLEANUP_UNICODE)); + preset.setConvertToBiblatex(getBoolean(CLEANUP_CONVERTTOBIBLATEX)); + preset.setFixFileLinks(getBoolean(CLEANUP_FIX_FILE_LINKS)); + return preset; + } } diff --git a/src/main/java/net/sf/jabref/gui/BasePanel.java b/src/main/java/net/sf/jabref/gui/BasePanel.java index 6ead6383107..64fa39a7e31 100644 --- a/src/main/java/net/sf/jabref/gui/BasePanel.java +++ b/src/main/java/net/sf/jabref/gui/BasePanel.java @@ -38,7 +38,7 @@ import net.sf.jabref.groups.GroupTreeNode; import net.sf.jabref.gui.actions.Actions; import net.sf.jabref.gui.actions.BaseAction; -import net.sf.jabref.gui.actions.CleanUpAction; +import net.sf.jabref.gui.actions.CleanupAction; import net.sf.jabref.gui.desktop.JabRefDesktop; import net.sf.jabref.gui.entryeditor.EntryEditor; import net.sf.jabref.gui.fieldeditors.FieldEditor; @@ -305,7 +305,7 @@ public void output(String s) { private void setupActions() { saveAction = new SaveDatabaseAction(this); - CleanUpAction cleanUpAction = new CleanUpAction(this); + CleanupAction cleanUpAction = new CleanupAction(this, Globals.prefs); actions.put(Actions.UNDO, undoAction); actions.put(Actions.REDO, redoAction); diff --git a/src/main/java/net/sf/jabref/gui/CleanupPresetPanel.java b/src/main/java/net/sf/jabref/gui/CleanupPresetPanel.java new file mode 100644 index 00000000000..ef59050a82f --- /dev/null +++ b/src/main/java/net/sf/jabref/gui/CleanupPresetPanel.java @@ -0,0 +1,143 @@ +package net.sf.jabref.gui; + +import java.util.Objects; + +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import com.jgoodies.forms.builder.FormBuilder; +import com.jgoodies.forms.layout.FormLayout; + +import net.sf.jabref.Globals; +import net.sf.jabref.gui.preftabs.ImportSettingsTab; +import net.sf.jabref.logic.cleanup.CleanupPreset; +import net.sf.jabref.logic.l10n.Localization; + +public class CleanupPresetPanel { + + private JCheckBox cleanUpSuperscripts; + private JCheckBox cleanUpDOI; + private JCheckBox cleanUpMonth; + private JCheckBox cleanUpPageNumbers; + private JCheckBox cleanUpDate; + private JCheckBox cleanUpMakePathsRelative; + private JCheckBox cleanUpRenamePDF; + private JCheckBox cleanUpRenamePDFonlyRelativePaths; + private JCheckBox cleanUpUpgradeExternalLinks; + private JCheckBox cleanUpHTML; + private JCheckBox cleanUpCase; + private JCheckBox cleanUpLaTeX; + private JCheckBox cleanUpUnits; + private JCheckBox cleanUpUnicode; + private JCheckBox cleanUpBibLatex; + + private JPanel panel; + private final CleanupPreset cleanupPreset; + + + public CleanupPresetPanel(CleanupPreset cleanupPreset) { + this.cleanupPreset = Objects.requireNonNull(cleanupPreset); + + init(); + } + + private void init() { + cleanUpSuperscripts = new JCheckBox(Localization.lang("Convert 1st, 2nd, ... to real superscripts")); + cleanUpDOI = new JCheckBox( + Localization.lang("Move DOIs from note and URL field to DOI field and remove http prefix")); + cleanUpMonth = new JCheckBox(Localization.lang("Format content of month field to #mon#")); + cleanUpPageNumbers = new JCheckBox(Localization.lang("Ensure that page ranges are of the form num1--num2")); + cleanUpDate = new JCheckBox(Localization.lang("Format date field in the form yyyy-mm or yyyy-mm-dd")); + cleanUpMakePathsRelative = new JCheckBox( + Localization.lang("Make paths of linked files relative (if possible)")); + cleanUpRenamePDF = new JCheckBox(Localization.lang("Rename PDFs to given filename format pattern")); + cleanUpRenamePDF.addChangeListener(new ChangeListener() { + + @Override + public void stateChanged(ChangeEvent arg0) { + cleanUpRenamePDFonlyRelativePaths.setEnabled(cleanUpRenamePDF.isSelected()); + } + }); + cleanUpRenamePDFonlyRelativePaths = new JCheckBox(Localization.lang("Rename only PDFs having a relative path")); + cleanUpUpgradeExternalLinks = new JCheckBox( + Localization.lang("Upgrade external PDF/PS links to use the '%0' field.", Globals.FILE_FIELD)); + cleanUpHTML = new JCheckBox(Localization.lang("Run HTML converter on title")); + cleanUpCase = new JCheckBox(Localization.lang("Run filter on title keeping the case of selected words")); + cleanUpLaTeX = new JCheckBox( + Localization.lang("Remove unneccessary $, {, and } and move adjacent numbers into equations")); + cleanUpUnits = new JCheckBox( + Localization.lang("Add brackets and replace separators with their non-breaking version for units")); + cleanUpUnicode = new JCheckBox(Localization.lang("Run Unicode converter on title, author(s), and abstract")); + cleanUpBibLatex = new JCheckBox(Localization.lang( + "Convert to BibLatex format (for example, move the value of the 'journal' field to 'journaltitle')")); + updateDisplay(cleanupPreset); + + FormLayout layout = new FormLayout("left:15dlu,pref:grow", + "pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref"); + FormBuilder builder = FormBuilder.create().layout(layout); + builder.add(cleanUpHTML).xyw(1, 1, 2); + builder.add(cleanUpUnicode).xyw(1, 2, 2); + builder.add(cleanUpCase).xyw(1, 3, 2); + builder.add(cleanUpLaTeX).xyw(1, 4, 2); + builder.add(cleanUpUnits).xyw(1, 5, 2); + builder.add(cleanUpSuperscripts).xyw(1, 6, 2); + builder.add(cleanUpDOI).xyw(1, 7, 2); + builder.add(cleanUpMonth).xyw(1, 8, 2); + builder.add(cleanUpPageNumbers).xyw(1, 9, 2); + builder.add(cleanUpDate).xyw(1, 10, 2); + builder.add(cleanUpUpgradeExternalLinks).xyw(1, 11, 2); + builder.add(cleanUpMakePathsRelative).xyw(1, 12, 2); + builder.add(cleanUpRenamePDF).xyw(1, 13, 2); + String currentPattern = Localization.lang("Filename format pattern").concat(": ") + .concat(Globals.prefs.get(ImportSettingsTab.PREF_IMPORT_FILENAMEPATTERN)); + builder.add(new JLabel(currentPattern)).xy(2, 14); + builder.add(cleanUpRenamePDFonlyRelativePaths).xy(2, 15); + builder.add(cleanUpBibLatex).xyw(1, 16, 2); + panel = builder.build(); + } + + private void updateDisplay(CleanupPreset preset) { + cleanUpSuperscripts.setSelected(preset.isCleanUpSuperscripts()); + cleanUpDOI.setSelected(preset.isCleanUpDOI()); + cleanUpMonth.setSelected(preset.isCleanUpMonth()); + cleanUpPageNumbers.setSelected(preset.isCleanUpPageNumbers()); + cleanUpDate.setSelected(preset.isCleanUpDate()); + cleanUpMakePathsRelative.setSelected(preset.isMakePathsRelative()); + cleanUpRenamePDF.setSelected(preset.isRenamePDF()); + cleanUpRenamePDFonlyRelativePaths.setSelected(preset.isRenamePdfOnlyRelativePaths()); + cleanUpRenamePDFonlyRelativePaths.setEnabled(cleanUpRenamePDF.isSelected()); + cleanUpUpgradeExternalLinks.setSelected(preset.isCleanUpUpgradeExternalLinks()); + cleanUpHTML.setSelected(preset.isConvertHTMLToLatex()); + cleanUpCase.setSelected(preset.isConvertCase()); + cleanUpLaTeX.setSelected(preset.isConvertLaTeX()); + cleanUpUnits.setSelected(preset.isConvertUnits()); + cleanUpUnicode.setSelected(preset.isConvertUnicodeToLatex()); + cleanUpBibLatex.setSelected(preset.isConvertToBiblatex()); + } + + public JPanel getPanel() { + return panel; + } + + public CleanupPreset getCleanupPreset() { + cleanupPreset.setCleanUpSuperscripts(cleanUpSuperscripts.isSelected()); + cleanupPreset.setCleanUpDOI(cleanUpDOI.isSelected()); + cleanupPreset.setCleanUpMonth(cleanUpMonth.isSelected()); + cleanupPreset.setCleanUpPageNumbers(cleanUpPageNumbers.isSelected()); + cleanupPreset.setCleanUpDate(cleanUpDate.isSelected()); + cleanupPreset.setCleanUpUpgradeExternalLinks(cleanUpUpgradeExternalLinks.isSelected()); + cleanupPreset.setMakePathsRelative(cleanUpMakePathsRelative.isSelected()); + cleanupPreset.setRenamePDF(cleanUpRenamePDF.isSelected()); + cleanupPreset.setConvertHTMLToLatex(cleanUpHTML.isSelected()); + cleanupPreset.setConvertCase(cleanUpCase.isSelected()); + cleanupPreset.setConvertLaTeX(cleanUpLaTeX.isSelected()); + cleanupPreset.setConvertUnits(cleanUpUnits.isSelected()); + cleanupPreset.setConvertUnicodeToLatex(cleanUpUnicode.isSelected()); + cleanupPreset.setConvertToBiblatex(cleanUpBibLatex.isSelected()); + cleanupPreset.setFixFileLinks(true); + return cleanupPreset; + } +} diff --git a/src/main/java/net/sf/jabref/gui/actions/CleanUpAction.java b/src/main/java/net/sf/jabref/gui/actions/CleanUpAction.java index ce93dcd4c9b..bd2e25acb0f 100644 --- a/src/main/java/net/sf/jabref/gui/actions/CleanUpAction.java +++ b/src/main/java/net/sf/jabref/gui/actions/CleanUpAction.java @@ -15,92 +15,26 @@ */ package net.sf.jabref.gui.actions; -import java.util.HashMap; +import java.util.Arrays; import java.util.List; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; +import java.util.Objects; +import javax.swing.JOptionPane; import net.sf.jabref.*; import net.sf.jabref.gui.*; -import net.sf.jabref.gui.preftabs.ImportSettingsTab; import net.sf.jabref.gui.worker.AbstractWorker; import net.sf.jabref.gui.undo.NamedCompound; import net.sf.jabref.gui.undo.UndoableFieldChange; -import com.jgoodies.forms.builder.FormBuilder; -import com.jgoodies.forms.layout.FormLayout; - import net.sf.jabref.logic.FieldChange; -import net.sf.jabref.logic.cleanup.Cleaner; -import net.sf.jabref.logic.cleanup.DoiCleanup; -import net.sf.jabref.logic.cleanup.FieldFormatterCleanup; -import net.sf.jabref.logic.cleanup.FormatterCleanup; -import net.sf.jabref.logic.formatter.BibtexFieldFormatters; +import net.sf.jabref.logic.cleanup.CleanupPreset; +import net.sf.jabref.logic.cleanup.CleanupWorker; import net.sf.jabref.logic.l10n.Localization; -import net.sf.jabref.model.database.BibDatabase; +import net.sf.jabref.logic.preferences.PreferenceStorage; import net.sf.jabref.model.entry.BibEntry; -import net.sf.jabref.util.Util; -public class CleanUpAction extends AbstractWorker { - - private static final String AKS_AUTO_NAMING_PDFS_AGAIN = "AskAutoNamingPDFsAgain"; - private static final String CLEANUP_DOI = "CleanUpDOI"; - private static final String CLEANUP_MONTH = "CleanUpMonth"; - private static final String CLEANUP_PAGENUMBERS = "CleanUpPageNumbers"; - private static final String CLEANUP_DATE = "CleanUpDate"; - private static final String CLEANUP_MAKEPATHSRELATIVE = "CleanUpMakePathsRelative"; - private static final String CLEANUP_RENAMEPDF = "CleanUpRenamePDF"; - private static final String CLEANUP_RENAMEPDF_ONLYRELATIVE_PATHS = "CleanUpRenamePDFonlyRelativePaths"; - private static final String CLEANUP_UPGRADE_EXTERNAL_LINKS = "CleanUpUpgradeExternalLinks"; - private static final String CLEANUP_SUPERSCRIPTS = "CleanUpSuperscripts"; - private static final String CLEANUP_HTML = "CleanUpHTML"; - private static final String CLEANUP_CASE = "CleanUpCase"; - private static final String CLEANUP_LATEX = "CleanUpLaTeX"; - private static final String CLEANUP_UNITS = "CleanUpUnits"; - private static final String CLEANUP_UNICODE = "CleanUpUnicode"; - private static final String CLEANUP_CONVERTTOBIBLATEX = "CleanUpConvertToBiblatex"; - - public static void putDefaults(HashMap defaults) { - defaults.put(AKS_AUTO_NAMING_PDFS_AGAIN, Boolean.TRUE); - defaults.put(CLEANUP_SUPERSCRIPTS, Boolean.TRUE); - defaults.put(CLEANUP_DOI, Boolean.TRUE); - defaults.put(CLEANUP_MONTH, Boolean.TRUE); - defaults.put(CLEANUP_PAGENUMBERS, Boolean.TRUE); - defaults.put(CLEANUP_DATE, Boolean.TRUE); - defaults.put(CLEANUP_MAKEPATHSRELATIVE, Boolean.TRUE); - defaults.put(CLEANUP_RENAMEPDF, Boolean.TRUE); - defaults.put(CLEANUP_RENAMEPDF_ONLYRELATIVE_PATHS, Boolean.FALSE); - defaults.put(CLEANUP_UPGRADE_EXTERNAL_LINKS, Boolean.FALSE); - defaults.put(CLEANUP_MAKEPATHSRELATIVE, Boolean.TRUE); - defaults.put(CLEANUP_HTML, Boolean.TRUE); - defaults.put(CLEANUP_CASE, Boolean.TRUE); - defaults.put(CLEANUP_LATEX, Boolean.TRUE); - defaults.put(CLEANUP_UNITS, Boolean.TRUE); - defaults.put(CLEANUP_UNICODE, Boolean.TRUE); - defaults.put(CLEANUP_CONVERTTOBIBLATEX, Boolean.FALSE); - } +public class CleanupAction extends AbstractWorker { - private JCheckBox cleanUpSuperscripts; - private JCheckBox cleanUpDOI; - private JCheckBox cleanUpMonth; - private JCheckBox cleanUpPageNumbers; - private JCheckBox cleanUpDate; - private JCheckBox cleanUpMakePathsRelative; - private JCheckBox cleanUpRenamePDF; - private JCheckBox cleanUpRenamePDFonlyRelativePaths; - private JCheckBox cleanUpUpgradeExternalLinks; - private JCheckBox cleanUpHTML; - private JCheckBox cleanUpCase; - private JCheckBox cleanUpLaTeX; - private JCheckBox cleanUpUnits; - private JCheckBox cleanUpUnicode; - private JCheckBox cleanUpBibLatex; - - private JPanel optionsPanel = new JPanel(); private final BasePanel panel; private final JabRefFrame frame; @@ -111,106 +45,15 @@ public static void putDefaults(HashMap defaults) { private boolean cancelled; private int modifiedEntriesCount; + private final PreferenceStorage preferences; + private final CleanupPresetPanel presetPanel; - public CleanUpAction(BasePanel panel) { + public CleanupAction(BasePanel panel, PreferenceStorage preferences) { this.panel = panel; this.frame = panel.frame(); - initOptionsPanel(); - } - - private void initOptionsPanel() { - cleanUpSuperscripts = new JCheckBox(Localization.lang("Convert 1st, 2nd, ... to real superscripts")); - cleanUpDOI = new JCheckBox(Localization.lang("Move DOIs from note and URL field to DOI field and remove http prefix")); - cleanUpMonth = new JCheckBox(Localization.lang("Format content of month field to #mon#")); - cleanUpPageNumbers = new JCheckBox(Localization.lang("Ensure that page ranges are of the form num1--num2")); - cleanUpDate = new JCheckBox(Localization.lang("Format date field in the form yyyy-mm or yyyy-mm-dd")); - cleanUpMakePathsRelative = new JCheckBox(Localization.lang("Make paths of linked files relative (if possible)")); - cleanUpRenamePDF = new JCheckBox(Localization.lang("Rename PDFs to given filename format pattern")); - cleanUpRenamePDF.addChangeListener(new ChangeListener() { - - @Override - public void stateChanged(ChangeEvent arg0) { - cleanUpRenamePDFonlyRelativePaths.setEnabled(cleanUpRenamePDF.isSelected()); - } - }); - cleanUpRenamePDFonlyRelativePaths = new JCheckBox(Localization.lang("Rename only PDFs having a relative path")); - cleanUpUpgradeExternalLinks = new JCheckBox(Localization.lang("Upgrade external PDF/PS links to use the '%0' field.", Globals.FILE_FIELD)); - cleanUpHTML = new JCheckBox(Localization.lang("Run HTML converter on title")); - cleanUpCase = new JCheckBox(Localization.lang("Run filter on title keeping the case of selected words")); - cleanUpLaTeX = new JCheckBox(Localization.lang("Remove unneccessary $, {, and } and move adjacent numbers into equations")); - cleanUpUnits = new JCheckBox(Localization.lang("Add brackets and replace separators with their non-breaking version for units")); - cleanUpUnicode = new JCheckBox(Localization.lang("Run Unicode converter on title, author(s), and abstract")); - cleanUpBibLatex = new JCheckBox(Localization.lang("Convert to BibLatex format (for example, move the value of the 'journal' field to 'journaltitle')")); - retrieveSettings(); - - FormLayout layout = new FormLayout("left:15dlu,pref:grow", - "pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref"); - FormBuilder builder = FormBuilder.create().layout(layout); - builder.add(cleanUpHTML).xyw(1, 1, 2); - builder.add(cleanUpUnicode).xyw(1, 2, 2); - builder.add(cleanUpCase).xyw(1, 3, 2); - builder.add(cleanUpLaTeX).xyw(1, 4, 2); - builder.add(cleanUpUnits).xyw(1, 5, 2); - builder.add(cleanUpSuperscripts).xyw(1, 6, 2); - builder.add(cleanUpDOI).xyw(1, 7, 2); - builder.add(cleanUpMonth).xyw(1, 8, 2); - builder.add(cleanUpPageNumbers).xyw(1, 9, 2); - builder.add(cleanUpDate).xyw(1, 10, 2); - builder.add(cleanUpUpgradeExternalLinks).xyw(1, 11, 2); - builder.add(cleanUpMakePathsRelative).xyw(1, 12, 2); - builder.add(cleanUpRenamePDF).xyw(1, 13, 2); - String currentPattern = Localization.lang("Filename format pattern").concat(": ").concat(Globals.prefs.get(ImportSettingsTab.PREF_IMPORT_FILENAMEPATTERN)); - builder.add(new JLabel(currentPattern)).xy(2, 14); - builder.add(cleanUpRenamePDFonlyRelativePaths).xy(2, 15); - builder.add(cleanUpBibLatex).xyw(1, 16, 2); - optionsPanel = builder.build(); - - } - - private void retrieveSettings() { - cleanUpSuperscripts.setSelected(Globals.prefs.getBoolean(CleanUpAction.CLEANUP_SUPERSCRIPTS)); - cleanUpDOI.setSelected(Globals.prefs.getBoolean(CleanUpAction.CLEANUP_DOI)); - cleanUpMonth.setSelected(Globals.prefs.getBoolean(CleanUpAction.CLEANUP_MONTH)); - cleanUpPageNumbers.setSelected(Globals.prefs.getBoolean(CleanUpAction.CLEANUP_PAGENUMBERS)); - cleanUpDate.setSelected(Globals.prefs.getBoolean(CleanUpAction.CLEANUP_DATE)); - cleanUpMakePathsRelative.setSelected(Globals.prefs.getBoolean(CleanUpAction.CLEANUP_MAKEPATHSRELATIVE)); - cleanUpRenamePDF.setSelected(Globals.prefs.getBoolean(CleanUpAction.CLEANUP_RENAMEPDF)); - cleanUpRenamePDFonlyRelativePaths.setSelected(Globals.prefs.getBoolean(CleanUpAction.CLEANUP_RENAMEPDF_ONLYRELATIVE_PATHS)); - cleanUpRenamePDFonlyRelativePaths.setEnabled(cleanUpRenamePDF.isSelected()); - cleanUpUpgradeExternalLinks.setSelected(Globals.prefs.getBoolean(CleanUpAction.CLEANUP_UPGRADE_EXTERNAL_LINKS)); - cleanUpHTML.setSelected(Globals.prefs.getBoolean(CleanUpAction.CLEANUP_HTML)); - cleanUpCase.setSelected(Globals.prefs.getBoolean(CleanUpAction.CLEANUP_CASE)); - cleanUpLaTeX.setSelected(Globals.prefs.getBoolean(CleanUpAction.CLEANUP_LATEX)); - cleanUpUnits.setSelected(Globals.prefs.getBoolean(CleanUpAction.CLEANUP_UNITS)); - cleanUpUnicode.setSelected(Globals.prefs.getBoolean(CleanUpAction.CLEANUP_UNICODE)); - cleanUpBibLatex.setSelected(Globals.prefs.getBoolean(CleanUpAction.CLEANUP_CONVERTTOBIBLATEX)); - } - - private void storeSettings() { - Globals.prefs.putBoolean(CleanUpAction.CLEANUP_SUPERSCRIPTS, cleanUpSuperscripts.isSelected()); - Globals.prefs.putBoolean(CleanUpAction.CLEANUP_DOI, cleanUpDOI.isSelected()); - Globals.prefs.putBoolean(CleanUpAction.CLEANUP_MONTH, cleanUpMonth.isSelected()); - Globals.prefs.putBoolean(CleanUpAction.CLEANUP_PAGENUMBERS, cleanUpPageNumbers.isSelected()); - Globals.prefs.putBoolean(CleanUpAction.CLEANUP_DATE, cleanUpDate.isSelected()); - Globals.prefs.putBoolean(CleanUpAction.CLEANUP_MAKEPATHSRELATIVE, cleanUpMakePathsRelative.isSelected()); - Globals.prefs.putBoolean(CleanUpAction.CLEANUP_RENAMEPDF, cleanUpRenamePDF.isSelected()); - Globals.prefs.putBoolean(CleanUpAction.CLEANUP_RENAMEPDF_ONLYRELATIVE_PATHS, cleanUpRenamePDFonlyRelativePaths.isSelected()); - Globals.prefs.putBoolean(CleanUpAction.CLEANUP_UPGRADE_EXTERNAL_LINKS, cleanUpUpgradeExternalLinks.isSelected()); - Globals.prefs.putBoolean(CleanUpAction.CLEANUP_HTML, cleanUpHTML.isSelected()); - Globals.prefs.putBoolean(CleanUpAction.CLEANUP_CASE, cleanUpCase.isSelected()); - Globals.prefs.putBoolean(CleanUpAction.CLEANUP_LATEX, cleanUpLaTeX.isSelected()); - Globals.prefs.putBoolean(CleanUpAction.CLEANUP_UNITS, cleanUpUnits.isSelected()); - Globals.prefs.putBoolean(CleanUpAction.CLEANUP_UNICODE, cleanUpUnicode.isSelected()); - Globals.prefs.putBoolean(CleanUpAction.CLEANUP_CONVERTTOBIBLATEX, cleanUpBibLatex.isSelected()); - } - - private int showCleanUpDialog() { - String dialogTitle = Localization.lang("Cleanup entries"); - - Object[] messages = {Localization.lang("What would you like to clean up?"), optionsPanel}; - return JOptionPane.showConfirmDialog(frame, messages, dialogTitle, - JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); + this.preferences = Objects.requireNonNull(preferences); + this.presetPanel = new CleanupPresetPanel(preferences.retrieveCleanupPreset()); } @Override @@ -233,34 +76,21 @@ public void run() { if (cancelled) { return; } - int choice = showCleanUpDialog(); + int choice = showDialog(); if (choice != JOptionPane.OK_OPTION) { cancelled = true; return; } - storeSettings(); - boolean choiceCleanUpSuperscripts = cleanUpSuperscripts.isSelected(); - boolean choiceCleanUpDOI = cleanUpDOI.isSelected(); - boolean choiceCleanUpMonth = cleanUpMonth.isSelected(); - boolean choiceCleanUpPageNumbers = cleanUpPageNumbers.isSelected(); - boolean choiceCleanUpDate = cleanUpDate.isSelected(); - boolean choiceCleanUpUpgradeExternalLinks = cleanUpUpgradeExternalLinks.isSelected(); - boolean choiceMakePathsRelative = cleanUpMakePathsRelative.isSelected(); - boolean choiceRenamePDF = cleanUpRenamePDF.isSelected(); - boolean choiceConvertHTML = cleanUpHTML.isSelected(); - boolean choiceConvertCase = cleanUpCase.isSelected(); - boolean choiceConvertLaTeX = cleanUpLaTeX.isSelected(); - boolean choiceConvertUnits = cleanUpUnits.isSelected(); - boolean choiceConvertUnicode = cleanUpUnicode.isSelected(); - boolean choiceConvertToBiblatex = cleanUpBibLatex.isSelected(); + CleanupPreset cleanupPreset = presetPanel.getCleanupPreset(); + preferences.storeCleanupPreset(cleanupPreset); - if (choiceRenamePDF && Globals.prefs.getBoolean(CleanUpAction.AKS_AUTO_NAMING_PDFS_AGAIN)) { + if (cleanupPreset.isRenamePDF() && Globals.prefs.getBoolean(JabRefPreferences.AKS_AUTO_NAMING_PDFS_AGAIN)) { CheckBoxMessage cbm = new CheckBoxMessage(Localization.lang("Auto-generating PDF-Names does not support undo. Continue?"), Localization.lang("Disable this confirmation dialog"), false); int answer = JOptionPane.showConfirmDialog(frame, cbm, Localization.lang("Autogenerate PDF Names"), JOptionPane.YES_NO_OPTION); if (cbm.isSelected()) { - Globals.prefs.putBoolean(CleanUpAction.AKS_AUTO_NAMING_PDFS_AGAIN, false); + Globals.prefs.putBoolean(JabRefPreferences.AKS_AUTO_NAMING_PDFS_AGAIN, false); } if (answer == JOptionPane.NO_OPTION) { cancelled = true; @@ -272,50 +102,7 @@ public void run() { // undo granularity is on entry level NamedCompound ce = new NamedCompound(Localization.lang("Cleanup entry")); - if (choiceCleanUpUpgradeExternalLinks) { - doUpgradePdfPsToFile(entry, ce); - } - if (choiceCleanUpSuperscripts) { - doCleanUpSuperscripts(entry, ce); - } - if (choiceCleanUpDOI) { - doCleanUpDOI(entry, ce); - } - if (choiceCleanUpMonth) { - doCleanUpMonth(entry, ce); - } - if (choiceCleanUpPageNumbers) { - doCleanUpPageNumbers(entry, ce); - } - if (choiceCleanUpDate) { - doCleanUpDate(entry, ce); - } - - fixWrongFileEntries(entry, ce); - if (choiceMakePathsRelative) { - doMakePathsRelative(entry, ce); - } - if (choiceRenamePDF) { - doRenamePDFs(entry, ce); - } - if (choiceConvertHTML) { - doConvertHTML(entry, ce); - } - if (choiceConvertUnits) { - doConvertUnits(entry, ce); - } - if (choiceConvertCase) { - doConvertCase(entry, ce); - } - if (choiceConvertLaTeX) { - doConvertLaTeX(entry, ce); - } - if (choiceConvertUnicode) { - doConvertUnicode(entry, ce); - } - if (choiceConvertToBiblatex) { - doConvertToBiblatex(entry, ce); - } + doCleanup(cleanupPreset, entry, ce); ce.end(); if (ce.hasEdits()) { @@ -356,102 +143,25 @@ public void update() { frame.unblock(); } - /** - * Collects file links from the pdf or ps field, and adds them to the list contained in the file field. - */ - private void doUpgradePdfPsToFile(BibEntry entry, NamedCompound ce) { - Util.upgradePdfPsToFile(entry, new String[] {"pdf", "ps"}, ce); - } - - /** - * Converts the text in 1st, 2nd, ... to real superscripts by wrapping in \textsuperscript{st}, ... - */ - private static void doCleanUpSuperscripts(BibEntry entry, NamedCompound ce) { - doCleanup(new FormatterCleanup(BibtexFieldFormatters.SUPERSCRIPTS), entry, ce); - } - - /** - * Removes the http://... for each DOI. Moves DOIs from URL and NOTE filed to DOI field. - */ - private static void doCleanUpDOI(BibEntry entry, NamedCompound ce) { - doCleanup(new DoiCleanup(), entry, ce); - } - - private static void doCleanUpMonth(BibEntry entry, NamedCompound ce) { - doCleanup(FieldFormatterCleanup.MONTH, entry, ce); - } - - private static void doCleanUpPageNumbers(BibEntry entry, NamedCompound ce) { - doCleanup(FieldFormatterCleanup.PAGE_NUMBERS, entry, ce); - } - - private static void fixWrongFileEntries(BibEntry entry, NamedCompound ce) { - doCleanup(new FileEntryCleaner(), entry, ce); - } - - private void doMakePathsRelative(BibEntry entry, NamedCompound ce) { - doCleanup(new RelativePathsCleanup(panel.metaData().getFileDirectory(Globals.FILE_FIELD)), entry, ce); - } - - private void doRenamePDFs(BibEntry entry, NamedCompound ce) { - String[] paths = panel.metaData().getFileDirectory(Globals.FILE_FIELD); - BibDatabase database = panel.database(); - Boolean onlyRelativePaths = cleanUpRenamePDFonlyRelativePaths.isSelected(); - RenamePdfCleanup cleaner = new RenamePdfCleanup(paths, onlyRelativePaths, database); - doCleanup(cleaner, entry, ce); - unsuccessfulRenames += cleaner.getUnsuccessfulRenames(); - } - - /** - * Converts HTML code to LaTeX code - */ - private static void doConvertHTML(BibEntry entry, NamedCompound ce) { - doCleanup(FieldFormatterCleanup.TITLE_HTML, entry, ce); - } - - /** - * Converts Unicode characters to LaTeX code - */ - private static void doConvertUnicode(BibEntry entry, NamedCompound ce) { - doCleanup(new UnicodeCleanup(), entry, ce); - } - - /** - * Adds curly brackets {} around keywords - */ - private static void doConvertCase(BibEntry entry, NamedCompound ce) { - doCleanup(FieldFormatterCleanup.TITLE_CASE, entry, ce); - } - - private static void doConvertUnits(BibEntry entry, NamedCompound ce) { - doCleanup(FieldFormatterCleanup.TITLE_UNITS, entry, ce); - } - - private static void doConvertLaTeX(BibEntry entry, NamedCompound ce) { - doCleanup(FieldFormatterCleanup.TITLE_LATEX, entry, ce); - } - - /** - * Converts to BibLatex format - */ - private static void doConvertToBiblatex(BibEntry entry, NamedCompound ce) { - doCleanup(new BiblatexCleanup(), entry, ce); - } + private int showDialog() { + String dialogTitle = Localization.lang("Cleanup entries"); - /** - * Format dates correctly (yyyy-mm-dd or yyyy-mm) - */ - private static void doCleanUpDate(BibEntry entry, NamedCompound ce) { - doCleanup(FieldFormatterCleanup.DATES, entry, ce); + Object[] messages = {Localization.lang("What would you like to clean up?"), presetPanel.getPanel()}; + return JOptionPane.showConfirmDialog(frame, messages, dialogTitle, JOptionPane.OK_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE); } /** - * Runs the field formatter on the entry and records the change. + * Runs the cleanup on the entry and records the change. */ - private static void doCleanup(Cleaner cleaner, BibEntry entry, NamedCompound ce) { + private void doCleanup(CleanupPreset preset, BibEntry entry, NamedCompound ce) { // Run cleaner + CleanupWorker cleaner = new CleanupWorker(preset, + Arrays.asList(panel.metaData().getFileDirectory(Globals.FILE_FIELD))); List changes = cleaner.cleanup(entry); + // TODO: Set unsuccessful renames + if (changes.isEmpty()) { return; } diff --git a/src/main/java/net/sf/jabref/gui/actions/FileEntryCleaner.java b/src/main/java/net/sf/jabref/gui/actions/FileEntryCleaner.java deleted file mode 100644 index 6a9d05a38b3..00000000000 --- a/src/main/java/net/sf/jabref/gui/actions/FileEntryCleaner.java +++ /dev/null @@ -1,50 +0,0 @@ -package net.sf.jabref.gui.actions; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import net.sf.jabref.Globals; -import net.sf.jabref.gui.FileListEntry; -import net.sf.jabref.gui.FileListTableModel; -import net.sf.jabref.logic.FieldChange; -import net.sf.jabref.logic.cleanup.Cleaner; -import net.sf.jabref.model.entry.BibEntry; - - -public class FileEntryCleaner implements Cleaner { - - @Override - public List cleanup(BibEntry entry) { - String oldValue = entry.getField(Globals.FILE_FIELD); - if (oldValue == null) { - return new ArrayList<>(); - } - FileListTableModel flModel = new FileListTableModel(); - flModel.setContent(oldValue); - if (flModel.getRowCount() == 0) { - return new ArrayList<>(); - } - boolean changed = false; - for (int i = 0; i < flModel.getRowCount(); i++) { - FileListEntry flEntry = flModel.getEntry(i); - String link = flEntry.getLink(); - String description = flEntry.getDescription(); - if ("".equals(link) && (!"".equals(description))) { - // link and description seem to be switched, quickly fix that - flEntry.setLink(flEntry.getDescription()); - flEntry.setDescription(""); - changed = true; - } - } - if (changed) { - String newValue = flModel.getStringRepresentation(); - assert(!oldValue.equals(newValue)); - entry.setField(Globals.FILE_FIELD, newValue); - FieldChange change = new FieldChange(entry, Globals.FILE_FIELD, oldValue, newValue); - return Arrays.asList(new FieldChange[] {change}); - } - return new ArrayList<>(); - } - -} diff --git a/src/main/java/net/sf/jabref/gui/actions/RelativePathsCleanup.java b/src/main/java/net/sf/jabref/gui/actions/RelativePathsCleanup.java deleted file mode 100644 index af1bb1c8898..00000000000 --- a/src/main/java/net/sf/jabref/gui/actions/RelativePathsCleanup.java +++ /dev/null @@ -1,59 +0,0 @@ -package net.sf.jabref.gui.actions; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import net.sf.jabref.Globals; -import net.sf.jabref.gui.FileListEntry; -import net.sf.jabref.gui.FileListTableModel; -import net.sf.jabref.logic.FieldChange; -import net.sf.jabref.logic.cleanup.Cleaner; -import net.sf.jabref.logic.util.io.FileUtil; -import net.sf.jabref.model.entry.BibEntry; - - -public class RelativePathsCleanup implements Cleaner { - - private final String[] paths; - - - public RelativePathsCleanup(String[] paths) { - this.paths = paths; - } - - @Override - public List cleanup(BibEntry entry) { - String oldValue = entry.getField(Globals.FILE_FIELD); - if (oldValue == null) { - return new ArrayList<>(); - } - FileListTableModel flModel = new FileListTableModel(); - flModel.setContent(oldValue); - if (flModel.getRowCount() == 0) { - return new ArrayList<>(); - } - boolean changed = false; - for (int i = 0; i < flModel.getRowCount(); i++) { - FileListEntry flEntry = flModel.getEntry(i); - String oldFileName = flEntry.getLink(); - String newFileName = FileUtil - .shortenFileName(new File(oldFileName), paths) - .toString(); - if (!oldFileName.equals(newFileName)) { - flEntry.setLink(newFileName); - changed = true; - } - } - if (changed) { - String newValue = flModel.getStringRepresentation(); - assert(!oldValue.equals(newValue)); - entry.setField(Globals.FILE_FIELD, newValue); - FieldChange change = new FieldChange(entry, Globals.FILE_FIELD, oldValue, newValue); - return Arrays.asList(new FieldChange[] {change}); - } - return new ArrayList<>(); - } - -} diff --git a/src/main/java/net/sf/jabref/gui/actions/RenamePdfCleanup.java b/src/main/java/net/sf/jabref/gui/actions/RenamePdfCleanup.java deleted file mode 100644 index 9c789806ece..00000000000 --- a/src/main/java/net/sf/jabref/gui/actions/RenamePdfCleanup.java +++ /dev/null @@ -1,119 +0,0 @@ -package net.sf.jabref.gui.actions; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import net.sf.jabref.Globals; -import net.sf.jabref.external.ExternalFileType; -import net.sf.jabref.gui.FileListEntry; -import net.sf.jabref.gui.FileListTableModel; -import net.sf.jabref.logic.FieldChange; -import net.sf.jabref.logic.cleanup.Cleaner; -import net.sf.jabref.logic.util.io.FileUtil; -import net.sf.jabref.model.database.BibDatabase; -import net.sf.jabref.model.entry.BibEntry; -import net.sf.jabref.util.Util; - -public class RenamePdfCleanup implements Cleaner { - - private final String[] paths; - private final BibDatabase database; - private final Boolean onlyRelativePaths; - private int unsuccessfulRenames; - - - public RenamePdfCleanup(String[] paths, Boolean onlyRelativePaths, BibDatabase database) { - this.paths = paths; - this.database = database; - this.onlyRelativePaths = onlyRelativePaths; - } - - @Override - public List cleanup(BibEntry entry) { - //Extract the path - String oldValue = entry.getField(Globals.FILE_FIELD); - if (oldValue == null) { - return new ArrayList<>(); - } - FileListTableModel flModel = new FileListTableModel(); - flModel.setContent(oldValue); - if (flModel.getRowCount() == 0) { - return new ArrayList<>(); - } - boolean changed = false; - - for (int i = 0; i < flModel.getRowCount(); i++) { - String realOldFilename = flModel.getEntry(i).getLink(); - - if (onlyRelativePaths && (new File(realOldFilename).isAbsolute())) { - continue; - } - - String newFilename = Util.getLinkedFileName(database, entry); - //String oldFilename = bes.getField(GUIGlobals.FILE_FIELD); // would have to be stored for undoing purposes - - //Add extension to newFilename - newFilename = newFilename + "." + flModel.getEntry(i).getType().getExtension(); - - //get new Filename with path - //Create new Path based on old Path and new filename - File expandedOldFile = FileUtil.expandFilename(realOldFilename, paths); - if ((expandedOldFile == null) || (expandedOldFile.getParent() == null)) { - // something went wrong. Just skip this entry - continue; - } - String newPath = expandedOldFile.getParent().concat(System.getProperty("file.separator")) - .concat(newFilename); - - if (new File(newPath).exists()) { - // we do not overwrite files - // TODO: we could check here if the newPath file is linked with the current entry. And if not, we could add a link - continue; - } - - //do rename - boolean renameSuccessful = FileUtil.renameFile(expandedOldFile.toString(), newPath); - - if (renameSuccessful) { - changed = true; - - //Change the path for this entry - String description = flModel.getEntry(i).getDescription(); - ExternalFileType type = flModel.getEntry(i).getType(); - flModel.removeEntry(i); - - // we cannot use "newPath" to generate a FileListEntry as newPath is absolute, but we want to keep relative paths whenever possible - File parent = (new File(realOldFilename)).getParentFile(); - String newFileEntryFileName; - if (parent == null) { - newFileEntryFileName = newFilename; - } else { - newFileEntryFileName = parent.toString().concat(System.getProperty("file.separator")) - .concat(newFilename); - } - flModel.addEntry(i, new FileListEntry(description, newFileEntryFileName, type)); - } else { - unsuccessfulRenames++; - } - } - - if (changed) { - String newValue = flModel.getStringRepresentation(); - assert(!oldValue.equals(newValue)); - entry.setField(Globals.FILE_FIELD, newValue); - //we put an undo of the field content here - //the file is not being renamed back, which leads to inconsistencies - //if we put a null undo object here, the change by "doMakePathsRelative" would overwrite the field value nevertheless. - FieldChange change = new FieldChange(entry, Globals.FILE_FIELD, oldValue, newValue); - return Arrays.asList(new FieldChange[] {change}); - } - - return new ArrayList<>(); - } - - public int getUnsuccessfulRenames() { - return unsuccessfulRenames; - } -} diff --git a/src/main/java/net/sf/jabref/logic/FieldChange.java b/src/main/java/net/sf/jabref/logic/FieldChange.java index b8af8e9f48b..41ad702afd6 100644 --- a/src/main/java/net/sf/jabref/logic/FieldChange.java +++ b/src/main/java/net/sf/jabref/logic/FieldChange.java @@ -35,4 +35,58 @@ public String getOldValue() { public String getNewValue() { return this.newValue; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = (prime * result) + ((entry == null) ? 0 : entry.hashCode()); + result = (prime * result) + ((field == null) ? 0 : field.hashCode()); + result = (prime * result) + ((newValue == null) ? 0 : newValue.hashCode()); + result = (prime * result) + ((oldValue == null) ? 0 : oldValue.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + FieldChange other = (FieldChange) obj; + if (entry == null) { + if (other.entry != null) { + return false; + } + } else if (!entry.equals(other.entry)) { + return false; + } + if (field == null) { + if (other.field != null) { + return false; + } + } else if (!field.equals(other.field)) { + return false; + } + if (newValue == null) { + if (other.newValue != null) { + return false; + } + } else if (!newValue.equals(other.newValue)) { + return false; + } + if (oldValue == null) { + if (other.oldValue != null) { + return false; + } + } else if (!oldValue.equals(other.oldValue)) { + return false; + } + return true; + } } diff --git a/src/main/java/net/sf/jabref/gui/actions/BiblatexCleanup.java b/src/main/java/net/sf/jabref/logic/cleanup/BiblatexCleanup.java similarity index 54% rename from src/main/java/net/sf/jabref/gui/actions/BiblatexCleanup.java rename to src/main/java/net/sf/jabref/logic/cleanup/BiblatexCleanup.java index 44b53eda33e..14dd7e3abc9 100644 --- a/src/main/java/net/sf/jabref/gui/actions/BiblatexCleanup.java +++ b/src/main/java/net/sf/jabref/logic/cleanup/BiblatexCleanup.java @@ -1,18 +1,31 @@ -package net.sf.jabref.gui.actions; +/* Copyright (C) 2003-2015 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package net.sf.jabref.logic.cleanup; import java.util.ArrayList; import java.util.List; import java.util.Map; import net.sf.jabref.logic.FieldChange; -import net.sf.jabref.logic.cleanup.Cleaner; import net.sf.jabref.model.entry.BibEntry; import net.sf.jabref.model.entry.EntryConverter; /** * Converts the entry to BibLatex format. */ -public class BiblatexCleanup implements Cleaner { +public class BiblatexCleanup implements CleanupJob { @Override public List cleanup(BibEntry entry) { @@ -37,13 +50,16 @@ public List cleanup(BibEntry entry) { String newDate = entry.getFieldOrAlias("date"); String oldYear = entry.getField("year"); String oldMonth = entry.getField("month"); - entry.setField("date", newDate); - entry.clearField("year"); - entry.clearField("month"); - changes.add(new FieldChange(entry, "date", null, newDate)); - changes.add(new FieldChange(entry, "year", oldYear, null)); - changes.add(new FieldChange(entry, "month", oldMonth, null)); + if (newDate != null) { + entry.setField("date", newDate); + entry.clearField("year"); + entry.clearField("month"); + + changes.add(new FieldChange(entry, "date", null, newDate)); + changes.add(new FieldChange(entry, "year", oldYear, null)); + changes.add(new FieldChange(entry, "month", oldMonth, null)); + } } return changes; } diff --git a/src/main/java/net/sf/jabref/logic/cleanup/Cleaner.java b/src/main/java/net/sf/jabref/logic/cleanup/Cleaner.java deleted file mode 100644 index 21ca88a67c6..00000000000 --- a/src/main/java/net/sf/jabref/logic/cleanup/Cleaner.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.sf.jabref.logic.cleanup; - -import java.util.List; - -import net.sf.jabref.logic.FieldChange; -import net.sf.jabref.model.entry.BibEntry; - -public interface Cleaner { - - /** - * Cleanup the entry. - */ - List cleanup(BibEntry entry); - -} \ No newline at end of file diff --git a/src/main/java/net/sf/jabref/logic/cleanup/CleanupJob.java b/src/main/java/net/sf/jabref/logic/cleanup/CleanupJob.java new file mode 100644 index 00000000000..83cc7a3fdc3 --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/cleanup/CleanupJob.java @@ -0,0 +1,29 @@ +/* Copyright (C) 2003-2015 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package net.sf.jabref.logic.cleanup; + +import java.util.List; + +import net.sf.jabref.logic.FieldChange; +import net.sf.jabref.model.entry.BibEntry; + +public interface CleanupJob { + + /** + * Cleanup the entry. + */ + List cleanup(BibEntry entry); + +} \ No newline at end of file diff --git a/src/main/java/net/sf/jabref/logic/cleanup/CleanupPreset.java b/src/main/java/net/sf/jabref/logic/cleanup/CleanupPreset.java new file mode 100644 index 00000000000..76ab7d72231 --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/cleanup/CleanupPreset.java @@ -0,0 +1,210 @@ +/* Copyright (C) 2003-2015 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package net.sf.jabref.logic.cleanup; + +public class CleanupPreset { + + public static final CleanupPreset DEFAULT; + + static { + DEFAULT = new CleanupPreset(); + DEFAULT.setCleanUpSuperscripts(true); + DEFAULT.setCleanUpDOI(true); + DEFAULT.setCleanUpMonth(true); + DEFAULT.setCleanUpPageNumbers(true); + DEFAULT.setCleanUpDate(true); + DEFAULT.setMakePathsRelative(true); + DEFAULT.setRenamePDF(true); + DEFAULT.setConvertHTMLToLatex(true); + DEFAULT.setConvertCase(true); + DEFAULT.setConvertLaTeX(true); + DEFAULT.setConvertUnits(true); + DEFAULT.setConvertUnicodeToLatex(true); + DEFAULT.setFixFileLinks(true); + } + + + private boolean cleanUpSuperscripts; + private boolean cleanUpDOI; + private boolean cleanUpMonth; + private boolean cleanUpPageNumbers; + private boolean cleanUpDate; + private boolean cleanUpUpgradeExternalLinks; + private boolean makePathsRelative; + private boolean renamePDF; + private boolean renamePdfOnlyRelativePaths; + private boolean convertHTMLToLatex; + private boolean convertCase; + private boolean convertLaTeX; + private boolean convertUnits; + private boolean convertUnicodeToLatex; + private boolean convertToBiblatex; + private boolean fixFileLinks; + + + public boolean isCleanUpSuperscripts() { + return cleanUpSuperscripts; + } + + /** + * Converts the text in 1st, 2nd, ... to real superscripts by wrapping in \textsuperscript{st}, ... + */ + public void setCleanUpSuperscripts(boolean cleanUpSuperscripts) { + this.cleanUpSuperscripts = cleanUpSuperscripts; + } + + /** + * Removes the http://... for each DOI. Moves DOIs from URL and NOTE filed to DOI field. + */ + public boolean isCleanUpDOI() { + return cleanUpDOI; + } + + public void setCleanUpDOI(boolean cleanUpDOI) { + this.cleanUpDOI = cleanUpDOI; + } + + public boolean isCleanUpMonth() { + return cleanUpMonth; + } + + public void setCleanUpMonth(boolean cleanUpMonth) { + this.cleanUpMonth = cleanUpMonth; + } + + public boolean isCleanUpPageNumbers() { + return cleanUpPageNumbers; + } + + public void setCleanUpPageNumbers(boolean cleanUpPageNumbers) { + this.cleanUpPageNumbers = cleanUpPageNumbers; + } + + public boolean isCleanUpDate() { + return cleanUpDate; + } + + /** + * Format dates correctly (yyyy-mm-dd or yyyy-mm) + */ + public void setCleanUpDate(boolean cleanUpDate) { + this.cleanUpDate = cleanUpDate; + } + + /** + * Collects file links from the pdf or ps field, and adds them to the list contained in the file field. + */ + public boolean isCleanUpUpgradeExternalLinks() { + return cleanUpUpgradeExternalLinks; + } + + public void setCleanUpUpgradeExternalLinks(boolean cleanUpUpgradeExternalLinks) { + this.cleanUpUpgradeExternalLinks = cleanUpUpgradeExternalLinks; + } + + public boolean isMakePathsRelative() { + return makePathsRelative; + } + + public void setMakePathsRelative(boolean makePathsRelative) { + this.makePathsRelative = makePathsRelative; + } + + public boolean isRenamePDF() { + return renamePDF; + } + + public void setRenamePDF(boolean renamePDF) { + this.renamePDF = renamePDF; + } + + public boolean isConvertHTMLToLatex() { + return convertHTMLToLatex; + } + + /** + * Converts HTML code to LaTeX code + */ + public void setConvertHTMLToLatex(boolean convertHTMLToLatex) { + this.convertHTMLToLatex = convertHTMLToLatex; + } + + public boolean isConvertCase() { + return convertCase; + } + + /** + * Adds curly brackets {} around keywords + */ + public void setConvertCase(boolean convertCase) { + this.convertCase = convertCase; + } + + public boolean isConvertLaTeX() { + return convertLaTeX; + } + + + public void setConvertLaTeX(boolean convertLaTeX) { + this.convertLaTeX = convertLaTeX; + } + + public boolean isConvertUnits() { + return convertUnits; + } + + public void setConvertUnits(boolean convertUnits) { + this.convertUnits = convertUnits; + } + + /** + * Converts Unicode characters to LaTeX code + */ + public boolean isConvertUnicodeToLatex() { + return convertUnicodeToLatex; + } + + public void setConvertUnicodeToLatex(boolean convertUnicodeToLatex) { + this.convertUnicodeToLatex = convertUnicodeToLatex; + } + + /** + * Converts to BibLatex format + */ + public boolean isConvertToBiblatex() { + return convertToBiblatex; + } + + public void setConvertToBiblatex(boolean convertToBiblatex) { + this.convertToBiblatex = convertToBiblatex; + } + + public boolean isRenamePdfOnlyRelativePaths() { + return renamePdfOnlyRelativePaths; + } + + public void setRenamePdfOnlyRelativePaths(boolean renamePdfOnlyRelativePaths) { + this.renamePdfOnlyRelativePaths = renamePdfOnlyRelativePaths; + } + + public boolean isFixFileLinks() { + return fixFileLinks; + } + + public void setFixFileLinks(boolean fixFileLinks) { + this.fixFileLinks = fixFileLinks; + } + +} diff --git a/src/main/java/net/sf/jabref/logic/cleanup/CleanupWorker.java b/src/main/java/net/sf/jabref/logic/cleanup/CleanupWorker.java new file mode 100644 index 00000000000..1267bc91dd6 --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/cleanup/CleanupWorker.java @@ -0,0 +1,115 @@ +/* Copyright (C) 2003-2015 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package net.sf.jabref.logic.cleanup; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import net.sf.jabref.logic.FieldChange; +import net.sf.jabref.logic.formatter.BibtexFieldFormatters; +import net.sf.jabref.model.database.BibDatabase; +import net.sf.jabref.model.entry.BibEntry; + +public class CleanupWorker { + + private final CleanupPreset preset; + private final List paths; + private final BibDatabase database; + + + public CleanupWorker(CleanupPreset preset) { + this(preset, Collections.emptyList()); + } + + public CleanupWorker(CleanupPreset preset, List paths) { + this(preset, paths, null); + } + + public CleanupWorker(CleanupPreset preset, List paths, BibDatabase database) { + this.preset = Objects.requireNonNull(preset); + this.paths = Objects.requireNonNull(paths); + this.database = database; + } + + public List cleanup(BibEntry entry) { + Objects.requireNonNull(entry); + + ArrayList jobs = determineCleanupActions(); + + ArrayList changes = new ArrayList<>(); + for (CleanupJob job : jobs) { + changes.addAll(job.cleanup(entry)); + } + + return changes; + } + + private ArrayList determineCleanupActions() { + ArrayList jobs = new ArrayList<>(); + + if (preset.isCleanUpUpgradeExternalLinks()) { + jobs.add(new UpgradePdfPsToFileCleanup(Arrays.asList("pdf", "ps"))); + } + if (preset.isCleanUpSuperscripts()) { + jobs.add(new FormatterCleanup(BibtexFieldFormatters.SUPERSCRIPTS)); + } + if (preset.isCleanUpDOI()) { + jobs.add(new DoiCleanup()); + } + if (preset.isCleanUpMonth()) { + jobs.add(FieldFormatterCleanup.MONTH); + } + if (preset.isCleanUpPageNumbers()) { + jobs.add(FieldFormatterCleanup.PAGE_NUMBERS); + } + if (preset.isCleanUpDate()) { + jobs.add(FieldFormatterCleanup.DATES); + } + if (preset.isFixFileLinks()) { + jobs.add(new FileLinksCleanup()); + } + if (preset.isMakePathsRelative()) { + jobs.add(new RelativePathsCleanup(paths)); + } + if (preset.isRenamePDF()) { + RenamePdfCleanup cleaner = new RenamePdfCleanup(paths, preset.isRenamePdfOnlyRelativePaths(), database); + jobs.add(cleaner); + // Reenable this: + //unsuccessfulRenames += cleaner.getUnsuccessfulRenames(); + } + if (preset.isConvertHTMLToLatex()) { + jobs.add(FieldFormatterCleanup.TITLE_HTML); + } + if (preset.isConvertUnits()) { + jobs.add(FieldFormatterCleanup.TITLE_UNITS); + } + if (preset.isConvertCase()) { + jobs.add(FieldFormatterCleanup.TITLE_CASE); + } + if (preset.isConvertLaTeX()) { + jobs.add(FieldFormatterCleanup.TITLE_LATEX); + } + if (preset.isConvertUnicodeToLatex()) { + jobs.add(new UnicodeCleanup()); + } + if (preset.isConvertToBiblatex()) { + jobs.add(new BiblatexCleanup()); + } + return jobs; + } +} diff --git a/src/main/java/net/sf/jabref/logic/cleanup/DoiCleanup.java b/src/main/java/net/sf/jabref/logic/cleanup/DoiCleanup.java index 9be5ebb6c49..70e8e733f96 100644 --- a/src/main/java/net/sf/jabref/logic/cleanup/DoiCleanup.java +++ b/src/main/java/net/sf/jabref/logic/cleanup/DoiCleanup.java @@ -1,3 +1,17 @@ +/* Copyright (C) 2003-2015 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + package net.sf.jabref.logic.cleanup; import java.util.ArrayList; @@ -11,7 +25,7 @@ /** * Formats the DOI (e.g. removes http part) and also moves DOIs from note, url or ee field to the doi field. */ -public class DoiCleanup implements Cleaner { +public class DoiCleanup implements CleanupJob { /** * Fields to check for DOIs. diff --git a/src/main/java/net/sf/jabref/logic/cleanup/FieldFormatterCleanup.java b/src/main/java/net/sf/jabref/logic/cleanup/FieldFormatterCleanup.java index 66ddb41b7e4..346425ccfb3 100644 --- a/src/main/java/net/sf/jabref/logic/cleanup/FieldFormatterCleanup.java +++ b/src/main/java/net/sf/jabref/logic/cleanup/FieldFormatterCleanup.java @@ -1,7 +1,21 @@ +/* Copyright (C) 2003-2015 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + package net.sf.jabref.logic.cleanup; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; import java.util.List; import net.sf.jabref.importer.HTMLConverter; @@ -17,18 +31,18 @@ /** * Formats a given entry field with the specified formatter. */ -public class FieldFormatterCleanup implements Cleaner { +public class FieldFormatterCleanup implements CleanupJob { private final String field; private final Formatter formatter; - public static Cleaner PAGE_NUMBERS = new FieldFormatterCleanup("pages", BibtexFieldFormatters.PAGE_NUMBERS); - public static Cleaner DATES = new FieldFormatterCleanup("date", BibtexFieldFormatters.DATE); - public static Cleaner MONTH = new FieldFormatterCleanup("month", new MonthFormatter()); - public static Cleaner TITLE_CASE = new FieldFormatterCleanup("title", new CaseKeeper()); - public static Cleaner TITLE_UNITS = new FieldFormatterCleanup("title", new UnitFormatter()); - public static Cleaner TITLE_LATEX = new FieldFormatterCleanup("title", new LatexFormatter()); - public static Cleaner TITLE_HTML = new FieldFormatterCleanup("title", new HTMLConverter()); + public static CleanupJob PAGE_NUMBERS = new FieldFormatterCleanup("pages", BibtexFieldFormatters.PAGE_NUMBERS); + public static CleanupJob DATES = new FieldFormatterCleanup("date", BibtexFieldFormatters.DATE); + public static CleanupJob MONTH = new FieldFormatterCleanup("month", new MonthFormatter()); + public static CleanupJob TITLE_CASE = new FieldFormatterCleanup("title", new CaseKeeper()); + public static CleanupJob TITLE_UNITS = new FieldFormatterCleanup("title", new UnitFormatter()); + public static CleanupJob TITLE_LATEX = new FieldFormatterCleanup("title", new LatexFormatter()); + public static CleanupJob TITLE_HTML = new FieldFormatterCleanup("title", new HTMLConverter()); public FieldFormatterCleanup(String field, Formatter formatter) { @@ -50,7 +64,7 @@ public List cleanup(BibEntry entry) { if (!oldValue.equals(newValue)) { entry.setField(field, newValue); FieldChange change = new FieldChange(entry, field, oldValue, newValue); - return Arrays.asList(new FieldChange[] {change}); + return Collections.singletonList(change); } else { return new ArrayList<>(); } diff --git a/src/main/java/net/sf/jabref/logic/cleanup/FileLinksCleanup.java b/src/main/java/net/sf/jabref/logic/cleanup/FileLinksCleanup.java new file mode 100644 index 00000000000..13c63b9eb54 --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/cleanup/FileLinksCleanup.java @@ -0,0 +1,31 @@ +/* Copyright (C) 2003-2015 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +package net.sf.jabref.logic.cleanup; + +import java.util.List; + +import net.sf.jabref.logic.FieldChange; +import net.sf.jabref.model.entry.BibEntry; +import net.sf.jabref.util.CleanupUtil; + +/** + * Fixes the format of the file field. For example, if the file link is empty but the description wrongly contains the path. + */ +public class FileLinksCleanup implements CleanupJob { + + @Override + public List cleanup(BibEntry entry) { + return CleanupUtil.fixFileEntries(entry); + } +} diff --git a/src/main/java/net/sf/jabref/logic/cleanup/FormatterCleanup.java b/src/main/java/net/sf/jabref/logic/cleanup/FormatterCleanup.java index 85b4805bbe6..f7ee6103857 100644 --- a/src/main/java/net/sf/jabref/logic/cleanup/FormatterCleanup.java +++ b/src/main/java/net/sf/jabref/logic/cleanup/FormatterCleanup.java @@ -1,3 +1,17 @@ +/* Copyright (C) 2003-2015 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + package net.sf.jabref.logic.cleanup; import java.util.ArrayList; @@ -10,7 +24,7 @@ /** * Runs a formatter on every field. */ -public class FormatterCleanup implements Cleaner { +public class FormatterCleanup implements CleanupJob { private final Formatter formatter; diff --git a/src/main/java/net/sf/jabref/logic/cleanup/RelativePathsCleanup.java b/src/main/java/net/sf/jabref/logic/cleanup/RelativePathsCleanup.java new file mode 100644 index 00000000000..c27fb65eb86 --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/cleanup/RelativePathsCleanup.java @@ -0,0 +1,37 @@ +/* Copyright (C) 2003-2015 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +package net.sf.jabref.logic.cleanup; + +import java.util.List; + +import net.sf.jabref.logic.FieldChange; +import net.sf.jabref.model.entry.BibEntry; +import net.sf.jabref.util.CleanupUtil; + + +public class RelativePathsCleanup implements CleanupJob { + + private final List paths; + + + public RelativePathsCleanup(List paths) { + this.paths = paths; + } + + @Override + public List cleanup(BibEntry entry) { + return CleanupUtil.makePathsRelative(entry, paths.toArray(new String[] {})); + } + +} diff --git a/src/main/java/net/sf/jabref/logic/cleanup/RemoveFieldCleanup.java b/src/main/java/net/sf/jabref/logic/cleanup/RemoveFieldCleanup.java index c7805a81b0d..ac8f62d41ec 100644 --- a/src/main/java/net/sf/jabref/logic/cleanup/RemoveFieldCleanup.java +++ b/src/main/java/net/sf/jabref/logic/cleanup/RemoveFieldCleanup.java @@ -1,7 +1,21 @@ +/* Copyright (C) 2003-2015 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + package net.sf.jabref.logic.cleanup; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; import java.util.List; import net.sf.jabref.logic.FieldChange; @@ -10,7 +24,7 @@ /** * Removes a given field. */ -public class RemoveFieldCleanup implements Cleaner { +public class RemoveFieldCleanup implements CleanupJob { private final String field; @@ -29,7 +43,7 @@ public List cleanup(BibEntry entry) { entry.clearField(field); FieldChange change = new FieldChange(entry, field, oldValue, null); - return Arrays.asList(new FieldChange[] {change}); + return Collections.singletonList(change); } } diff --git a/src/main/java/net/sf/jabref/logic/cleanup/RenamePdfCleanup.java b/src/main/java/net/sf/jabref/logic/cleanup/RenamePdfCleanup.java new file mode 100644 index 00000000000..eb12f30cf8e --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/cleanup/RenamePdfCleanup.java @@ -0,0 +1,45 @@ +/* Copyright (C) 2003-2015 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +package net.sf.jabref.logic.cleanup; + +import java.util.List; + +import net.sf.jabref.logic.FieldChange; +import net.sf.jabref.model.database.BibDatabase; +import net.sf.jabref.model.entry.BibEntry; +import net.sf.jabref.util.CleanupUtil; + +public class RenamePdfCleanup implements CleanupJob { + + private final List paths; + private final BibDatabase database; + private final Boolean onlyRelativePaths; + private int unsuccessfulRenames; + + + public RenamePdfCleanup(List paths, Boolean onlyRelativePaths, BibDatabase database) { + this.paths = paths; + this.database = database; + this.onlyRelativePaths = onlyRelativePaths; + } + + @Override + public List cleanup(BibEntry entry) { + return CleanupUtil.renameFiles(entry, onlyRelativePaths, database, paths); + } + + public int getUnsuccessfulRenames() { + return unsuccessfulRenames; + } +} diff --git a/src/main/java/net/sf/jabref/gui/actions/UnicodeCleanup.java b/src/main/java/net/sf/jabref/logic/cleanup/UnicodeCleanup.java similarity index 52% rename from src/main/java/net/sf/jabref/gui/actions/UnicodeCleanup.java rename to src/main/java/net/sf/jabref/logic/cleanup/UnicodeCleanup.java index 5ffa09a7ef6..4662542be7a 100644 --- a/src/main/java/net/sf/jabref/gui/actions/UnicodeCleanup.java +++ b/src/main/java/net/sf/jabref/logic/cleanup/UnicodeCleanup.java @@ -1,17 +1,30 @@ -package net.sf.jabref.gui.actions; +/* Copyright (C) 2003-2015 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package net.sf.jabref.logic.cleanup; import java.util.ArrayList; import java.util.List; import net.sf.jabref.importer.HTMLConverter; import net.sf.jabref.logic.FieldChange; -import net.sf.jabref.logic.cleanup.Cleaner; import net.sf.jabref.model.entry.BibEntry; /** * Converts Unicode characters to LaTeX code. */ -public class UnicodeCleanup implements Cleaner { +public class UnicodeCleanup implements CleanupJob { @Override public List cleanup(BibEntry entry) { diff --git a/src/main/java/net/sf/jabref/logic/cleanup/UpgradePdfPsToFileCleanup.java b/src/main/java/net/sf/jabref/logic/cleanup/UpgradePdfPsToFileCleanup.java new file mode 100644 index 00000000000..16ed75325a4 --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/cleanup/UpgradePdfPsToFileCleanup.java @@ -0,0 +1,40 @@ +/* Copyright (C) 2003-2015 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package net.sf.jabref.logic.cleanup; + +import java.util.List; +import java.util.Objects; + +import net.sf.jabref.logic.FieldChange; +import net.sf.jabref.model.entry.BibEntry; +import net.sf.jabref.util.CleanupUtil; + +/** + * Collects file links from the given set of fields, and add them to the list contained in the file field. + */ +public class UpgradePdfPsToFileCleanup implements CleanupJob { + + private final List fields; + + + public UpgradePdfPsToFileCleanup(List fields) { + this.fields = Objects.requireNonNull(fields); + } + + @Override + public List cleanup(BibEntry entry) { + return CleanupUtil.upgradePdfPsToFile(entry, fields); + } +} diff --git a/src/main/java/net/sf/jabref/logic/preferences/PreferenceStorage.java b/src/main/java/net/sf/jabref/logic/preferences/PreferenceStorage.java new file mode 100644 index 00000000000..62046a6aeea --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/preferences/PreferenceStorage.java @@ -0,0 +1,11 @@ +package net.sf.jabref.logic.preferences; + +import net.sf.jabref.logic.cleanup.CleanupPreset; + +public interface PreferenceStorage { + + void storeCleanupPreset(CleanupPreset preset); + + CleanupPreset retrieveCleanupPreset(); + +} \ No newline at end of file diff --git a/src/main/java/net/sf/jabref/migrations/FileLinksUpgradeWarning.java b/src/main/java/net/sf/jabref/migrations/FileLinksUpgradeWarning.java index b1d0aea9509..2063308ce03 100644 --- a/src/main/java/net/sf/jabref/migrations/FileLinksUpgradeWarning.java +++ b/src/main/java/net/sf/jabref/migrations/FileLinksUpgradeWarning.java @@ -32,7 +32,7 @@ import net.sf.jabref.logic.l10n.Localization; import net.sf.jabref.model.database.BibDatabase; import net.sf.jabref.model.entry.BibEntry; -import net.sf.jabref.util.Util; +import net.sf.jabref.util.CleanupUtil; /** * This class defines the warning that can be offered when opening a pre-2.3 @@ -184,7 +184,8 @@ private void makeChanges(BasePanel panel, ParserResult pr, boolean upgradePrefs, if (upgradeDatabase) { // Update file links links in the database: - NamedCompound ce = Util.upgradePdfPsToFile(pr.getDatabase(), FileLinksUpgradeWarning.FIELDS_TO_LOOK_FOR); + NamedCompound ce = CleanupUtil.upgradePdfPsToFile(pr.getDatabase(), + FileLinksUpgradeWarning.FIELDS_TO_LOOK_FOR); panel.undoManager.addEdit(ce); panel.markBaseChanged(); } diff --git a/src/main/java/net/sf/jabref/util/CleanupUtil.java b/src/main/java/net/sf/jabref/util/CleanupUtil.java new file mode 100644 index 00000000000..dcf559f23d7 --- /dev/null +++ b/src/main/java/net/sf/jabref/util/CleanupUtil.java @@ -0,0 +1,235 @@ +package net.sf.jabref.util; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import net.sf.jabref.Globals; +import net.sf.jabref.external.ExternalFileType; +import net.sf.jabref.gui.FileListEntry; +import net.sf.jabref.gui.FileListTableModel; +import net.sf.jabref.gui.undo.NamedCompound; +import net.sf.jabref.gui.undo.UndoableFieldChange; +import net.sf.jabref.logic.FieldChange; +import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.util.io.FileUtil; +import net.sf.jabref.model.database.BibDatabase; +import net.sf.jabref.model.entry.BibEntry; + +// TODO: Move to cleanup classes. +public class CleanupUtil { + + /** + * Collect file links from the given set of fields, and add them to the list contained in the field + * GUIGlobals.FILE_FIELD. + * + * @param database The database to modify. + * @param fields The fields to find links in. + * @return A CompoundEdit specifying the undo operation for the whole operation. + */ + public static NamedCompound upgradePdfPsToFile(BibDatabase database, String[] fields) { + NamedCompound ce = new NamedCompound(Localization.lang("Move external links to 'file' field")); + + for (BibEntry entry : database.getEntryMap().values()) { + List changes = upgradePdfPsToFile(entry, Arrays.asList(fields)); + + for (FieldChange change : changes) { + ce.addEdit(new UndoableFieldChange(change)); + } + } + + ce.end(); + return ce; + } + + /** + * Collect file links from the given set of fields, and add them to the list + * contained in the field GUIGlobals.FILE_FIELD. + * + * @param entries The entries to modify. + * @param fields The fields to find links in. + * @return + * @return A CompoundEdit specifying the undo operation for the whole operation. + */ + public static List upgradePdfPsToFile(BibEntry entry, List fields) { + List changes = new ArrayList<>(); + + FileListTableModel tableModel = new FileListTableModel(); + // If there are already links in the file field, keep those on top: + String oldFileContent = entry.getField(Globals.FILE_FIELD); + if (oldFileContent != null) { + tableModel.setContent(oldFileContent); + } + int oldRowCount = tableModel.getRowCount(); + for (String field : fields) { + String o = entry.getField(field); + if (o != null) { + if (!o.trim().isEmpty()) { + File f = new File(o); + FileListEntry flEntry = new FileListEntry(f.getName(), o, + Globals.prefs.getExternalFileTypeByExt(field)); + tableModel.addEntry(tableModel.getRowCount(), flEntry); + + entry.clearField(field); + changes.add(new FieldChange(entry, field, o, null)); + } + } + } + if (tableModel.getRowCount() != oldRowCount) { + String newValue = tableModel.getStringRepresentation(); + entry.setField(Globals.FILE_FIELD, newValue); + changes.add(new FieldChange(entry, Globals.FILE_FIELD, oldFileContent, newValue)); + } + + return changes; + } + + public static List fixFileEntries(BibEntry entry) { + String oldValue = entry.getField(Globals.FILE_FIELD); + if (oldValue == null) { + return new ArrayList<>(); + } + FileListTableModel flModel = new FileListTableModel(); + flModel.setContent(oldValue); + if (flModel.getRowCount() == 0) { + return new ArrayList<>(); + } + boolean changed = false; + for (int i = 0; i < flModel.getRowCount(); i++) { + FileListEntry flEntry = flModel.getEntry(i); + String link = flEntry.getLink(); + String description = flEntry.getDescription(); + if ("".equals(link) && (!"".equals(description))) { + // link and description seem to be switched, quickly fix that + flEntry.setLink(flEntry.getDescription()); + flEntry.setDescription(""); + changed = true; + } + } + if (changed) { + String newValue = flModel.getStringRepresentation(); + assert(!oldValue.equals(newValue)); + entry.setField(Globals.FILE_FIELD, newValue); + FieldChange change = new FieldChange(entry, Globals.FILE_FIELD, oldValue, newValue); + return Collections.singletonList(change); + } + return new ArrayList<>(); + } + + public static List makePathsRelative(BibEntry entry, String[] paths) { + String oldValue = entry.getField(Globals.FILE_FIELD); + if (oldValue == null) { + return new ArrayList<>(); + } + FileListTableModel flModel = new FileListTableModel(); + flModel.setContent(oldValue); + if (flModel.getRowCount() == 0) { + return new ArrayList<>(); + } + boolean changed = false; + for (int i = 0; i < flModel.getRowCount(); i++) { + FileListEntry flEntry = flModel.getEntry(i); + String oldFileName = flEntry.getLink(); + String newFileName = FileUtil.shortenFileName(new File(oldFileName), paths).toString(); + if (!oldFileName.equals(newFileName)) { + flEntry.setLink(newFileName); + changed = true; + } + } + if (changed) { + String newValue = flModel.getStringRepresentation(); + assert(!oldValue.equals(newValue)); + entry.setField(Globals.FILE_FIELD, newValue); + FieldChange change = new FieldChange(entry, Globals.FILE_FIELD, oldValue, newValue); + return Collections.singletonList(change); + } + return new ArrayList<>(); + } + + // TODO: Remove dependence on database if possible + public static List renameFiles(BibEntry entry, boolean onlyRelativePaths, BibDatabase database, + List paths) { + //Extract the path + String oldValue = entry.getField(Globals.FILE_FIELD); + if (oldValue == null) { + return new ArrayList<>(); + } + FileListTableModel flModel = new FileListTableModel(); + flModel.setContent(oldValue); + if (flModel.getRowCount() == 0) { + return new ArrayList<>(); + } + boolean changed = false; + + for (int i = 0; i < flModel.getRowCount(); i++) { + String realOldFilename = flModel.getEntry(i).getLink(); + + if (onlyRelativePaths && (new File(realOldFilename).isAbsolute())) { + continue; + } + + String newFilename = Util.getLinkedFileName(database, entry); + //String oldFilename = bes.getField(GUIGlobals.FILE_FIELD); // would have to be stored for undoing purposes + + //Add extension to newFilename + newFilename = newFilename + "." + flModel.getEntry(i).getType().getExtension(); + + //get new Filename with path + //Create new Path based on old Path and new filename + File expandedOldFile = FileUtil.expandFilename(realOldFilename, paths.toArray(new String[] {})); + if ((expandedOldFile == null) || (expandedOldFile.getParent() == null)) { + // something went wrong. Just skip this entry + continue; + } + String newPath = expandedOldFile.getParent().concat(System.getProperty("file.separator")) + .concat(newFilename); + + if (new File(newPath).exists()) { + // we do not overwrite files + // TODO: we could check here if the newPath file is linked with the current entry. And if not, we could add a link + continue; + } + + //do rename + boolean renameSuccessful = FileUtil.renameFile(expandedOldFile.toString(), newPath); + + if (renameSuccessful) { + changed = true; + + //Change the path for this entry + String description = flModel.getEntry(i).getDescription(); + ExternalFileType type = flModel.getEntry(i).getType(); + flModel.removeEntry(i); + + // we cannot use "newPath" to generate a FileListEntry as newPath is absolute, but we want to keep relative paths whenever possible + File parent = (new File(realOldFilename)).getParentFile(); + String newFileEntryFileName; + if (parent == null) { + newFileEntryFileName = newFilename; + } else { + newFileEntryFileName = parent.toString().concat(System.getProperty("file.separator")) + .concat(newFilename); + } + flModel.addEntry(i, new FileListEntry(description, newFileEntryFileName, type)); + } else { + // TODO: Reenable this + //unsuccessfulRenames++; + } + } + + if (changed) { + String newValue = flModel.getStringRepresentation(); + assert(!oldValue.equals(newValue)); + entry.setField(Globals.FILE_FIELD, newValue); + //we put an undo of the field content here + //the file is not being renamed back, which leads to inconsistencies + //if we put a null undo object here, the change by "doMakePathsRelative" would overwrite the field value nevertheless. + FieldChange change = new FieldChange(entry, Globals.FILE_FIELD, oldValue, newValue); + return Arrays.asList(new FieldChange[] {change}); + } + + return new ArrayList<>(); + } +} diff --git a/src/main/java/net/sf/jabref/util/Util.java b/src/main/java/net/sf/jabref/util/Util.java index 123ed0b745c..e322cb3a753 100644 --- a/src/main/java/net/sf/jabref/util/Util.java +++ b/src/main/java/net/sf/jabref/util/Util.java @@ -55,7 +55,6 @@ import net.sf.jabref.logic.util.strings.UnicodeCharMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import net.sf.jabref.gui.worker.AbstractWorker; import net.sf.jabref.model.database.BibDatabase; import net.sf.jabref.model.entry.BibEntry; @@ -337,61 +336,7 @@ private static void setAutomaticFields(BibEntry entry, boolean setOwner, String } } - /** - * Collect file links from the given set of fields, and add them to the list contained in the field - * GUIGlobals.FILE_FIELD. - * - * @param database The database to modify. - * @param fields The fields to find links in. - * @return A CompoundEdit specifying the undo operation for the whole operation. - */ - public static NamedCompound upgradePdfPsToFile(BibDatabase database, String[] fields) { - NamedCompound ce = new NamedCompound(Localization.lang("Move external links to 'file' field")); - for (BibEntry entry : database.getEntryMap().values()) { - upgradePdfPsToFile(entry, fields, ce); - } - - ce.end(); - return ce; - } - - /** - * TODO: Move this to cleanup class. Collect file links from the given set of fields, and add them to the list - * contained in the field GUIGlobals.FILE_FIELD. - * - * @param entries The entries to modify. - * @param fields The fields to find links in. - * @return A CompoundEdit specifying the undo operation for the whole operation. - */ - public static void upgradePdfPsToFile(BibEntry entry, String[] fields, NamedCompound ce) { - FileListTableModel tableModel = new FileListTableModel(); - // If there are already links in the file field, keep those on top: - String oldFileContent = entry.getField(Globals.FILE_FIELD); - if (oldFileContent != null) { - tableModel.setContent(oldFileContent); - } - int oldRowCount = tableModel.getRowCount(); - for (String field : fields) { - String o = entry.getField(field); - if (o != null) { - if (!o.trim().isEmpty()) { - File f = new File(o); - FileListEntry flEntry = new FileListEntry(f.getName(), o, - Globals.prefs.getExternalFileTypeByExt(field)); - tableModel.addEntry(tableModel.getRowCount(), flEntry); - - entry.clearField(field); - ce.addEdit(new UndoableFieldChange(entry, field, o, null)); - } - } - } - if (tableModel.getRowCount() != oldRowCount) { - String newValue = tableModel.getStringRepresentation(); - entry.setField(Globals.FILE_FIELD, newValue); - ce.addEdit(new UndoableFieldChange(entry, Globals.FILE_FIELD, oldFileContent, newValue)); - } - } /** * This method looks up what kind of external binding is used for the given field, and constructs on OpenFileFilter @@ -718,7 +663,7 @@ public static boolean warnAssignmentSideEffects(AbstractGroup[] groups, BibEntry if (affectedFields.isEmpty()) { return true; // no side effects } - + // show a warning, then return StringBuffer message = new StringBuffer("This action will modify the following field(s)\n" + "in at least one entry each:\n"); for (int i = 0; i < affectedFields.size(); ++i) { @@ -727,7 +672,7 @@ public static boolean warnAssignmentSideEffects(AbstractGroup[] groups, BibEntry message.append("This could cause undesired changes to " + "your entries, so it is\nrecommended that you change the grouping field " + "in your group\ndefinition to \"keywords\" or a non-standard name." + "\n\nDo you still want to continue?"); int choice = JOptionPane.showConfirmDialog(parent, message, Localization.lang("Warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); return choice != JOptionPane.NO_OPTION; - + // if (groups instanceof KeywordGroup) { // KeywordGroup kg = (KeywordGroup) groups; // String field = kg.getSearchField().toLowerCase(); diff --git a/src/test/java/net/sf/jabref/logic/cleanup/CleanupWorkerTest.java b/src/test/java/net/sf/jabref/logic/cleanup/CleanupWorkerTest.java new file mode 100644 index 00000000000..51bcc61dc5f --- /dev/null +++ b/src/test/java/net/sf/jabref/logic/cleanup/CleanupWorkerTest.java @@ -0,0 +1,272 @@ +package net.sf.jabref.logic.cleanup; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import net.sf.jabref.logic.FieldChange; +import net.sf.jabref.model.entry.BibEntry; +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +public class CleanupWorkerTest { + + @Rule + public TemporaryFolder testFolder = new TemporaryFolder(); + + + @SuppressWarnings("unused") + @Test(expected = NullPointerException.class) + public void initWithNullPresetThrowsException() { + new CleanupWorker(null); + } + + @Test(expected = NullPointerException.class) + public void cleanupNullThrowsException() { + CleanupPreset preset = new CleanupPreset(); + CleanupWorker worker = new CleanupWorker(preset); + worker.cleanup(null); + } + + @Test + public void cleanupDoesNothingByDefault() { + CleanupPreset preset = new CleanupPreset(); + CleanupWorker worker = new CleanupWorker(preset); + BibEntry entry = new BibEntry(); + entry.setField("pdf", "aPdfFile"); + entry.setField("some", "1st"); + entry.setField("doi", "http://dx.doi.org/10.1016/0001-8708(80)90035-3"); + entry.setField("month", "01"); + entry.setField("pages", "1-2"); + entry.setField("date", "01/1999"); + entry.setField("pdf", "aPdfFile"); + entry.setField("ps", "aPsFile"); + entry.setField("file", "link::"); + entry.setField("journal", "test"); + // TODO: Add files for rename + relative + // TODO: Add html entries to title + // TODO: Cases + + List changes = worker.cleanup(entry); + Assert.assertEquals(Collections.emptyList(), changes); + } + + @Test + public void upgradeExternalLinksMoveFromPdfToFile() { + CleanupPreset preset = new CleanupPreset(); + preset.setCleanUpUpgradeExternalLinks(true); + BibEntry entry = new BibEntry(); + entry.setField("pdf", "aPdfFile"); + + CleanupWorker worker = new CleanupWorker(preset); + worker.cleanup(entry); + Assert.assertEquals(null, entry.getField("pdf")); + Assert.assertEquals("aPdfFile:aPdfFile:", entry.getField("file")); + } + + @Test + public void upgradeExternalLinksMoveFromPsToFile() { + CleanupPreset preset = new CleanupPreset(); + preset.setCleanUpUpgradeExternalLinks(true); + BibEntry entry = new BibEntry(); + entry.setField("ps", "aPsFile"); + + CleanupWorker worker = new CleanupWorker(preset); + worker.cleanup(entry); + Assert.assertEquals(null, entry.getField("pdf")); + Assert.assertEquals("aPsFile:aPsFile:", entry.getField("file")); + } + + @Test + public void cleanupSupercriptChangesFirstToLatex() { + CleanupPreset preset = new CleanupPreset(); + preset.setCleanUpSuperscripts(true); + BibEntry entry = new BibEntry(); + entry.setField("some", "1st"); + + CleanupWorker worker = new CleanupWorker(preset); + worker.cleanup(entry); + Assert.assertEquals("1\\textsuperscript{st}", entry.getField("some")); + } + + @Test + public void cleanupDoiRemovesLeadingHttp() { + CleanupPreset preset = new CleanupPreset(); + preset.setCleanUpDOI(true); + BibEntry entry = new BibEntry(); + entry.setField("doi", "http://dx.doi.org/10.1016/0001-8708(80)90035-3"); + + CleanupWorker worker = new CleanupWorker(preset); + worker.cleanup(entry); + Assert.assertEquals("10.1016/0001-8708(80)90035-3", entry.getField("doi")); + } + + @Test + public void cleanupDoiReturnsChanges() { + CleanupPreset preset = new CleanupPreset(); + preset.setCleanUpDOI(true); + BibEntry entry = new BibEntry(); + entry.setField("doi", "http://dx.doi.org/10.1016/0001-8708(80)90035-3"); + + CleanupWorker worker = new CleanupWorker(preset); + List changes = worker.cleanup(entry); + + FieldChange expectedChange = new FieldChange(entry, "doi", "http://dx.doi.org/10.1016/0001-8708(80)90035-3", + "10.1016/0001-8708(80)90035-3"); + Assert.assertEquals(Collections.singletonList(expectedChange), changes); + } + + @Test + public void cleanupMonthChangesNumberToBibtex() { + CleanupPreset preset = new CleanupPreset(); + preset.setCleanUpMonth(true); + BibEntry entry = new BibEntry(); + entry.setField("month", "01"); + + CleanupWorker worker = new CleanupWorker(preset); + worker.cleanup(entry); + Assert.assertEquals("#jan#", entry.getField("month")); + } + + @Test + public void cleanupPagenumbersConvertsSingleDashToDouble() { + CleanupPreset preset = new CleanupPreset(); + preset.setCleanUpPageNumbers(true); + BibEntry entry = new BibEntry(); + entry.setField("pages", "1-2"); + + CleanupWorker worker = new CleanupWorker(preset); + worker.cleanup(entry); + Assert.assertEquals("1--2", entry.getField("pages")); + } + + @Test + public void cleanupDatesConvertsToCorrectFormat() { + CleanupPreset preset = new CleanupPreset(); + preset.setCleanUpDate(true); + BibEntry entry = new BibEntry(); + entry.setField("date", "01/1999"); + + CleanupWorker worker = new CleanupWorker(preset); + worker.cleanup(entry); + Assert.assertEquals("1999-01", entry.getField("date")); + } + + @Test + public void cleanupFixFileLinksMovesSingleDescriptionToLink() { + CleanupPreset preset = new CleanupPreset(); + preset.setFixFileLinks(true); + BibEntry entry = new BibEntry(); + entry.setField("file", "link::"); + + CleanupWorker worker = new CleanupWorker(preset); + worker.cleanup(entry); + Assert.assertEquals(":link:", entry.getField("file")); + } + + @Test + @Ignore + public void cleanupRelativePathsConvertAbsoluteToRelativePath() throws IOException { + // TODO: Correct test + CleanupPreset preset = new CleanupPreset(); + preset.setMakePathsRelative(true); + + File tempFile = testFolder.newFile(); + BibEntry entry = new BibEntry(); + entry.setField("file", tempFile.getAbsolutePath()); + + CleanupWorker worker = new CleanupWorker(preset, + Collections.singletonList(testFolder.getRoot().getAbsolutePath())); + worker.cleanup(entry); + Assert.assertEquals(tempFile.getName(), entry.getField("file")); + } + + @Test + @Ignore + public void cleanupRenamePdfDoesSomething() { + // TODO: Add test + } + + @Test + @Ignore + // TODO: Bug? + public void cleanupHtmlConvertsBoldToTextbfCommand() { + CleanupPreset preset = new CleanupPreset(); + preset.setConvertHTMLToLatex(true); + BibEntry entry = new BibEntry(); + entry.setField("title", "hallo"); + + CleanupWorker worker = new CleanupWorker(preset); + worker.cleanup(entry); + Assert.assertEquals("\\textbf{hallo}", entry.getField("title")); + } + + @Test + public void cleanupUnitsConvertsOneAmpereToLatex() { + CleanupPreset preset = new CleanupPreset(); + preset.setConvertUnits(true); + BibEntry entry = new BibEntry(); + entry.setField("title", "1 A"); + + CleanupWorker worker = new CleanupWorker(preset); + worker.cleanup(entry); + Assert.assertEquals("1~{A}", entry.getField("title")); + } + + @Test + @Ignore + // TODO: BUG? + public void cleanupCasesAddsBracketAroundUppercaseWord() { + CleanupPreset preset = new CleanupPreset(); + preset.setConvertCase(true); + BibEntry entry = new BibEntry(); + entry.setField("title", "TEST"); + + CleanupWorker worker = new CleanupWorker(preset); + worker.cleanup(entry); + Assert.assertEquals("{TEST}", entry.getField("title")); + } + + @Test + public void cleanupLatexMergesTwoLatexMathEnvironments() { + CleanupPreset preset = new CleanupPreset(); + preset.setConvertLaTeX(true); + BibEntry entry = new BibEntry(); + entry.setField("title", "$\\alpha$$\\beta$"); + + CleanupWorker worker = new CleanupWorker(preset); + worker.cleanup(entry); + Assert.assertEquals("$\\alpha\\beta$", entry.getField("title")); + } + + @Test + @Ignore + // TODO: Bug? + public void cleanupUnicodeConvertsAcuteToLatex() { + CleanupPreset preset = new CleanupPreset(); + preset.setConvertUnicodeToLatex(true); + BibEntry entry = new BibEntry(); + entry.setField("abstract", "Réflexions"); + + CleanupWorker worker = new CleanupWorker(preset); + worker.cleanup(entry); + Assert.assertEquals("R\'eflexion", entry.getField("abstract")); + } + + @Test + public void convertToBiblatexMovesJournalToJournaltitle() { + CleanupPreset preset = new CleanupPreset(); + preset.setConvertToBiblatex(true); + BibEntry entry = new BibEntry(); + entry.setField("journal", "test"); + + CleanupWorker worker = new CleanupWorker(preset); + worker.cleanup(entry); + Assert.assertEquals(null, entry.getField("journal")); + Assert.assertEquals("test", entry.getField("journaltitle")); + } +}