From 4f4af10fcbbac3448aca6ef60f1644f8a6752261 Mon Sep 17 00:00:00 2001 From: GoldenGnu Date: Wed, 18 Dec 2024 19:11:30 +0100 Subject: [PATCH] Bug Fix: Importing tracker data replaced existing data --- .../jeveasset/data/settings/TrackerData.java | 27 +++++++- .../gui/tabs/tracker/TrackerTab.java | 42 ++++++++++-- .../eve/jeveasset/gui/tabs/values/Value.java | 12 ++++ .../nikr/eve/jeveasset/i18n/TabsTracker.java | 8 ++- .../eve/jeveasset/i18n/TabsTracker.properties | 12 ++-- .../data/settings/TrackerDataTest.java | 64 +++++++++++++++++++ 6 files changed, 149 insertions(+), 16 deletions(-) create mode 100644 src/test/java/net/nikr/eve/jeveasset/data/settings/TrackerDataTest.java diff --git a/src/main/java/net/nikr/eve/jeveasset/data/settings/TrackerData.java b/src/main/java/net/nikr/eve/jeveasset/data/settings/TrackerData.java index a948f27bf4..9d34bc8c13 100644 --- a/src/main/java/net/nikr/eve/jeveasset/data/settings/TrackerData.java +++ b/src/main/java/net/nikr/eve/jeveasset/data/settings/TrackerData.java @@ -25,6 +25,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.TreeSet; import java.util.concurrent.locks.ReentrantReadWriteLock; import net.nikr.eve.jeveasset.CliOptions; import net.nikr.eve.jeveasset.gui.tabs.values.Value; @@ -37,7 +39,7 @@ public class TrackerData { private static final Logger LOG = LoggerFactory.getLogger(TrackerData.class); - private static final Map> TRACKER_DATA = new HashMap>(); //ownerID :: long + private static final Map> TRACKER_DATA = new HashMap<>(); //ownerID :: long private static final ReentrantReadWriteLock LOCK = new ReentrantReadWriteLock(); private static final Object SAVE_QUEUE_SYNC = new Object(); private static Integer SAVE_QUEUE = 0; @@ -116,10 +118,29 @@ public static void add(String owner, Value add) { } } - public static void addAll(Map> trackerData) { + public static void addAll(Map> trackerData, boolean overwrite) { try { LOCK.writeLock().lock(); - TRACKER_DATA.putAll(trackerData); + for (Map.Entry> entry : trackerData.entrySet()) { + //For each owner + String owner = entry.getKey(); + List list = TRACKER_DATA.get(owner); + if (list == null) { //Owner doesn't exist + list = new ArrayList<>(); + TRACKER_DATA.put(owner, list); + } + //Remove duplicates, while staying in order + Set set = new TreeSet<>(Value.DATE_COMPARATOR); + if (overwrite) { + set.addAll(entry.getValue()); //Add new data (First) + set.addAll(list); //Add old data (Second, only add if not already contains) + } else { + set.addAll(list); //Add old data (First) + set.addAll(entry.getValue()); //Add new data (Second, only add if not already contains) + } + list.clear(); //Clear old data + list.addAll(set); //Set new merged data + } } finally { LOCK.writeLock().unlock(); } diff --git a/src/main/java/net/nikr/eve/jeveasset/gui/tabs/tracker/TrackerTab.java b/src/main/java/net/nikr/eve/jeveasset/gui/tabs/tracker/TrackerTab.java index 774b29abd4..96372b217c 100644 --- a/src/main/java/net/nikr/eve/jeveasset/gui/tabs/tracker/TrackerTab.java +++ b/src/main/java/net/nikr/eve/jeveasset/gui/tabs/tracker/TrackerTab.java @@ -152,6 +152,35 @@ private enum TrackerAction { FILTER_SKILL_POINTS } + public static enum ImportOptions { + KEEP() { + @Override + public String getName() { + return TabsTracker.get().importFileOptionsKeep(); + } + }, + OVERWRITE() { + @Override + public String getName() { + return TabsTracker.get().importFileOptionsOverwrite(); + } + }, + REPLACE() { + @Override + public String getName() { + return TabsTracker.get().importFileOptionsReplace(); + } + }; + + abstract public String getName(); + + @Override + public String toString() { + return getName(); + } + + } + private final Shape NO_FILTER = new Rectangle(-3, -3, 6, 6); private final Shape FILTER_AND_DEFAULT = new Ellipse2D.Float(-3.0f, -3.0f, 6.0f, 6.0f); private final int PANEL_WIDTH_MINIMUM = 160; @@ -1843,12 +1872,12 @@ public void task() { @Override public void hidden() { if (trackerData == null) { //Invalid file - JOptionPane.showMessageDialog(program.getMainWindow().getFrame(), TabsTracker.get().importFileInvalidMsg(), TabsTracker.get().importFileInvalidTitle(), JOptionPane.WARNING_MESSAGE); + JOptionPane.showMessageDialog(program.getMainWindow().getFrame(), TabsTracker.get().importFileInvalidMsg(), TabsTracker.get().importFileTitle(), JOptionPane.WARNING_MESSAGE); return; } //Overwrite? - int value = JOptionPane.showConfirmDialog(program.getMainWindow().getFrame(), TabsTracker.get().importFileOverwriteMsg(), TabsTracker.get().importFileOverwriteTitle(), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - if (value != JOptionPane.OK_OPTION) { + Object value = JOptionPane.showInputDialog(program.getMainWindow().getFrame(), TabsTracker.get().importFileOptionsMsg(), TabsTracker.get().importFileTitle(), JOptionPane.PLAIN_MESSAGE, null, ImportOptions.values(), ImportOptions.KEEP); + if (value == null) { return; //Cancel } SwingUtilities.invokeLater(new Runnable() { @@ -1857,10 +1886,13 @@ public void run() { jLockWindow.show(TabsTracker.get().importFileImport(), new LockWorkerAdaptor() { @Override public void task() { - TrackerData.addAll(trackerData); + if (value == ImportOptions.REPLACE) { + TrackerData.set(trackerData); + } else { + TrackerData.addAll(trackerData, value == ImportOptions.OVERWRITE); + } TrackerData.save("File Import", true); } - @Override public void gui() { updateData(); diff --git a/src/main/java/net/nikr/eve/jeveasset/gui/tabs/values/Value.java b/src/main/java/net/nikr/eve/jeveasset/gui/tabs/values/Value.java index c49ba6ada0..a172e7c0a9 100644 --- a/src/main/java/net/nikr/eve/jeveasset/gui/tabs/values/Value.java +++ b/src/main/java/net/nikr/eve/jeveasset/gui/tabs/values/Value.java @@ -21,6 +21,7 @@ package net.nikr.eve.jeveasset.gui.tabs.values; +import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -35,6 +36,8 @@ public class Value implements Comparable, LocationType { + + public static final Comparator DATE_COMPARATOR = new ValueDateComparator(); private final static long MINIMUM_SKILL_POINTS = 5000000; private final static double SKILL_EXTRACTOR_SIZE = 500000.0; private final String name; @@ -447,4 +450,13 @@ public boolean equals(Object obj) { public int compareTo(Value o) { return this.getName().compareToIgnoreCase(o.getName()); } + + private static class ValueDateComparator implements Comparator { + + @Override + public int compare(Value o1, Value o2) { + return Formatter.simpleDate(o1.date).compareTo(Formatter.simpleDate(o2.date)); + } + + } } diff --git a/src/main/java/net/nikr/eve/jeveasset/i18n/TabsTracker.java b/src/main/java/net/nikr/eve/jeveasset/i18n/TabsTracker.java index 69f778c616..e0697dd14b 100644 --- a/src/main/java/net/nikr/eve/jeveasset/i18n/TabsTracker.java +++ b/src/main/java/net/nikr/eve/jeveasset/i18n/TabsTracker.java @@ -68,9 +68,11 @@ public TabsTracker(final Locale locale) { public abstract String importFile(); public abstract String importFileImport(); public abstract String importFileInvalidMsg(); - public abstract String importFileInvalidTitle(); - public abstract String importFileOverwriteMsg(); - public abstract String importFileOverwriteTitle(); + public abstract String importFileOptionsKeep(); + public abstract String importFileOptionsMsg(); + public abstract String importFileOptionsOverwrite(); + public abstract String importFileOptionsReplace(); + public abstract String importFileTitle(); public abstract String includeZero(); public abstract String invalid(); public abstract String invalidNumberMsg(); diff --git a/src/main/resources/net/nikr/eve/jeveasset/i18n/TabsTracker.properties b/src/main/resources/net/nikr/eve/jeveasset/i18n/TabsTracker.properties index be1d8ecc3a..bc14ba0ba1 100644 --- a/src/main/resources/net/nikr/eve/jeveasset/i18n/TabsTracker.properties +++ b/src/main/resources/net/nikr/eve/jeveasset/i18n/TabsTracker.properties @@ -40,11 +40,13 @@ helpNewData=Filterable importFile=Import file... importFileImport=Importing... importFileInvalidMsg=Not a valid tracker data file -importFileInvalidTitle=Tracker Import -importFileOverwriteMsg=Are you sure you want to overwrite?\n\ -Your existing tracker data will be replaced by the imported data.\n\ -This action can not be undone! -importFileOverwriteTitle=Tracker Import +importFileOptionsKeep=Merge: On duplicates use existing data +importFileOptionsMsg=Warning: This action can not be undone!\n\ +\n\ +Select how to import: +importFileOptionsOverwrite=Merge: On duplicates use imported data +importFileOptionsReplace=Delete: Delete all exisitng data and replaced with imported data +importFileTitle=Tracker Import includeZero=Always include zero invalid=Invalid input invalidNumberMsg=Not a valid number, try again... diff --git a/src/test/java/net/nikr/eve/jeveasset/data/settings/TrackerDataTest.java b/src/test/java/net/nikr/eve/jeveasset/data/settings/TrackerDataTest.java new file mode 100644 index 0000000000..4c4c5558b7 --- /dev/null +++ b/src/test/java/net/nikr/eve/jeveasset/data/settings/TrackerDataTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2009-2024 Contributors (see credits.txt) + * + * This file is part of jEveAssets. + * + * jEveAssets 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. + * + * jEveAssets 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 jEveAssets; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +package net.nikr.eve.jeveasset.data.settings; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; +import net.nikr.eve.jeveasset.TestUtil; +import net.nikr.eve.jeveasset.gui.tabs.values.Value; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import org.junit.Test; + + +public class TrackerDataTest extends TestUtil { + + @Test + public void addAll() { + Map> values; + List list; + String owner = "owner"; + Date date = new Date(); + Value oldValue = new Value("Old", date); + Value newValue = new Value("New", date); + TrackerData.set(Collections.singletonMap(owner, new ArrayList<>(Collections.singletonList(oldValue)))); + TrackerData.addAll(Collections.singletonMap(owner, new ArrayList<>(Collections.singletonList(newValue))), true); + values = TrackerData.get(); + list = values.get(owner); + assertNotNull(list); + assertEquals(1, list.size()); + assertEquals(newValue.getName(), list.get(0).getName()); + TrackerData.set(Collections.emptyMap()); + + TrackerData.set(Collections.singletonMap(owner, new ArrayList<>(Collections.singletonList(oldValue)))); + TrackerData.addAll(Collections.singletonMap(owner, new ArrayList<>(Collections.singletonList(newValue))), false); + values = TrackerData.get(); + list = values.get(owner); + assertNotNull(list); + assertEquals(1, list.size()); + assertEquals(oldValue.getName(), list.get(0).getName()); + TrackerData.set(Collections.emptyMap()); + } + +}