diff --git a/src/main/java/world/bentobox/bentobox/api/logs/LogEntry.java b/src/main/java/world/bentobox/bentobox/api/logs/LogEntry.java index 786523164..061480460 100644 --- a/src/main/java/world/bentobox/bentobox/api/logs/LogEntry.java +++ b/src/main/java/world/bentobox/bentobox/api/logs/LogEntry.java @@ -1,12 +1,12 @@ package world.bentobox.bentobox.api.logs; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; - import java.util.LinkedHashMap; import java.util.Locale; import java.util.Map; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; + /** * Represents an event that occurred and that is logged. *
@@ -18,7 +18,7 @@ import java.util.Map; public class LogEntry { private final long timestamp; private final String type; - private final Map data; + private final Map data; private LogEntry(@NonNull Builder builder) { this.timestamp = builder.timestamp; @@ -36,14 +36,14 @@ public class LogEntry { } @Nullable - public Map getData() { + public Map getData() { return data; } public static class Builder { private long timestamp; private String type; - private Map data; + private Map data; public Builder(@NonNull String type) { this.timestamp = System.currentTimeMillis(); @@ -56,8 +56,8 @@ public class LogEntry { return this; } - public Builder data(Map<@NonNull String, @Nullable Object> data) { - this.data = data; + public Builder data(Map data2) { + this.data = data2; return this; } @@ -67,7 +67,7 @@ public class LogEntry { * @param value value to set * @return the Builder instance */ - public Builder data(@NonNull String key, @Nullable Object value) { + public Builder data(@NonNull String key, @Nullable String value) { this.data.put(key, value); return this; } diff --git a/src/main/java/world/bentobox/bentobox/database/objects/Island.java b/src/main/java/world/bentobox/bentobox/database/objects/Island.java index beb41e208..539dab700 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/Island.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/Island.java @@ -140,9 +140,9 @@ public class Island implements DataObject { * @param target UUID of the target, must be provided. * @return {@code true} */ - public boolean ban(@Nullable UUID issuer, @NonNull UUID target) { + public boolean ban(@NonNull UUID issuer, @NonNull UUID target) { setRank(target, RanksManager.BANNED_RANK); - log(new LogEntry.Builder("BAN").data("player", target).data("issuer", issuer).build()); + log(new LogEntry.Builder("BAN").data("player", target.toString()).data("issuer", issuer.toString()).build()); return true; } @@ -168,9 +168,9 @@ public class Island implements DataObject { * @param target UUID of the target, must be provided. * @return {@code true} if the target is successfully unbanned, {@code false} otherwise. */ - public boolean unban(@Nullable UUID issuer, @NonNull UUID target) { + public boolean unban(@NonNull UUID issuer, @NonNull UUID target) { if (members.remove(target) != null) { - log(new LogEntry.Builder("UNBAN").data("player", target).data("issuer", issuer).build()); + log(new LogEntry.Builder("UNBAN").data("player", target.toString()).data("issuer", issuer.toString()).build()); return true; } return false; diff --git a/src/main/java/world/bentobox/bentobox/database/objects/adapters/LogEntryListAdapter.java b/src/main/java/world/bentobox/bentobox/database/objects/adapters/LogEntryListAdapter.java index f37e2d314..a4f8b5954 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/adapters/LogEntryListAdapter.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/adapters/LogEntryListAdapter.java @@ -1,14 +1,11 @@ package world.bentobox.bentobox.database.objects.adapters; -import org.eclipse.jdt.annotation.NonNull; -import world.bentobox.bentobox.api.logs.LogEntry; - -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.UUID; + +import world.bentobox.bentobox.api.logs.LogEntry; /** * @author Poslovitch @@ -45,7 +42,7 @@ public class LogEntryListAdapter implements AdapterInterface, Lis for (Map entry : serialized) { long timestamp = (long) entry.get(TIMESTAMP); String type = (String) entry.get(TYPE); - Map data = (Map) entry.get(DATA); + Map data = (Map) entry.get(DATA); result.add(new LogEntry.Builder(type).timestamp(timestamp).data(data).build()); } @@ -68,7 +65,7 @@ public class LogEntryListAdapter implements AdapterInterface, Lis value.put(TYPE, logEntry.getType()); if (logEntry.getData() != null) { - value.put(DATA, tidy(logEntry.getData())); + value.put(DATA, logEntry.getData()); } result.add(value); @@ -77,24 +74,4 @@ public class LogEntryListAdapter implements AdapterInterface, Lis return result; } - /** - * Returns a "data" map that contains "tidied up" values, as some types are not safe to store 'as is'. - * See https://github.com/BentoBoxWorld/BentoBox/issues/486 - * @param data the data map to tidy up - * @return the tidied up data map - * @since 1.1.1 - */ - @NonNull - private Map tidy(@NonNull Map data) { - Map result = new HashMap<>(); - for (Map.Entry entry : data.entrySet()) { - if (entry.getValue() instanceof UUID) { - // UUIDs need some special handling - result.put(entry.getKey(), entry.getValue().toString()); - } else { - result.put(entry.getKey(), entry.getValue()); - } - } - return result; - } } diff --git a/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseConnector.java b/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseConnector.java index 4e0c7f407..ce5257787 100644 --- a/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseConnector.java +++ b/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseConnector.java @@ -1,22 +1,23 @@ package world.bentobox.bentobox.database.yaml; +import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; +import java.io.PrintWriter; import java.io.Writer; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.sql.Connection; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Scanner; -import java.util.UUID; +import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; import com.google.common.base.Charsets; @@ -59,7 +60,20 @@ public class YamlDatabaseConnector implements DatabaseConnector { config = new YamlConfiguration(); config.load(yamlFile); } catch (Exception e) { - plugin.logError("Could not load yml file from database " + tableName + " " + fileName + " " + e.getMessage()); + /* + * TODO: Temporary fix for removing UUID tags. Remove in a few versions + */ + if (e.getMessage().contains("!!java.util.UUID")) { + removeStringFromFile(yamlFile); + // Try again + try { + Objects.requireNonNull(config).load(yamlFile); + } catch (IOException | InvalidConfigurationException e1) { + plugin.logError("Could not load yml file from database " + tableName + " " + fileName + " " + e.getMessage()); + } + } else { + plugin.logError("Could not load yml file from database " + tableName + " " + fileName + " " + e.getMessage()); + } } } else { // Create the missing file @@ -81,6 +95,25 @@ public class YamlDatabaseConnector implements DatabaseConnector { return config; } + private void removeStringFromFile(File yamlFile) { + try { + File temp = File.createTempFile("file", ".tmp", yamlFile.getParentFile()); + BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(yamlFile), StandardCharsets.UTF_8)); + PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(temp), StandardCharsets.UTF_8)); + for (String line; (line = reader.readLine()) != null;) { + line = line.replace("!!java.util.UUID", ""); + writer.println(line); + } + reader.close(); + writer.close(); + if (yamlFile.delete()) { + temp.renameTo(yamlFile); + } + } catch (Exception e) { + plugin.logError("Could not fix Island object - skipping - " + e.getMessage()); + } + } + public void saveYamlFile(String data, String tableName, String fileName, Map commentMap) { String name = fileName.endsWith(YML) ? fileName : fileName + YML; File tableFolder = new File(plugin.getDataFolder(), tableName); diff --git a/src/test/java/world/bentobox/bentobox/TestBentoBox.java b/src/test/java/world/bentobox/bentobox/TestBentoBox.java index ab994a03f..005c89010 100644 --- a/src/test/java/world/bentobox/bentobox/TestBentoBox.java +++ b/src/test/java/world/bentobox/bentobox/TestBentoBox.java @@ -402,7 +402,7 @@ public class TestBentoBox { assertFalse(members.contains(member3)); // Ban member - island.ban(null, member1); + island.ban(UUID.randomUUID(), member1); members = island.getMemberSet(); assertTrue(members.contains(playerUUID)); assertFalse(members.contains(member1)); @@ -413,7 +413,7 @@ public class TestBentoBox { assertTrue(banned.contains(member1)); // Unban - island.unban(null, member1); + island.unban(UUID.randomUUID(), member1); assertFalse(island.getBanned().contains(member1)); // Protection @@ -445,7 +445,7 @@ public class TestBentoBox { // Check if the members have capability User mem1 = User.getInstance(member1); // Visitor User mem2 = User.getInstance(member2); // Member - island.ban(null, member3); + island.ban(member2, member3); User mem3 = User.getInstance(member3); // Banned // Member 1 is a visitor @@ -505,7 +505,7 @@ public class TestBentoBox { assertEquals(fl, customFlag.getListener().get()); // Add it to the Flag Manager flagsManager.registerFlag(customFlag); - assertEquals(customFlag, flagsManager.getFlagByID("CUSTOM_FLAG")); + assertEquals(customFlag, flagsManager.getFlag("CUSTOM_FLAG").get()); } /** diff --git a/src/test/java/world/bentobox/bentobox/database/objects/adapters/LogEntryListAdapterTest.java b/src/test/java/world/bentobox/bentobox/database/objects/adapters/LogEntryListAdapterTest.java new file mode 100644 index 000000000..27fca6397 --- /dev/null +++ b/src/test/java/world/bentobox/bentobox/database/objects/adapters/LogEntryListAdapterTest.java @@ -0,0 +1,68 @@ +/** + * + */ +package world.bentobox.bentobox.database.objects.adapters; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +import org.bukkit.configuration.file.YamlConfiguration; +import org.junit.Before; +import org.junit.Test; + +import world.bentobox.bentobox.api.logs.LogEntry; + +/** + * @author tastybento + * + */ +public class LogEntryListAdapterTest { + + private LogEntryListAdapter a; + private YamlConfiguration config; + private List history = new LinkedList<>(); + private UUID target; + private UUID issuer; + private List toLog; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + config = new YamlConfiguration(); + a = new LogEntryListAdapter(); + target = UUID.randomUUID(); + issuer = UUID.randomUUID(); + + toLog = new ArrayList<>(); + toLog.add(new LogEntry.Builder("BAN").data("player", target.toString()).data("issuer", issuer.toString()).build()); + toLog.add(new LogEntry.Builder("UNBAN").data("player", target.toString()).data("issuer", issuer.toString()).build()); + toLog.add(new LogEntry.Builder("UNOWNED").build()); + toLog.forEach(history::add); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.adapters.LogEntryListAdapter#serialize(java.lang.Object)} + * and {@link world.bentobox.bentobox.database.objects.adapters.LogEntryListAdapter#deserialize(java.lang.Object)}. + */ + @Test + public void testSerializeDeserialize() { + config.set("test.history", a.serialize(history)); + // Verify + List historyCheck = a.deserialize(config.get("test.history")); + assertTrue(historyCheck.size() == 3); + for (int i = 0; i < historyCheck.size(); i++) { + assertEquals(toLog.get(i).getTimestamp(), historyCheck.get(i).getTimestamp()); + assertEquals(toLog.get(i).getType(), historyCheck.get(i).getType()); + assertEquals(toLog.get(i).getData().get("player"), historyCheck.get(i).getData().get("player")); + assertEquals(toLog.get(i).getData().get("issuer"), historyCheck.get(i).getData().get("issuer")); + } + } + +}