diff --git a/src/main/java/com/gmail/nossr50/database/FlatFileDataFlag.java b/src/main/java/com/gmail/nossr50/database/FlatFileDataFlag.java index 58c3f6892..b67fe2806 100644 --- a/src/main/java/com/gmail/nossr50/database/FlatFileDataFlag.java +++ b/src/main/java/com/gmail/nossr50/database/FlatFileDataFlag.java @@ -6,8 +6,7 @@ public enum FlatFileDataFlag { MISSING_NAME, DUPLICATE_NAME, DUPLICATE_UUID, - BAD_UUID_DATA, //Can be because it is missing, null, or just not compatible data + BAD_UUID_DATA, //Can be because it is missing, null, or corrupted or some other reason TOO_INCOMPLETE, - JUNK, - EMPTY_LINE, + CORRUPTED_OR_UNRECOGNIZABLE, } diff --git a/src/main/java/com/gmail/nossr50/database/FlatFileDataProcessor.java b/src/main/java/com/gmail/nossr50/database/FlatFileDataProcessor.java index 674cfc47b..ddda18143 100644 --- a/src/main/java/com/gmail/nossr50/database/FlatFileDataProcessor.java +++ b/src/main/java/com/gmail/nossr50/database/FlatFileDataProcessor.java @@ -16,7 +16,7 @@ public class FlatFileDataProcessor { private final @NotNull Logger logger; private final HashSet names; private final HashSet uuids; - private int uniqueProcessingID; + private int uniqueProcessingID; //TODO: Not being used, should we use it? boolean corruptDataFound; public FlatFileDataProcessor(@NotNull Logger logger) { @@ -55,7 +55,7 @@ public class FlatFileDataProcessor { } //Flag as junk (corrupt) - builder.appendFlag(FlatFileDataFlag.JUNK); + builder.appendFlag(FlatFileDataFlag.CORRUPTED_OR_UNRECOGNIZABLE); //TODO: This block here is probably pointless if(splitDataLine.length >= 10 //The value here is kind of arbitrary, it shouldn't be too low to avoid false positives, but also we aren't really going to correctly identify when player data has been corrupted or not with 100% accuracy ever @@ -67,7 +67,7 @@ public class FlatFileDataProcessor { } } - registerData(builder.appendFlag(FlatFileDataFlag.JUNK)); + registerData(builder.appendFlag(FlatFileDataFlag.CORRUPTED_OR_UNRECOGNIZABLE)); return; } @@ -123,20 +123,8 @@ public class FlatFileDataProcessor { if(!name.isEmpty()) names.add(name); - //Make sure the data is up to date schema wise - if(splitDataLine.length < DATA_ENTRY_COUNT) { - int oldLength = splitDataLine.length; - splitDataLine = Arrays.copyOf(splitDataLine, DATA_ENTRY_COUNT); - int newLength = splitDataLine.length; - - //TODO: Test this - for(int i = oldLength; i < (newLength - 1); i++){ - badDataValues[i] = true; - } - - builder.appendFlag(FlatFileDataFlag.INCOMPLETE); - builder.setSplitStringData(splitDataLine); - } + //Make sure the data is up to date schema wise, if it isn't we adjust it to the correct size and flag it for repair + splitDataLine = isDataSchemaUpToDate(splitDataLine, builder, badDataValues); /* * After establishing this data has at least an identity we check for bad data @@ -169,6 +157,26 @@ public class FlatFileDataProcessor { registerData(builder); } + public @NotNull String[] isDataSchemaUpToDate(@NotNull String[] splitDataLine, @NotNull FlatFileDataBuilder builder, boolean[] badDataValues) { + assert splitDataLine.length <= DATA_ENTRY_COUNT; //should NEVER be higher + + if(splitDataLine.length < DATA_ENTRY_COUNT) { + int oldLength = splitDataLine.length; + splitDataLine = Arrays.copyOf(splitDataLine, DATA_ENTRY_COUNT); + int newLength = splitDataLine.length; + + //TODO: Test this + for(int i = oldLength; i < (newLength - 1); i++){ + badDataValues[i] = true; + } + + builder.appendFlag(FlatFileDataFlag.INCOMPLETE); + builder.setSplitStringData(splitDataLine); + } + return splitDataLine; + } + + public boolean shouldNotBeEmpty(String data, int index) { if(getExpectedValueType(index) == ExpectedType.IGNORED) { return false; @@ -221,8 +229,9 @@ public class FlatFileDataProcessor { } private void reportBadDataLine(String warning, String context, String dataLine) { - logger.severe("FlatFileDatabaseBuilder Warning: " + warning + " - " + context); - logger.severe("FlatFileDatabaseBuilder: (Line Data) - " + dataLine); + logger.warning("FlatFileDatabaseBuilder Warning: " + warning + " - " + context); + logger.warning("FlatFileDatabaseBuilder: (Line Data) - " + dataLine); + logger.warning("mcMMO will repair this data if automatically (if it is possible)."); } private int getMinimumSplitDataLength() { @@ -237,7 +246,7 @@ public class FlatFileDataProcessor { flatFileDataFlags.addAll(flatFileDataContainer.getDataFlags()); } - public @NotNull ExpectedType getExpectedValueType(int dataIndex) throws IndexOutOfBoundsException { + public static @NotNull ExpectedType getExpectedValueType(int dataIndex) throws IndexOutOfBoundsException { switch(dataIndex) { case USERNAME_INDEX: return ExpectedType.STRING; @@ -316,6 +325,8 @@ public class FlatFileDataProcessor { if(splitData == null) continue; + //We add a trailing : as it is needed for some reason (is it?) + //TODO: Is the trailing ":" actually necessary? String fromSplit = org.apache.commons.lang.StringUtils.join(splitData, ":") + ":"; stringBuilder.append(fromSplit).append("\r\n"); } diff --git a/src/main/java/com/gmail/nossr50/database/flatfile/CategorizedFlatFileData.java b/src/main/java/com/gmail/nossr50/database/flatfile/CategorizedFlatFileData.java index 8ed0478cb..500be9c4f 100644 --- a/src/main/java/com/gmail/nossr50/database/flatfile/CategorizedFlatFileData.java +++ b/src/main/java/com/gmail/nossr50/database/flatfile/CategorizedFlatFileData.java @@ -12,7 +12,7 @@ public class CategorizedFlatFileData implements FlatFileDataContainer { private final @NotNull String[] splitData; private final int uniqueProcessingId; - protected CategorizedFlatFileData(int uniqueProcessingId, @NotNull HashSet dataFlags, @NotNull String[] splitData) { + public CategorizedFlatFileData(int uniqueProcessingId, @NotNull HashSet dataFlags, @NotNull String[] splitData) { this.uniqueProcessingId = uniqueProcessingId; this.dataFlags = dataFlags; this.splitData = splitData; diff --git a/src/main/java/com/gmail/nossr50/database/flatfile/FlatFileSaveDataProcessor.java b/src/main/java/com/gmail/nossr50/database/flatfile/FlatFileSaveDataProcessor.java index 1e109cbcf..eb06d1dab 100644 --- a/src/main/java/com/gmail/nossr50/database/flatfile/FlatFileSaveDataProcessor.java +++ b/src/main/java/com/gmail/nossr50/database/flatfile/FlatFileSaveDataProcessor.java @@ -6,7 +6,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import static com.gmail.nossr50.database.FlatFileDatabaseManager.*; -import static com.gmail.nossr50.database.FlatFileDatabaseManager.UUID_INDEX; public class FlatFileSaveDataProcessor { @@ -18,11 +17,10 @@ public class FlatFileSaveDataProcessor { //Data of this type is not salvageable //TODO: Test that we ignore the things we are supposed to ignore //TODO: Should we even keep track of the bad data or just not even build data containers for it? Making containers for it is only really useful for debugging.. well I suppose operations are typically async so it shouldn't matter - if(dataContainer.getDataFlags().contains(FlatFileDataFlag.JUNK) + if(dataContainer.getDataFlags().contains(FlatFileDataFlag.CORRUPTED_OR_UNRECOGNIZABLE) || dataContainer.getDataFlags().contains(FlatFileDataFlag.DUPLICATE_UUID) //For now we will not try to fix any issues with UUIDs || dataContainer.getDataFlags().contains(FlatFileDataFlag.BAD_UUID_DATA) //For now we will not try to fix any issues with UUIDs - || dataContainer.getDataFlags().contains(FlatFileDataFlag.TOO_INCOMPLETE) - || dataContainer.getDataFlags().contains(FlatFileDataFlag.EMPTY_LINE)) { + || dataContainer.getDataFlags().contains(FlatFileDataFlag.TOO_INCOMPLETE)) { return null; } diff --git a/src/test/java/com/gmail/nossr50/database/FlatFileDataProcessorTest.java b/src/test/java/com/gmail/nossr50/database/FlatFileDataProcessorTest.java new file mode 100644 index 000000000..2acbd41f8 --- /dev/null +++ b/src/test/java/com/gmail/nossr50/database/FlatFileDataProcessorTest.java @@ -0,0 +1,23 @@ +package com.gmail.nossr50.database; + +import org.junit.Test; + +public class FlatFileDataProcessorTest { + + @SuppressWarnings("ResultOfMethodCallIgnored") + @Test + public void testGetExpectedValueType() { + for(int i = 0; i < FlatFileDatabaseManager.DATA_ENTRY_COUNT; i++) { + FlatFileDataProcessor.getExpectedValueType(i); + } + } + + @SuppressWarnings("ResultOfMethodCallIgnored") + @Test(expected = IndexOutOfBoundsException.class) + public void testGetExpectedValueTypeException() { + for(int i = 0; i < FlatFileDatabaseManager.DATA_ENTRY_COUNT+1; i++) { + FlatFileDataProcessor.getExpectedValueType(i); + } + } + +} \ No newline at end of file diff --git a/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java b/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java index 32a424ea0..795f89e96 100644 --- a/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java +++ b/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java @@ -131,7 +131,7 @@ public class FlatFileDatabaseManagerTest { @Test public void testFindCorruptData() { - overwriteDataAndCheckForFlag(db, corruptDatabaseData, FlatFileDataFlag.JUNK); + overwriteDataAndCheckForFlag(db, corruptDatabaseData, FlatFileDataFlag.CORRUPTED_OR_UNRECOGNIZABLE); } @Test @@ -139,11 +139,6 @@ public class FlatFileDatabaseManagerTest { overwriteDataAndCheckForFlag(db, emptyNameDatabaseData, FlatFileDataFlag.MISSING_NAME); } -// @Test -// public void testFindEmptyLine() { -// overwriteDataAndCheckForFlag(db, emptyLineDatabaseData, FlatFileDataFlag.EMPTY_LINE); -// } - @Test public void testFindBadValues() { overwriteDataAndCheckForFlag(db, badDatabaseData, FlatFileDataFlag.BAD_VALUES); diff --git a/src/test/java/com/gmail/nossr50/database/flatfile/FlatFileSaveDataProcessorTest.java b/src/test/java/com/gmail/nossr50/database/flatfile/FlatFileSaveDataProcessorTest.java new file mode 100644 index 000000000..8b10772fa --- /dev/null +++ b/src/test/java/com/gmail/nossr50/database/flatfile/FlatFileSaveDataProcessorTest.java @@ -0,0 +1,27 @@ +package com.gmail.nossr50.database.flatfile; + +import com.gmail.nossr50.database.FlatFileDatabaseManager; +import org.junit.Test; + +import java.util.HashSet; + +public class FlatFileSaveDataProcessorTest { + + @Test + public void getPreparedSaveDataLine() { + } + + @Test + public void repairBadData() { + } + + @Test + public void getZeroInitialisedData() { + } + + @Test(expected = AssertionError.class) + public void testTooManyDataEntriesSplitString() { + FlatFileDataContainer dataContainer = new CategorizedFlatFileData(0, new HashSet<>(), new String[FlatFileDatabaseManager.DATA_ENTRY_COUNT + 1]); + FlatFileSaveDataProcessor.getPreparedSaveDataLine(dataContainer); + } +} \ No newline at end of file