Improve and simplify default challenge data storing.

This commit is contained in:
BONNe1704 2019-04-25 18:21:10 +03:00
parent 188e86d546
commit 017147ff3f

View File

@ -1,12 +1,14 @@
package world.bentobox.challenges; package world.bentobox.challenges;
import java.beans.IntrospectionException; import com.google.gson.Gson;
import java.io.File; import com.google.gson.GsonBuilder;
import java.io.FileWriter; import com.google.gson.annotations.Expose;
import java.io.IOException; import java.io.*;
import java.lang.reflect.InvocationTargetException; import java.nio.file.Files;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
@ -14,11 +16,10 @@ import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.eclipse.jdt.annotation.NonNull; import org.bukkit.potion.PotionEffectType;
import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.database.DatabaseConnector; import world.bentobox.bentobox.database.json.adapters.*;
import world.bentobox.bentobox.database.json.AbstractJSONDatabaseHandler;
import world.bentobox.bentobox.database.objects.DataObject; import world.bentobox.bentobox.database.objects.DataObject;
import world.bentobox.bentobox.util.ItemParser; import world.bentobox.bentobox.util.ItemParser;
import world.bentobox.challenges.database.object.ChallengeLevel; import world.bentobox.challenges.database.object.ChallengeLevel;
@ -219,6 +220,7 @@ public class ChallengesImportManager
* @param world Target world. * @param world Target world.
* @return <code>true</code> if everything was successful, otherwise <code>false</code>. * @return <code>true</code> if everything was successful, otherwise <code>false</code>.
*/ */
@SuppressWarnings("unused")
private boolean loadDefaultChallenges(User user, World world) private boolean loadDefaultChallenges(User user, World world)
{ {
ChallengesManager manager = this.addon.getChallengesManager(); ChallengesManager manager = this.addon.getChallengesManager();
@ -241,21 +243,11 @@ public class ChallengesImportManager
// Safe json configuration to Challenges folder. // Safe json configuration to Challenges folder.
this.addon.saveResource("default.json", true); this.addon.saveResource("default.json", true);
// Init Connector
CustomJSONConnector connector = new CustomJSONConnector();
// Load challenges
CustomJSONHandler<Challenge> challengeHandler =
new CustomJSONHandler<>(BentoBox.getInstance(), Challenge.class, connector);
// Load levels
CustomJSONHandler<ChallengeLevel> levelHandler =
new CustomJSONHandler<>(BentoBox.getInstance(), ChallengeLevel.class, connector);
try try
{ {
challengeHandler.loadObjects().forEach(challenge -> manager.loadChallenge(challenge, false, user, false)); DefaultDataHolder defaultChallenges = new DefaultJSONHandler(this.addon).loadObject();
levelHandler.loadObjects().forEach(level -> manager.loadLevel(level, false, user, false)); defaultChallenges.getChallengeList().forEach(challenge -> manager.loadChallenge(challenge, false, user, true));
defaultChallenges.getLevelList().forEach(level -> manager.loadLevel(level, false, user, true));
} }
catch (Exception e) catch (Exception e)
{ {
@ -285,7 +277,7 @@ public class ChallengesImportManager
@SuppressWarnings("unused") @SuppressWarnings("unused")
private void generateDefaultChallengeFile(World world) private void generateDefaultChallengeFile(World world)
{ {
File defaultFile = new File(BentoBox.getInstance().getDataFolder() + "/addons/Challenges", "default.json"); File defaultFile = new File(this.addon.getDataFolder(), "default.json");
try try
{ {
@ -294,58 +286,25 @@ public class ChallengesImportManager
String replacementString = Util.getWorld(world).getName() + "_"; String replacementString = Util.getWorld(world).getName() + "_";
ChallengesManager manager = this.addon.getChallengesManager(); ChallengesManager manager = this.addon.getChallengesManager();
// Store all challenges to single file List<Challenge> challengeList = manager.getAllChallenges(world).
List<Challenge> challengeList = manager.getAllChallenges(world); stream().
map(Challenge::clone).
collect(Collectors.toList());
CustomJSONHandler<Challenge> generateChallengeJSON = List<ChallengeLevel> levelList = manager.getLevels(world).
new CustomJSONHandler<>(BentoBox.getInstance(), Challenge.class, new CustomJSONConnector()); stream().
map(ChallengeLevel::clone).
collect(Collectors.toList());
StringBuilder outputString = new StringBuilder(); DefaultDataHolder defaultChallenges = new DefaultDataHolder();
outputString.append("{\"challenges\": ["); defaultChallenges.setChallengeList(challengeList);
defaultChallenges.setLevelList(levelList);
defaultChallenges.setVersion(this.addon.getDescription().getVersion());
// Populate all challenges BufferedWriter writer = new BufferedWriter(new FileWriter(defaultFile, false));
for (int i = 0, size = challengeList.size(); i < size; i++) writer.write(Objects.requireNonNull(
{ new DefaultJSONHandler(this.addon).toJsonString(defaultChallenges)));
Challenge clone = challengeList.get(i).clone(); writer.close();
clone.setUniqueId(clone.getUniqueId().replaceFirst(replacementString, ""));
clone.setLevel(clone.getLevel().replaceFirst(replacementString, ""));
if (i != 0)
{
outputString.append(",");
}
outputString.append(generateChallengeJSON.toJsonString(clone));
}
outputString.append("],\"levels\": [");
// Populate all levels
List<ChallengeLevel> levelList = manager.getLevels(world);
CustomJSONHandler<ChallengeLevel> generateLevelJSON =
new CustomJSONHandler<>(BentoBox.getInstance(), ChallengeLevel.class, new CustomJSONConnector());
for (int i = 0, size = levelList.size(); i < size; i++)
{
ChallengeLevel clone = levelList.get(i).clone();
clone.setUniqueId(clone.getUniqueId().replaceFirst(replacementString, ""));
clone.getChallenges().forEach(challenge -> challenge = challenge.replaceFirst(replacementString, ""));
clone.setWorld("");
if (i != 0)
{
outputString.append(",");
}
outputString.append(generateLevelJSON.toJsonString(clone));
}
// Add version string
outputString.append("],\"version\": \"").append(this.addon.getDescription().getVersion()).append("\"}");
// Store to file.
new FileWriter(defaultFile).write(outputString.toString());
} }
} }
catch (IOException e) catch (IOException e)
@ -363,85 +322,28 @@ public class ChallengesImportManager
/** /**
* This Class allows to load default challenges and their levels as objects much easier. * This Class allows to load default challenges and their levels as objects much easier.
*/ */
private final class CustomJSONHandler<T> extends AbstractJSONDatabaseHandler<T> private final class DefaultJSONHandler
{ {
/** /**
* {@inheritDoc} * This constructor inits JSON builder that will be used to parese challenges.
*/ * @param addon Challenges Adddon
CustomJSONHandler(BentoBox plugin, Class<T> type, DatabaseConnector databaseConnector) */
DefaultJSONHandler(ChallengesAddon addon)
{ {
super(plugin, type, databaseConnector); GsonBuilder builder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().enableComplexMapKeySerialization();
} // Register adapters
builder.registerTypeAdapter(Location.class, new LocationAdapter()) ;
builder.registerTypeAdapter(World.class, new WorldAdapter());
builder.registerTypeAdapter(Flag.class, new FlagAdapter(addon.getPlugin()));
builder.registerTypeAdapter(PotionEffectType.class, new PotionEffectTypeAdapter());
builder.registerTypeAdapter(ItemStack.class, new ItemStackTypeAdapter());
// Keep null in the database
builder.serializeNulls();
// Allow characters like < or > without escaping them
builder.disableHtmlEscaping();
this.addon = addon;
/** this.gson = builder.create();
* {@inheritDoc}
*/
@Override
public List<T> loadObjects()
{
return Collections.emptyList();
}
/**
* {@inheritDoc}
*/
@Override
public T loadObject(@NonNull String s)
{
return null;
}
/**
* {@inheritDoc}
*/
@Override
public void saveObject(T t)
{
// Will not be used in default challenge loading process.
}
/**
* {@inheritDoc}
*/
@Override
public void deleteObject(T t)
{
// Will not be used in default challenge loading process.
}
/**
* {@inheritDoc}
*/
@Override
public boolean objectExists(String s)
{
// Will not be used in default challenge loading process.
return false;
}
/**
* {@inheritDoc}
*/
@Override
public void close()
{
// Will not be used in default challenge loading process.
}
/**
* {@inheritDoc}
*/
@Override
public void deleteID(String s)
{
// Will not be used in default challenge loading process.
} }
@ -450,79 +352,179 @@ public class ChallengesImportManager
* @param instance Instance that must be parsed to json string. * @param instance Instance that must be parsed to json string.
* @return String that contains JSON information from instance object. * @return String that contains JSON information from instance object.
*/ */
public String toJsonString(T instance) String toJsonString(DefaultDataHolder instance)
{ {
// Null check // Null check
if (instance == null) if (instance == null)
{ {
plugin.logError("JSON database request to store a null. "); this.addon.logError("JSON database request to store a null. ");
return null; return null;
} }
if (!(instance instanceof DataObject)) return this.gson.toJson(instance);
{
plugin.logError("This class is not a DataObject: " + instance.getClass().getName());
return null;
}
return this.getGson().toJson(instance);
} }
/**
* This method creates and adds to list all objects from default.json file.
* @return List of all objects from default.json that is with T instance.
*/
DefaultDataHolder loadObject()
{
File defaultFile = new File(this.addon.getDataFolder(), "default.json");
StringBuilder builder = new StringBuilder();
try
{
Files.readAllLines(defaultFile.toPath()).forEach(builder::append);
}
catch (IOException e)
{
e.printStackTrace();
}
return this.gson.fromJson(builder.toString(), DefaultDataHolder.class);
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* Holds JSON builder object.
*/
private Gson gson;
/**
* Holds ChallengesAddon object.
*/
private ChallengesAddon addon;
} }
/** /**
* Empty JSON connector. It is used just because it is necessary for AbstractJSONDatabaseHandler. * This is simple object that will allow to store all current challenges and levels
* UniqueIDs will always be unique, as default challenges will be implemented only if there * in single file.
* does not exist any challenge in targeted world. */
*/ private final class DefaultDataHolder implements DataObject
private final static class CustomJSONConnector implements DatabaseConnector {
{ /**
/** * Default constructor. Creates object with empty lists.
* {@inheritDoc} */
*/ DefaultDataHolder()
@Override {
public Object createConnection() this.challengeList = Collections.emptyList();
{ this.challengeLevelList = Collections.emptyList();
return null; this.version = "";
} }
/** /**
* {@inheritDoc} * This method returns stored challenge list.
*/ * @return list that contains default challenges.
@Override */
public void closeConnection() public List<Challenge> getChallengeList()
{ {
} return challengeList;
}
/** /**
* {@inheritDoc} * This method sets given list as default challenge list.
*/ * @param challengeList new default challenge list.
@Override */
public String getConnectionUrl() public void setChallengeList(List<Challenge> challengeList)
{ {
return null; this.challengeList = challengeList;
} }
/** /**
* {@inheritDoc} * This method returns list of default challenge levels.
*/ * @return List that contains default challenge levels.
@Override */
public String getUniqueId(String s) public List<ChallengeLevel> getLevelList()
{ {
return null; return challengeLevelList;
} }
/** /**
* {@inheritDoc} * This method sets given list as default challenge level list.
*/ * @param levelList new default challenge level list.
@Override */
public boolean uniqueIdExists(String s, String s1) public void setLevelList(List<ChallengeLevel> levelList)
{ {
return false; this.challengeLevelList = levelList;
} }
}
/**
* This method returns the version value.
* @return the value of version.
*/
public String getVersion()
{
return version;
}
/**
* This method sets the version value.
* @param version the version new value.
*
*/
public void setVersion(String version)
{
this.version = version;
}
/**
* @return default.json
*/
@Override
public String getUniqueId()
{
return "default.json";
}
/**
* @param uniqueId - unique ID the uniqueId to set
*/
@Override
public void setUniqueId(String uniqueId)
{
// method not used.
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* Holds a list with default challenges.
*/
@Expose
private List<Challenge> challengeList;
/**
* Holds a list with default levels.
*/
@Expose
private List<ChallengeLevel> challengeLevelList;
/**
* Holds a variable that stores in which addon version file was made.
*/
@Expose
private String version;
}
} }