Update
This commit is contained in:
		@@ -6,7 +6,7 @@ plugins {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
group = 'me.skymc'
 | 
			
		||||
version = '5.26'
 | 
			
		||||
version = '5.27'
 | 
			
		||||
 | 
			
		||||
sourceCompatibility = 1.8
 | 
			
		||||
targetCompatibility = 1.8
 | 
			
		||||
 
 | 
			
		||||
@@ -52,6 +52,12 @@ public class TabooLib {
 | 
			
		||||
        logger = TLogger.getUnformatted("TabooLib");
 | 
			
		||||
        // 配置文件从 config.yml 修改为 settings.yml 防止与老版本插件冲突
 | 
			
		||||
        config = TConfig.create(getPlugin(), "settings.yml");
 | 
			
		||||
        // 配置更新
 | 
			
		||||
        try {
 | 
			
		||||
            config.migrate();
 | 
			
		||||
        } catch (Throwable t) {
 | 
			
		||||
            t.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        // 加载版本号
 | 
			
		||||
        try {
 | 
			
		||||
            version = NumberConversions.toDouble(IO.readFully(Files.getResource("__resources__/version"), StandardCharsets.UTF_8));
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
package io.izzel.taboolib.module.config;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.Preconditions;
 | 
			
		||||
import com.google.common.collect.Lists;
 | 
			
		||||
import com.google.common.collect.Maps;
 | 
			
		||||
import io.izzel.taboolib.TabooLib;
 | 
			
		||||
@@ -7,12 +8,14 @@ import io.izzel.taboolib.TabooLibAPI;
 | 
			
		||||
import io.izzel.taboolib.module.locale.TLocale;
 | 
			
		||||
import io.izzel.taboolib.module.locale.logger.TLogger;
 | 
			
		||||
import io.izzel.taboolib.util.Files;
 | 
			
		||||
import io.izzel.taboolib.util.KV;
 | 
			
		||||
import io.izzel.taboolib.util.Ref;
 | 
			
		||||
import org.bukkit.configuration.InvalidConfigurationException;
 | 
			
		||||
import org.bukkit.configuration.file.YamlConfiguration;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@@ -24,12 +27,16 @@ import java.util.Map;
 | 
			
		||||
 */
 | 
			
		||||
public class TConfig extends YamlConfiguration {
 | 
			
		||||
 | 
			
		||||
    private static Map<String, List<File>> files = Maps.newHashMap();
 | 
			
		||||
    private File file;
 | 
			
		||||
    private List<Runnable> runnable = Lists.newArrayList();
 | 
			
		||||
    private static final Map<String, List<File>> files = Maps.newHashMap();
 | 
			
		||||
    private final Plugin plugin;
 | 
			
		||||
    private final File file;
 | 
			
		||||
    private final List<Runnable> runnable = Lists.newArrayList();
 | 
			
		||||
    private final List<KV<String, String[]>> migrate = Lists.newArrayList();
 | 
			
		||||
    private String path;
 | 
			
		||||
 | 
			
		||||
    private TConfig(File file, Plugin plugin) {
 | 
			
		||||
        files.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(file);
 | 
			
		||||
        this.plugin = plugin;
 | 
			
		||||
        this.file = file;
 | 
			
		||||
        reload();
 | 
			
		||||
        TConfigWatcher.getInst().addSimpleListener(this.file, this::reload);
 | 
			
		||||
@@ -53,7 +60,9 @@ public class TConfig extends YamlConfiguration {
 | 
			
		||||
        if (!file.exists()) {
 | 
			
		||||
            Files.releaseResource(plugin, path, false);
 | 
			
		||||
        }
 | 
			
		||||
        return create(file, plugin);
 | 
			
		||||
        TConfig conf = create(file, plugin);
 | 
			
		||||
        conf.path = path;
 | 
			
		||||
        return conf;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getStringColored(String path) {
 | 
			
		||||
@@ -89,6 +98,25 @@ public class TConfig extends YamlConfiguration {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public TConfig migrate() {
 | 
			
		||||
        Preconditions.checkNotNull(path, "path not exists");
 | 
			
		||||
        try (FileInputStream fileInputStream = new FileInputStream(file)) {
 | 
			
		||||
            List<String> migrate = TConfigMigrate.migrate(fileInputStream, Files.getResourceChecked(plugin, path));
 | 
			
		||||
            if (migrate != null) {
 | 
			
		||||
                Files.write(file, w -> {
 | 
			
		||||
                    for (String line : migrate) {
 | 
			
		||||
                        w.write(line);
 | 
			
		||||
                        w.newLine();
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
                load(file);
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Throwable t) {
 | 
			
		||||
            t.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // *********************************
 | 
			
		||||
    //
 | 
			
		||||
    //        Getter and Setter
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,152 @@
 | 
			
		||||
package io.izzel.taboolib.module.config;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.Lists;
 | 
			
		||||
import io.izzel.taboolib.module.db.local.SecuredFile;
 | 
			
		||||
import io.izzel.taboolib.util.ArrayUtil;
 | 
			
		||||
import io.izzel.taboolib.util.Files;
 | 
			
		||||
import io.izzel.taboolib.util.KV;
 | 
			
		||||
import io.izzel.taboolib.util.Strings;
 | 
			
		||||
import org.bukkit.configuration.ConfigurationSection;
 | 
			
		||||
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.stream.IntStream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2020-04-27 21:02
 | 
			
		||||
 */
 | 
			
		||||
public class TConfigMigrate {
 | 
			
		||||
 | 
			
		||||
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm");
 | 
			
		||||
 | 
			
		||||
    public static List<String> migrate(InputStream current, InputStream source) {
 | 
			
		||||
        boolean migrated = false;
 | 
			
		||||
        List<String> content = Files.readToList(current);
 | 
			
		||||
        String cc = String.join("\n", content);
 | 
			
		||||
        String cs = String.join("\n", Files.readToList(source));
 | 
			
		||||
        SecuredFile c = SecuredFile.loadConfiguration(cc);
 | 
			
		||||
        SecuredFile s = SecuredFile.loadConfiguration(cs);
 | 
			
		||||
        String hash1 = Strings.hashKeyForDisk(cs, "sha-1");
 | 
			
		||||
        String hash2 = "";
 | 
			
		||||
        for (String line : content) {
 | 
			
		||||
            if (line.startsWith("# HASH ")) {
 | 
			
		||||
                hash2 = line.substring("# HASH ".length()).trim().split(" ")[0];
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (Objects.equals(hash1, hash2)) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        List<KV<String, String[]>> update = Lists.newArrayList();
 | 
			
		||||
        List<KV<String, Object>> contrast = contrast(c.getValues(true), s.getValues(true));
 | 
			
		||||
        for (KV<String, Object> pair : contrast) {
 | 
			
		||||
            int index = pair.getKey().lastIndexOf(".");
 | 
			
		||||
            if (pair.getValue() == null) {
 | 
			
		||||
                Object data = s.get(pair.getKey());
 | 
			
		||||
                String[] nodes = pair.getKey().split("\\.");
 | 
			
		||||
                int regex = 0;
 | 
			
		||||
                int match = 0;
 | 
			
		||||
                int find = -1;
 | 
			
		||||
                for (int i = 0; i < content.size(); i++) {
 | 
			
		||||
                    String line = content.get(i);
 | 
			
		||||
                    for (int j = regex; j < nodes.length; j++) {
 | 
			
		||||
                        if (line.matches("( *)(['\"])?(" + nodes[j] + ")(['\"])?:(.*)")) {
 | 
			
		||||
                            match++;
 | 
			
		||||
                            find = i;
 | 
			
		||||
                            regex = j;
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (find == -1) {
 | 
			
		||||
                    update.add(new KV<>(pair.getKey(), SecuredFile.dump(data).split("\n")));
 | 
			
		||||
                } else {
 | 
			
		||||
                    String space = Strings.copy("  ", nodes.length - 1);
 | 
			
		||||
                    String[] dumpList = SecuredFile.dump(data).split("\n");
 | 
			
		||||
                    if (dumpList.length > 1) {
 | 
			
		||||
                        IntStream.range(0, dumpList.length).forEach(j -> dumpList[j] = space + "  # " + dumpList[j]);
 | 
			
		||||
                    }
 | 
			
		||||
                    ArrayUtil.addAutoExpand(content, find + 1, space + "# ------------------------- #\n" + space + "#  UPDATE " + dateFormat.format(System.currentTimeMillis()) + "  #\n" + space + "# ------------------------- #", "");
 | 
			
		||||
                    if (dumpList.length == 1) {
 | 
			
		||||
                        ArrayUtil.addAutoExpand(content, find + 2, space + "# " + pair.getKey().substring(index + 1) + ": " + dumpList[0] + "\n", "");
 | 
			
		||||
                    } else {
 | 
			
		||||
                        ArrayUtil.addAutoExpand(content, find + 2, space + "# " + pair.getKey().substring(index + 1) + ":", "");
 | 
			
		||||
                        ArrayUtil.addAutoExpand(content, find + 3, String.join("\n# ", dumpList) + "\n", "");
 | 
			
		||||
                    }
 | 
			
		||||
                    migrated = true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (update.size() > 0) {
 | 
			
		||||
            content.add("");
 | 
			
		||||
            content.add("# ------------------------- #\n" + "#  UPDATE " + dateFormat.format(System.currentTimeMillis()) + "  #\n" + "# ------------------------- #");
 | 
			
		||||
            for (KV<String, String[]> pair : update) {
 | 
			
		||||
                if (pair.getValue().length == 1) {
 | 
			
		||||
                    content.add("# " + pair.getKey() + ": " + pair.getValue()[0]);
 | 
			
		||||
                } else {
 | 
			
		||||
                    content.add("# " + pair.getKey() + ":");
 | 
			
		||||
                    content.add(String.join("\n# ", pair.getValue()));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            migrated = true;
 | 
			
		||||
        }
 | 
			
		||||
        if (migrated) {
 | 
			
		||||
            if (hash2.isEmpty()) {
 | 
			
		||||
                content.add("");
 | 
			
		||||
                content.add("# --------------------------------------------- #");
 | 
			
		||||
                content.add("# HASH " + hash1 + " #");
 | 
			
		||||
                content.add("# --------------------------------------------- #");
 | 
			
		||||
            } else {
 | 
			
		||||
                for (int i = 0; i < content.size(); i++) {
 | 
			
		||||
                    String line = content.get(i);
 | 
			
		||||
                    if (line.startsWith("# HASH ")) {
 | 
			
		||||
                        content.set(i, "# HASH " + hash1 + " #");
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return migrated ? content : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static List<KV<String, Object>> contrast(Map<?, ?> current, Map<?, ?> source) {
 | 
			
		||||
        List<String> deleted = Lists.newArrayList();
 | 
			
		||||
        List<KV<String, Object>> difference = Lists.newArrayList();
 | 
			
		||||
        // change & add
 | 
			
		||||
        for (Map.Entry<?, ?> entry : current.entrySet()) {
 | 
			
		||||
            if (entry.getValue() instanceof ConfigurationSection) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (entry.getValue() instanceof Map && source.get(entry.getKey()) instanceof Map) {
 | 
			
		||||
                List<KV<String, Object>> contrast = contrast((Map<?, ?>) entry.getValue(), (Map<?, ?>) source.get(entry.getKey()));
 | 
			
		||||
                for (KV<String, Object> pair : contrast) {
 | 
			
		||||
                    pair.setKey(entry.getKey() + "." + pair.getKey());
 | 
			
		||||
                }
 | 
			
		||||
                difference.addAll(contrast);
 | 
			
		||||
            } else if (!Objects.equals(entry.getValue(), source.get(entry.getKey()))) {
 | 
			
		||||
                difference.add(new KV<>(entry.getKey().toString(), entry.getValue()));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // delete
 | 
			
		||||
        for (Map.Entry<?, ?> entry : source.entrySet()) {
 | 
			
		||||
            if (deleted.stream().anyMatch(delete -> entry.getKey().toString().startsWith(delete) && delete.split("\\.").length < entry.getKey().toString().split("\\.").length)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (entry.getValue() instanceof Map && current.get(entry.getKey()) instanceof Map) {
 | 
			
		||||
                List<KV<String, Object>> contrast = contrast((Map<?, ?>) entry.getValue(), (Map<?, ?>) source.get(entry.getKey()));
 | 
			
		||||
                for (KV<String, Object> pair : contrast) {
 | 
			
		||||
                    pair.setKey(entry.getKey() + "." + pair.getKey());
 | 
			
		||||
                }
 | 
			
		||||
                difference.addAll(contrast);
 | 
			
		||||
            } else if (!current.containsKey(entry.getKey())) {
 | 
			
		||||
                deleted.add(entry.getKey().toString());
 | 
			
		||||
                difference.add(new KV<>(entry.getKey().toString(), null));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return difference;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -19,7 +19,7 @@ import java.util.function.Consumer;
 | 
			
		||||
 */
 | 
			
		||||
public class TConfigWatcher {
 | 
			
		||||
 | 
			
		||||
    private static TConfigWatcher configWatcher = new TConfigWatcher();
 | 
			
		||||
    private final static TConfigWatcher configWatcher = new TConfigWatcher();
 | 
			
		||||
    private final ScheduledExecutorService service = Executors.newScheduledThreadPool(1, new BasicThreadFactory.Builder().namingPattern("TConfigWatcherService-%d").build());
 | 
			
		||||
    private final Map<WatchService, Triple<File, Object, Consumer<Object>>> map = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,11 @@
 | 
			
		||||
package io.izzel.taboolib.module.db.local;
 | 
			
		||||
 | 
			
		||||
import io.izzel.taboolib.module.lite.SimpleReflection;
 | 
			
		||||
import io.izzel.taboolib.util.Files;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.configuration.InvalidConfigurationException;
 | 
			
		||||
import org.bukkit.configuration.file.YamlConfiguration;
 | 
			
		||||
import org.yaml.snakeyaml.Yaml;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
@@ -11,7 +13,7 @@ import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.logging.Level;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Author sky, yumc
 | 
			
		||||
 * @Since 2020-02-28 11:14
 | 
			
		||||
 */
 | 
			
		||||
public class SecuredFile extends YamlConfiguration {
 | 
			
		||||
@@ -39,7 +41,7 @@ public class SecuredFile extends YamlConfiguration {
 | 
			
		||||
    public void load(File file) throws InvalidConfigurationException {
 | 
			
		||||
        String content = Files.readFromFile(file);
 | 
			
		||||
        try {
 | 
			
		||||
            super.loadFromString(Files.readFromFile(file));
 | 
			
		||||
            loadFromString(content);
 | 
			
		||||
        } catch (InvalidConfigurationException t) {
 | 
			
		||||
            Files.copy(file, new File(file.getParent(), file.getName() + "_" + new SimpleDateFormat("yyyyMMddHHmmss").format(System.currentTimeMillis()) + ".bak"));
 | 
			
		||||
            throw t;
 | 
			
		||||
@@ -60,6 +62,21 @@ public class SecuredFile extends YamlConfiguration {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String saveToString() {
 | 
			
		||||
        return super.saveToString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String dump(Object data) {
 | 
			
		||||
        Yaml yaml = (Yaml) SimpleReflection.getFieldValueChecked(YamlConfiguration.class, new YamlConfiguration(), "yaml", true);
 | 
			
		||||
        try {
 | 
			
		||||
            return yaml.dump(data);
 | 
			
		||||
        } catch (Throwable t) {
 | 
			
		||||
            t.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        return "";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static SecuredFile loadConfiguration(String contents) {
 | 
			
		||||
        SecuredFile config = new SecuredFile();
 | 
			
		||||
        try {
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,8 @@ public @interface TInject {
 | 
			
		||||
 | 
			
		||||
    State state() default State.NONE;
 | 
			
		||||
 | 
			
		||||
    boolean autoMigrate() default false;
 | 
			
		||||
 | 
			
		||||
    enum State {
 | 
			
		||||
 | 
			
		||||
        LOADING, STARTING, ACTIVATED, NONE
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ import java.util.Map;
 | 
			
		||||
 */
 | 
			
		||||
public class TInjectLoader implements TabooLibLoader.Loader {
 | 
			
		||||
 | 
			
		||||
    private static Map<Class<?>, TInjectTask> injectTypes = Maps.newLinkedHashMap();
 | 
			
		||||
    private static final Map<Class<?>, TInjectTask> injectTypes = Maps.newLinkedHashMap();
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        // Instance Inject
 | 
			
		||||
@@ -91,6 +91,9 @@ public class TInjectLoader implements TabooLibLoader.Loader {
 | 
			
		||||
                        t.printStackTrace();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (args.autoMigrate()) {
 | 
			
		||||
                    config.migrate();
 | 
			
		||||
                }
 | 
			
		||||
                TabooLibLoader.runTask(config::runListener);
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@ public class ArrayUtil {
 | 
			
		||||
    public static <T> boolean contains(T[] array, T obj) {
 | 
			
		||||
        return indexOf(array, obj) != -1;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    public static <T> int indexOf(T[] array, T obj) {
 | 
			
		||||
        return array == null || array.length == 0 ? -1 : IntStream.range(0, array.length).filter(i -> array[i] != null && array[i].equals(obj)).findFirst().orElse(-1);
 | 
			
		||||
    }
 | 
			
		||||
@@ -73,6 +73,22 @@ public class ArrayUtil {
 | 
			
		||||
        return arrayNew;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T> List<T> setAutoExpand(List<T> list, int index, T element, T def) {
 | 
			
		||||
        while (list.size() <= index) {
 | 
			
		||||
            list.add(def);
 | 
			
		||||
        }
 | 
			
		||||
        list.set(index, element);
 | 
			
		||||
        return list;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T> List<T> addAutoExpand(List<T> list, int index, T element, T def) {
 | 
			
		||||
        while (list.size() <= index) {
 | 
			
		||||
            list.add(def);
 | 
			
		||||
        }
 | 
			
		||||
        list.add(index, element);
 | 
			
		||||
        return list;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings("SuspiciousSystemArraycopy")
 | 
			
		||||
    public static <T> T arrayExpand(T oldArray, int expand) {
 | 
			
		||||
        int length = Array.getLength(oldArray);
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ import java.security.MessageDigest;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import java.util.concurrent.CopyOnWriteArrayList;
 | 
			
		||||
import java.util.jar.JarFile;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
import java.util.zip.ZipEntry;
 | 
			
		||||
import java.util.zip.ZipFile;
 | 
			
		||||
 | 
			
		||||
@@ -70,6 +71,10 @@ public class Files {
 | 
			
		||||
        return plugin instanceof InternalPlugin ? getTabooLibResource(filename) : plugin.getClass().getClassLoader().getResourceAsStream(filename);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static InputStream getResourceChecked(Plugin plugin, String filename) {
 | 
			
		||||
        return plugin instanceof InternalPlugin ? getResource(plugin, "__resources__/" + filename) : getResource(filename);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static InputStream getTabooLibResource(String filename) {
 | 
			
		||||
        return getCanonicalResource(TabooLib.getPlugin(), filename);
 | 
			
		||||
    }
 | 
			
		||||
@@ -234,7 +239,7 @@ public class Files {
 | 
			
		||||
        return Optional.ofNullable(readFromURL(url)).orElse(def);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String readFromURL(String url,  Charset charset, String def) {
 | 
			
		||||
    public static String readFromURL(String url, Charset charset, String def) {
 | 
			
		||||
        return Optional.ofNullable(readFromURL(url, charset)).orElse(def);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -273,6 +278,24 @@ public class Files {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static List<String> readToList(File file) {
 | 
			
		||||
        try (FileInputStream fin = new FileInputStream(file); InputStreamReader isr = new InputStreamReader(fin, StandardCharsets.UTF_8); BufferedReader bin = new BufferedReader(isr)) {
 | 
			
		||||
            return bin.lines().collect(Collectors.toList());
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        return Collections.emptyList();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static List<String> readToList(InputStream inputStream) {
 | 
			
		||||
        try (InputStreamReader isr = new InputStreamReader(inputStream, StandardCharsets.UTF_8); BufferedReader bin = new BufferedReader(isr)) {
 | 
			
		||||
            return bin.lines().collect(Collectors.toList());
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        return Collections.emptyList();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String readFromStream(InputStream in) {
 | 
			
		||||
        return readFromStream(in, 1024, StandardCharsets.UTF_8);
 | 
			
		||||
    }
 | 
			
		||||
@@ -296,7 +319,9 @@ public class Files {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void read(File file, ReadHandle readHandle) {
 | 
			
		||||
        try (FileReader fileReader = new FileReader(file); BufferedReader bufferedReader = new BufferedReader(fileReader)) {
 | 
			
		||||
        try (FileInputStream fileInputStream = new FileInputStream(file);
 | 
			
		||||
             InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8);
 | 
			
		||||
             BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
 | 
			
		||||
            readHandle.read(bufferedReader);
 | 
			
		||||
        } catch (Throwable t) {
 | 
			
		||||
            t.printStackTrace();
 | 
			
		||||
@@ -304,7 +329,8 @@ public class Files {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void read(InputStream in, ReadHandle readHandle) {
 | 
			
		||||
        try (InputStreamReader inputStreamReader = new InputStreamReader(in); BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
 | 
			
		||||
        try (InputStreamReader inputStreamReader = new InputStreamReader(in, StandardCharsets.UTF_8);
 | 
			
		||||
             BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
 | 
			
		||||
            readHandle.read(bufferedReader);
 | 
			
		||||
        } catch (Throwable t) {
 | 
			
		||||
            t.printStackTrace();
 | 
			
		||||
@@ -312,7 +338,9 @@ public class Files {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void write(File file, WriteHandle writeHandle) {
 | 
			
		||||
        try (FileWriter fileWriter = new FileWriter(file); BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) {
 | 
			
		||||
        try (FileOutputStream fileOutputStream = new FileOutputStream(file);
 | 
			
		||||
             OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8);
 | 
			
		||||
             BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter)) {
 | 
			
		||||
            writeHandle.write(bufferedWriter);
 | 
			
		||||
            bufferedWriter.flush();
 | 
			
		||||
        } catch (Throwable t) {
 | 
			
		||||
@@ -321,7 +349,9 @@ public class Files {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void writeAppend(File file, WriteHandle writeHandle) {
 | 
			
		||||
        try (FileWriter fileWriter = new FileWriter(file, true); BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) {
 | 
			
		||||
        try (FileOutputStream fileOutputStream = new FileOutputStream(file, true);
 | 
			
		||||
             OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8);
 | 
			
		||||
             BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter)) {
 | 
			
		||||
            writeHandle.write(bufferedWriter);
 | 
			
		||||
            bufferedWriter.flush();
 | 
			
		||||
        } catch (Throwable t) {
 | 
			
		||||
@@ -330,7 +360,8 @@ public class Files {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void write(OutputStream out, WriteHandle writeHandle) {
 | 
			
		||||
        try (OutputStreamWriter outputStreamWriter = new OutputStreamWriter(out); BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter)) {
 | 
			
		||||
        try (OutputStreamWriter outputStreamWriter = new OutputStreamWriter(out, StandardCharsets.UTF_8);
 | 
			
		||||
             BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter)) {
 | 
			
		||||
            writeHandle.write(bufferedWriter);
 | 
			
		||||
            bufferedWriter.flush();
 | 
			
		||||
        } catch (Throwable t) {
 | 
			
		||||
@@ -355,14 +386,14 @@ public class Files {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String getFileHash(File file, String algorithm) {
 | 
			
		||||
        try(FileInputStream fileInputStream = new FileInputStream(file)) {
 | 
			
		||||
        try (FileInputStream fileInputStream = new FileInputStream(file)) {
 | 
			
		||||
            MessageDigest digest = MessageDigest.getInstance(algorithm);
 | 
			
		||||
            byte[] buffer = new byte[1024];
 | 
			
		||||
            int length;
 | 
			
		||||
            while ((length = fileInputStream.read(buffer, 0, 1024)) != -1) {
 | 
			
		||||
                digest.update(buffer, 0, length);
 | 
			
		||||
            }
 | 
			
		||||
            byte[] md5Bytes  = digest.digest();
 | 
			
		||||
            byte[] md5Bytes = digest.digest();
 | 
			
		||||
            return new BigInteger(1, md5Bytes).toString(16);
 | 
			
		||||
        } catch (Throwable t) {
 | 
			
		||||
            t.printStackTrace();
 | 
			
		||||
 
 | 
			
		||||
@@ -60,9 +60,13 @@ public class Strings {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String hashKeyForDisk(String key) {
 | 
			
		||||
        return hashKeyForDisk(key, "MD5");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String hashKeyForDisk(String key, String type) {
 | 
			
		||||
        String cacheKey;
 | 
			
		||||
        try {
 | 
			
		||||
            final MessageDigest mDigest = MessageDigest.getInstance("MD5");
 | 
			
		||||
            final MessageDigest mDigest = MessageDigest.getInstance(type);
 | 
			
		||||
            mDigest.update(key.getBytes());
 | 
			
		||||
            cacheKey = bytesToHexString(mDigest.digest());
 | 
			
		||||
        } catch (NoSuchAlgorithmException e) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user