Added defensive null checking code to DB

Relates to https://github.com/BentoBoxWorld/BentoBox/issues/447
This commit is contained in:
tastybento 2019-01-07 07:46:59 -08:00
parent 9eec14ffb3
commit acb6cd5650
5 changed files with 75 additions and 10 deletions

View File

@ -1,8 +1,5 @@
package world.bentobox.bentobox.database.json;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.database.DatabaseConnector;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.File;
@ -19,6 +16,10 @@ import java.util.List;
import java.util.Locale;
import java.util.Objects;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.database.DatabaseConnector;
import world.bentobox.bentobox.database.objects.DataObject;
public class JSONDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
private static final String JSON = ".json";
@ -84,6 +85,15 @@ public class JSONDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
@Override
public void saveObject(T instance) throws IllegalAccessException, InvocationTargetException, IntrospectionException {
// Null check
if (instance == null) {
plugin.logError("JSON database request to store a null. ");
return;
}
if (!(instance instanceof DataObject)) {
plugin.logError("This class is not a DataObject: " + instance.getClass().getName());
return;
}
String path = DATABASE_FOLDER_NAME + File.separator + dataObject.getSimpleName();
// Obtain the value of uniqueId within the instance (which must be a DataObject)
@ -114,6 +124,16 @@ public class JSONDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
@Override
public void deleteObject(T instance) throws IllegalAccessException, InvocationTargetException, IntrospectionException {
// Null check
if (instance == null) {
plugin.logError("JSON database request to delete a null. ");
return;
}
if (!(instance instanceof DataObject)) {
plugin.logError("This class is not a DataObject: " + instance.getClass().getName());
return;
}
// Obtain the value of uniqueId within the instance (which must be a DataObject)
PropertyDescriptor propertyDescriptor = new PropertyDescriptor("uniqueId", dataObject);
Method method = propertyDescriptor.getReadMethod();

View File

@ -15,8 +15,8 @@ import com.mongodb.client.model.Indexes;
import com.mongodb.util.JSON;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.database.json.AbstractJSONDatabaseHandler;
import world.bentobox.bentobox.database.DatabaseConnector;
import world.bentobox.bentobox.database.json.AbstractJSONDatabaseHandler;
import world.bentobox.bentobox.database.objects.DataObject;
/**
@ -78,6 +78,11 @@ public class MongoDBDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
@Override
public void saveObject(T instance) {
// Null check
if (instance == null) {
plugin.logError("MongoDB database request to store a null. ");
return;
}
if (!(instance instanceof DataObject)) {
plugin.logError("This class is not a DataObject: " + instance.getClass().getName());
return;
@ -103,6 +108,11 @@ public class MongoDBDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
@Override
public void deleteObject(T instance) {
// Null check
if (instance == null) {
plugin.logError("MondDB database request to delete a null. ");
return;
}
if (!(instance instanceof DataObject)) {
plugin.logError("This class is not a DataObject: " + instance.getClass().getName());
return;

View File

@ -115,6 +115,11 @@ public class MySQLDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
@Override
public void saveObject(T instance) {
// Null check
if (instance == null) {
plugin.logError("MySQL database request to store a null. ");
return;
}
if (!(instance instanceof DataObject)) {
plugin.logError("This class is not a DataObject: " + instance.getClass().getName());
return;
@ -138,6 +143,11 @@ public class MySQLDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
@Override
public void deleteObject(T instance) {
// Null check
if (instance == null) {
plugin.logError("MySQL database request to delete a null. ");
return;
}
if (!(instance instanceof DataObject)) {
plugin.logError("This class is not a DataObject: " + instance.getClass().getName());
return;

View File

@ -34,6 +34,7 @@ import world.bentobox.bentobox.api.configuration.StoreAt;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.database.AbstractDatabaseHandler;
import world.bentobox.bentobox.database.DatabaseConnector;
import world.bentobox.bentobox.database.objects.DataObject;
import world.bentobox.bentobox.database.objects.adapters.Adapter;
import world.bentobox.bentobox.database.objects.adapters.AdapterInterface;
import world.bentobox.bentobox.util.Util;
@ -293,6 +294,16 @@ public class YamlDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
@SuppressWarnings("unchecked")
@Override
public void saveObject(T instance) throws IllegalAccessException, InvocationTargetException, IntrospectionException {
// Null check
if (instance == null) {
plugin.logError("YAML database request to store a null. ");
return;
}
// DataObject check
if (!(instance instanceof DataObject)) {
plugin.logError("This class is not a DataObject: " + instance.getClass().getName());
return;
}
// This is the Yaml Configuration that will be used and saved at the end
YamlConfiguration config = new YamlConfiguration();
@ -547,6 +558,16 @@ public class YamlDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
*/
@Override
public void deleteObject(T instance) throws IllegalAccessException, InvocationTargetException, IntrospectionException {
// Null check
if (instance == null) {
plugin.logError("YAM database request to delete a null. ");
return;
}
if (!(instance instanceof DataObject)) {
plugin.logError("This class is not a DataObject: " + instance.getClass().getName());
return;
}
// Obtain the value of uniqueId within the instance (which must be a DataObject)
PropertyDescriptor propertyDescriptor = new PropertyDescriptor("uniqueId", dataObject);
Method method = propertyDescriptor.getReadMethod();

View File

@ -19,7 +19,7 @@ import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.inventory.ItemFactory;
import org.bukkit.plugin.PluginManager;
import org.junit.BeforeClass;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@ -39,7 +39,7 @@ import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.util.Util;
@RunWith(PowerMockRunner.class)
@PrepareForTest( { BentoBox.class, Util.class })
@PrepareForTest( { Bukkit.class, BentoBox.class, Util.class })
public class MySQLDatabaseHandlerTest {
private static MySQLDatabaseHandler<Island> handler;
@ -52,8 +52,8 @@ public class MySQLDatabaseHandlerTest {
private static IslandWorldManager iwm;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
@Before
public void setUp() throws Exception {
Server server = mock(Server.class);
world = mock(World.class);
when(server.getLogger()).thenReturn(Logger.getAnonymousLogger());
@ -66,8 +66,7 @@ public class MySQLDatabaseHandlerTest {
ItemFactory itemFactory = mock(ItemFactory.class);
when(server.getItemFactory()).thenReturn(itemFactory);
Bukkit.setServer(server);
PowerMockito.mockStatic(Bukkit.class);
when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger());
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
@ -100,6 +99,11 @@ public class MySQLDatabaseHandlerTest {
}
@Test
public void testSaveNullObject() {
handler.saveObject(null);
}
@Test
public void testSaveObject() {
handler.saveObject(instance);