Use NIO java file API

This commit is contained in:
filoghost 2021-01-07 21:05:38 +01:00
parent 1f32c7127c
commit aa8aad2b83
8 changed files with 105 additions and 137 deletions

View File

@ -35,6 +35,7 @@ import org.bstats.bukkit.MetricsLite;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import java.nio.file.Path;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -58,6 +59,8 @@ public class HolographicDisplays extends BaseJavaPlugin {
// Not null if ProtocolLib is installed and successfully loaded. // Not null if ProtocolLib is installed and successfully loaded.
private static ProtocolLibHook protocolLibHook; private static ProtocolLibHook protocolLibHook;
private static Path dataFolderPath;
@Override @Override
public void onCheckedEnable() throws PluginEnableException { public void onCheckedEnable() throws PluginEnableException {
// Warn about plugin reloaders and the /reload command. // Warn about plugin reloaders and the /reload command.
@ -67,6 +70,7 @@ public class HolographicDisplays extends BaseJavaPlugin {
System.setProperty("HolographicDisplaysLoaded", "true"); System.setProperty("HolographicDisplaysLoaded", "true");
instance = this; instance = this;
dataFolderPath = getDataFolder().toPath();
// Load placeholders.yml. // Load placeholders.yml.
UnicodeSymbols.load(this); UnicodeSymbols.load(this);
@ -221,4 +225,8 @@ public class HolographicDisplays extends BaseJavaPlugin {
return protocolLibHook; return protocolLibHook;
} }
public static Path getDataFolderPath() {
return dataFolderPath;
}
} }

View File

@ -16,8 +16,9 @@ import me.filoghost.holographicdisplays.util.FileUtils;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class CommandValidator { public class CommandValidator {
@ -63,16 +64,18 @@ public class CommandValidator {
} }
} }
public static File getUserReadableFile(String fileName) throws CommandException, IOException { public static Path getUserReadableFile(String fileName) throws CommandException, IOException {
File dataFolder = HolographicDisplays.getInstance().getDataFolder(); Path dataFolder = HolographicDisplays.getDataFolderPath();
File targetFile = new File(dataFolder, fileName); Path targetFile = dataFolder.resolve(fileName);
CommandValidator.isTrue(FileUtils.isParentFolder(dataFolder, targetFile), "The file must be inside HolographicDisplays' folder."); CommandValidator.isTrue(FileUtils.isInsideDirectory(targetFile, dataFolder), "The specified file must be inside HolographicDisplays' folder.");
CommandValidator.isTrue(!isConfigFile(targetFile), "Cannot read default configuration files."); CommandValidator.isTrue(Files.exists(targetFile), "The specified file \"" + fileName + "\" does not exist inside HolographicDisplays' folder.");
CommandValidator.isTrue(!Files.isDirectory(targetFile), "The file cannot be a folder.");
CommandValidator.isTrue(!isConfigFile(targetFile), "Cannot read YML configuration files.");
return targetFile; return targetFile;
} }
private static boolean isConfigFile(File file) { private static boolean isConfigFile(Path file) {
return file.getName().toLowerCase().endsWith(".yml"); return Files.isRegularFile(file) && file.getFileName().toString().toLowerCase().endsWith(".yml");
} }
} }

View File

@ -6,10 +6,10 @@
package me.filoghost.holographicdisplays.commands.main.subs; package me.filoghost.holographicdisplays.commands.main.subs;
import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.Permissions;
import me.filoghost.holographicdisplays.commands.CommandValidator; import me.filoghost.holographicdisplays.commands.CommandValidator;
import me.filoghost.holographicdisplays.commands.Messages; import me.filoghost.holographicdisplays.commands.Messages;
import me.filoghost.holographicdisplays.commands.main.HologramSubCommand; import me.filoghost.holographicdisplays.commands.main.HologramSubCommand;
import me.filoghost.holographicdisplays.Permissions;
import me.filoghost.holographicdisplays.disk.HologramDatabase; import me.filoghost.holographicdisplays.disk.HologramDatabase;
import me.filoghost.holographicdisplays.event.NamedHologramEditedEvent; import me.filoghost.holographicdisplays.event.NamedHologramEditedEvent;
import me.filoghost.holographicdisplays.exception.CommandException; import me.filoghost.holographicdisplays.exception.CommandException;
@ -24,11 +24,10 @@ import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -90,7 +89,7 @@ public class ReadimageCommand extends HologramSubCommand {
Messages.sendWarning(sender, "The image path seems to be an URL. If so, please use http:// or https:// in the path."); Messages.sendWarning(sender, "The image path seems to be an URL. If so, please use http:// or https:// in the path.");
} }
File targetImage = CommandValidator.getUserReadableFile(fileName); Path targetImage = CommandValidator.getUserReadableFile(fileName);
image = FileUtils.readImage(targetImage); image = FileUtils.readImage(targetImage);
} }
@ -128,8 +127,6 @@ public class ReadimageCommand extends HologramSubCommand {
throw new CommandException("The image is too large. Max width allowed is " + ImageMessage.MAX_WIDTH + " pixels."); throw new CommandException("The image is too large. Max width allowed is " + ImageMessage.MAX_WIDTH + " pixels.");
} catch (UnreadableImageException e) { } catch (UnreadableImageException e) {
throw new CommandException("The plugin was unable to read the image. Be sure that the format is supported."); throw new CommandException("The plugin was unable to read the image. Be sure that the format is supported.");
} catch (FileNotFoundException e) {
throw new CommandException("The image \"" + args[1] + "\" doesn't exist in the plugin's folder.");
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
throw new CommandException("I/O exception while reading the image. " + (isUrl ? "Is the URL valid?" : "Is it in use?")); throw new CommandException("I/O exception while reading the image. " + (isUrl ? "Is the URL valid?" : "Is it in use?"));

View File

@ -18,14 +18,13 @@ import me.filoghost.holographicdisplays.exception.CommandException;
import me.filoghost.holographicdisplays.exception.HologramLineParseException; import me.filoghost.holographicdisplays.exception.HologramLineParseException;
import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.NamedHologram;
import me.filoghost.holographicdisplays.object.line.CraftHologramLine; import me.filoghost.holographicdisplays.object.line.CraftHologramLine;
import me.filoghost.holographicdisplays.util.FileUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -53,8 +52,8 @@ public class ReadtextCommand extends HologramSubCommand {
String fileName = args[1]; String fileName = args[1];
try { try {
File targetFile = CommandValidator.getUserReadableFile(fileName); Path targetFile = CommandValidator.getUserReadableFile(fileName);
List<String> serializedLines = FileUtils.readLines(targetFile); List<String> serializedLines = Files.readAllLines(targetFile);
int linesAmount = serializedLines.size(); int linesAmount = serializedLines.size();
if (linesAmount > 40) { if (linesAmount > 40) {
@ -88,8 +87,6 @@ public class ReadtextCommand extends HologramSubCommand {
sender.sendMessage(Colors.PRIMARY + "The lines were pasted into the hologram!"); sender.sendMessage(Colors.PRIMARY + "The lines were pasted into the hologram!");
Bukkit.getPluginManager().callEvent(new NamedHologramEditedEvent(hologram)); Bukkit.getPluginManager().callEvent(new NamedHologramEditedEvent(hologram));
} catch (FileNotFoundException e) {
throw new CommandException("A file named '" + args[1] + "' doesn't exist in the plugin's folder.");
} catch (IOException e) { } catch (IOException e) {
throw new CommandException("I/O exception while reading the file. Is it in use?"); throw new CommandException("I/O exception while reading the file. Is it in use?");
} }

View File

@ -5,6 +5,7 @@
*/ */
package me.filoghost.holographicdisplays.commands.main.subs; package me.filoghost.holographicdisplays.commands.main.subs;
import me.filoghost.fcommons.logging.Log;
import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.HolographicDisplays; import me.filoghost.holographicdisplays.HolographicDisplays;
import me.filoghost.holographicdisplays.Permissions; import me.filoghost.holographicdisplays.Permissions;
@ -60,7 +61,11 @@ public class ReloadCommand extends HologramSubCommand {
BungeeServerTracker.restartTask(Configuration.bungeeRefreshSeconds); BungeeServerTracker.restartTask(Configuration.bungeeRefreshSeconds);
HologramDatabase.loadYamlFile(HolographicDisplays.getInstance()); HologramDatabase.loadYamlFile(HolographicDisplays.getInstance());
AnimationsRegister.loadAnimations(HolographicDisplays.getInstance()); try {
AnimationsRegister.loadAnimations(HolographicDisplays.getInstance());
} catch (Exception e) {
Log.warning("Failed to load animation files!", e);
}
PlaceholdersManager.untrackAll(); PlaceholdersManager.untrackAll();
NamedHologramManager.clearAll(); NamedHologramManager.clearAll();

View File

@ -12,12 +12,13 @@
package me.filoghost.holographicdisplays.disk; package me.filoghost.holographicdisplays.disk;
import me.filoghost.fcommons.logging.Log; import me.filoghost.fcommons.logging.Log;
import me.filoghost.holographicdisplays.util.FileUtils; import me.filoghost.holographicdisplays.HolographicDisplays;
import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringEscapeUtils;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -30,16 +31,15 @@ public class UnicodeSymbols {
public static void load(Plugin plugin) { public static void load(Plugin plugin) {
placeholders.clear(); placeholders.clear();
File file = new File(plugin.getDataFolder(), "symbols.yml"); Path file = HolographicDisplays.getDataFolderPath().resolve("symbols.yml");
if (!file.exists()) { if (!Files.isRegularFile(file)) {
plugin.getDataFolder().mkdirs();
plugin.saveResource("symbols.yml", true); plugin.saveResource("symbols.yml", true);
} }
List<String> lines; List<String> lines;
try { try {
lines = FileUtils.readLines(file); lines = Files.readAllLines(file);
} catch (IOException e) { } catch (IOException e) {
Log.warning("I/O error while reading symbols.yml. Was the file in use?", e); Log.warning("I/O error while reading symbols.yml. Was the file in use?", e);
return; return;

View File

@ -9,74 +9,79 @@ import me.filoghost.fcommons.logging.Log;
import me.filoghost.holographicdisplays.HolographicDisplays; import me.filoghost.holographicdisplays.HolographicDisplays;
import me.filoghost.holographicdisplays.common.DebugLogger; import me.filoghost.holographicdisplays.common.DebugLogger;
import me.filoghost.holographicdisplays.disk.StringConverter; import me.filoghost.holographicdisplays.disk.StringConverter;
import me.filoghost.holographicdisplays.util.FileUtils;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import java.io.File; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Stream;
public class AnimationsRegister { public class AnimationsRegister {
// <fileName, lines> // <fileName, lines>
private final static Map<String, Placeholder> animations = new HashMap<>(); private final static Map<String, Placeholder> animations = new HashMap<>();
public static void loadAnimations(Plugin plugin) { public static void loadAnimations(Plugin plugin) throws IOException {
animations.clear(); animations.clear();
File animationFolder = new File(plugin.getDataFolder(), "animations"); Path animationFolder = HolographicDisplays.getDataFolderPath().resolve("animations");
if (!animationFolder.isDirectory()) { if (!Files.isDirectory(animationFolder)) {
animationFolder.mkdirs(); Files.createDirectories(animationFolder);
plugin.saveResource("animations/example.txt", false); plugin.saveResource("animations/example.txt", false);
return; return;
} }
for (File file : animationFolder.listFiles()) { try (Stream<Path> animationFiles = Files.list(animationFolder)) {
animationFiles.forEach(AnimationsRegister::readAnimationFile);
}
}
try { private static void readAnimationFile(Path file) {
List<String> lines = FileUtils.readLines(file); try {
if (lines.size() == 0) { List<String> lines = Files.readAllLines(file);
continue; if (lines.size() == 0) {
} return;
double speed = 0.5;
boolean validSpeedFound = false;
String firstLine = lines.get(0).trim();
if (firstLine.toLowerCase().startsWith("speed:")) {
// Do not consider it.
lines.remove(0);
firstLine = firstLine.substring("speed:".length()).trim();
try {
speed = Double.parseDouble(firstLine);
validSpeedFound = true;
} catch (NumberFormatException ignored) {}
}
if (!validSpeedFound) {
Log.warning("Could not find a valid 'speed: <number>' in the first line of the file '" + file.getName() + "'. Default speed of 0.5 seconds will be used.");
}
if (lines.isEmpty()) {
lines.add("[No lines: " + file.getName() + "]");
Log.warning("Could not find any line in '" + file.getName() + "' (excluding the speed). You should add at least one more line.");
}
// Replace placeholders.
for (int i = 0; i < lines.size(); i++) {
lines.set(i, StringConverter.toReadableFormat(lines.get(i)));
}
animations.put(file.getName(), new Placeholder(HolographicDisplays.getInstance(), file.getName(), speed, new CyclicPlaceholderReplacer(lines.toArray(new String[0]))));
DebugLogger.info("Successfully loaded animation '" + file.getName() + "', speed = " + speed + ".");
} catch (Exception e) {
Log.severe("Couldn't load the file '" + file.getName() + "'!", e);
} }
double speed = 0.5;
boolean validSpeedFound = false;
String firstLine = lines.get(0).trim();
if (firstLine.toLowerCase().startsWith("speed:")) {
// Do not consider it.
lines.remove(0);
firstLine = firstLine.substring("speed:".length()).trim();
try {
speed = Double.parseDouble(firstLine);
validSpeedFound = true;
} catch (NumberFormatException ignored) {}
}
if (!validSpeedFound) {
Log.warning("Could not find a valid 'speed: <number>' in the first line of the file '" + file.getFileName() + "'. Default speed of 0.5 seconds will be used.");
}
if (lines.isEmpty()) {
lines.add("[No lines: " + file.getFileName() + "]");
Log.warning("Could not find any line in '" + file.getFileName() + "' (excluding the speed). You should add at least one more line.");
}
// Replace placeholders.
for (int i = 0; i < lines.size(); i++) {
lines.set(i, StringConverter.toReadableFormat(lines.get(i)));
}
animations.put(file.getFileName().toString(), new Placeholder(HolographicDisplays.getInstance(), file.getFileName().toString(), speed, new CyclicPlaceholderReplacer(lines.toArray(new String[0]))));
DebugLogger.info("Successfully loaded animation '" + file.getFileName() + "', speed = " + speed + ".");
} catch (Exception e) {
Log.severe("Couldn't load the file '" + file.getFileName() + "'!", e);
} }
} }

View File

@ -9,58 +9,16 @@ import me.filoghost.holographicdisplays.exception.UnreadableImageException;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.nio.file.Files;
import java.util.List; import java.nio.file.Path;
public class FileUtils { public class FileUtils {
public static List<String> readLines(File file) throws IOException { public static BufferedImage readImage(Path file) throws UnreadableImageException, IOException {
if (!file.isFile()) { BufferedImage image = ImageIO.read(Files.newInputStream(file));
throw new FileNotFoundException(file.getName());
}
BufferedReader br = null;
try {
List<String> lines = new ArrayList<>();
if (!file.exists()) {
throw new FileNotFoundException();
}
br = new BufferedReader(new FileReader(file));
String line = br.readLine();
while (line != null) {
lines.add(line);
line = br.readLine();
}
return lines;
} finally {
if (br != null) {
try {
br.close();
} catch (IOException ignored) {}
}
}
}
public static BufferedImage readImage(File file) throws UnreadableImageException, IOException {
if (!file.isFile()) {
throw new FileNotFoundException(file.getName());
}
BufferedImage image = ImageIO.read(file);
if (image == null) { if (image == null) {
throw new UnreadableImageException(); throw new UnreadableImageException();
@ -79,16 +37,11 @@ public class FileUtils {
return image; return image;
} }
public static boolean isParentFolder(File folder, File file) throws IOException { public static boolean isInsideDirectory(Path file, Path directory) {
File iteratorFile = file.getCanonicalFile(); Path canonicalFile = file.toAbsolutePath().normalize();
folder = folder.getCanonicalFile(); Path canonicalDirectory = directory.toAbsolutePath().normalize();
while ((iteratorFile = iteratorFile.getParentFile()) != null) {
if (iteratorFile.equals(folder)) {
return true;
}
}
return false; return canonicalFile.getNameCount() > canonicalDirectory.getNameCount() && canonicalFile.startsWith(canonicalDirectory);
} }
} }