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.ChatColor;
import java.nio.file.Path;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -58,6 +59,8 @@ public class HolographicDisplays extends BaseJavaPlugin {
// Not null if ProtocolLib is installed and successfully loaded.
private static ProtocolLibHook protocolLibHook;
private static Path dataFolderPath;
@Override
public void onCheckedEnable() throws PluginEnableException {
// Warn about plugin reloaders and the /reload command.
@ -67,6 +70,7 @@ public class HolographicDisplays extends BaseJavaPlugin {
System.setProperty("HolographicDisplaysLoaded", "true");
instance = this;
dataFolderPath = getDataFolder().toPath();
// Load placeholders.yml.
UnicodeSymbols.load(this);
@ -220,5 +224,9 @@ public class HolographicDisplays extends BaseJavaPlugin {
public static ProtocolLibHook getProtocolLibHook() {
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.entity.Player;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class CommandValidator {
@ -63,16 +64,18 @@ public class CommandValidator {
}
}
public static File getUserReadableFile(String fileName) throws CommandException, IOException {
File dataFolder = HolographicDisplays.getInstance().getDataFolder();
File targetFile = new File(dataFolder, fileName);
CommandValidator.isTrue(FileUtils.isParentFolder(dataFolder, targetFile), "The file must be inside HolographicDisplays' folder.");
CommandValidator.isTrue(!isConfigFile(targetFile), "Cannot read default configuration files.");
public static Path getUserReadableFile(String fileName) throws CommandException, IOException {
Path dataFolder = HolographicDisplays.getDataFolderPath();
Path targetFile = dataFolder.resolve(fileName);
CommandValidator.isTrue(FileUtils.isInsideDirectory(targetFile, dataFolder), "The specified file must be inside HolographicDisplays' folder.");
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;
}
private static boolean isConfigFile(File file) {
return file.getName().toLowerCase().endsWith(".yml");
private static boolean isConfigFile(Path file) {
return Files.isRegularFile(file) && file.getFileName().toString().toLowerCase().endsWith(".yml");
}
}

View File

@ -6,10 +6,10 @@
package me.filoghost.holographicdisplays.commands.main.subs;
import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.Permissions;
import me.filoghost.holographicdisplays.commands.CommandValidator;
import me.filoghost.holographicdisplays.commands.Messages;
import me.filoghost.holographicdisplays.commands.main.HologramSubCommand;
import me.filoghost.holographicdisplays.Permissions;
import me.filoghost.holographicdisplays.disk.HologramDatabase;
import me.filoghost.holographicdisplays.event.NamedHologramEditedEvent;
import me.filoghost.holographicdisplays.exception.CommandException;
@ -24,11 +24,10 @@ import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
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.");
}
File targetImage = CommandValidator.getUserReadableFile(fileName);
Path targetImage = CommandValidator.getUserReadableFile(fileName);
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.");
} catch (UnreadableImageException e) {
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) {
e.printStackTrace();
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.object.NamedHologram;
import me.filoghost.holographicdisplays.object.line.CraftHologramLine;
import me.filoghost.holographicdisplays.util.FileUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -53,8 +52,8 @@ public class ReadtextCommand extends HologramSubCommand {
String fileName = args[1];
try {
File targetFile = CommandValidator.getUserReadableFile(fileName);
List<String> serializedLines = FileUtils.readLines(targetFile);
Path targetFile = CommandValidator.getUserReadableFile(fileName);
List<String> serializedLines = Files.readAllLines(targetFile);
int linesAmount = serializedLines.size();
if (linesAmount > 40) {
@ -88,8 +87,6 @@ public class ReadtextCommand extends HologramSubCommand {
sender.sendMessage(Colors.PRIMARY + "The lines were pasted into the 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) {
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;
import me.filoghost.fcommons.logging.Log;
import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.HolographicDisplays;
import me.filoghost.holographicdisplays.Permissions;
@ -60,7 +61,11 @@ public class ReloadCommand extends HologramSubCommand {
BungeeServerTracker.restartTask(Configuration.bungeeRefreshSeconds);
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();
NamedHologramManager.clearAll();

View File

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

View File

@ -9,78 +9,83 @@ import me.filoghost.fcommons.logging.Log;
import me.filoghost.holographicdisplays.HolographicDisplays;
import me.filoghost.holographicdisplays.common.DebugLogger;
import me.filoghost.holographicdisplays.disk.StringConverter;
import me.filoghost.holographicdisplays.util.FileUtils;
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.List;
import java.util.Map;
import java.util.stream.Stream;
public class AnimationsRegister {
// <fileName, lines>
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();
File animationFolder = new File(plugin.getDataFolder(), "animations");
if (!animationFolder.isDirectory()) {
animationFolder.mkdirs();
Path animationFolder = HolographicDisplays.getDataFolderPath().resolve("animations");
if (!Files.isDirectory(animationFolder)) {
Files.createDirectories(animationFolder);
plugin.saveResource("animations/example.txt", false);
return;
}
for (File file : animationFolder.listFiles()) {
try {
List<String> lines = FileUtils.readLines(file);
if (lines.size() == 0) {
continue;
}
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);
}
try (Stream<Path> animationFiles = Files.list(animationFolder)) {
animationFiles.forEach(AnimationsRegister::readAnimationFile);
}
}
private static void readAnimationFile(Path file) {
try {
List<String> lines = Files.readAllLines(file);
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.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);
}
}
public static Map<String, Placeholder> getAnimations() {
return animations;
}

View File

@ -9,58 +9,16 @@ import me.filoghost.holographicdisplays.exception.UnreadableImageException;
import javax.imageio.ImageIO;
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.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.nio.file.Files;
import java.nio.file.Path;
public class FileUtils {
public static List<String> readLines(File file) throws IOException {
if (!file.isFile()) {
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);
public static BufferedImage readImage(Path file) throws UnreadableImageException, IOException {
BufferedImage image = ImageIO.read(Files.newInputStream(file));
if (image == null) {
throw new UnreadableImageException();
@ -78,17 +36,12 @@ public class FileUtils {
return image;
}
public static boolean isParentFolder(File folder, File file) throws IOException {
File iteratorFile = file.getCanonicalFile();
folder = folder.getCanonicalFile();
while ((iteratorFile = iteratorFile.getParentFile()) != null) {
if (iteratorFile.equals(folder)) {
return true;
}
}
return false;
public static boolean isInsideDirectory(Path file, Path directory) {
Path canonicalFile = file.toAbsolutePath().normalize();
Path canonicalDirectory = directory.toAbsolutePath().normalize();
return canonicalFile.getNameCount() > canonicalDirectory.getNameCount() && canonicalFile.startsWith(canonicalDirectory);
}
}