All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ru.cwcode.tkach.config.base.manager.ConfigManager Maven / Gradle / Ivy

The newest version!
package ru.cwcode.tkach.config.base.manager;

import org.jetbrains.annotations.NotNull;
import ru.cwcode.commands.api.Sender;
import ru.cwcode.tkach.config.Utils;
import ru.cwcode.tkach.config.annotation.Reloadable;
import ru.cwcode.tkach.config.base.Config;
import ru.cwcode.tkach.config.base.ConfigPersistOptions;
import ru.cwcode.tkach.config.base.ConfigPlatform;

import java.nio.file.Path;
import java.sql.Timestamp;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static ru.cwcode.tkach.config.server.ServerPlatform.l10n;

public abstract class ConfigManager> {
  protected final ConfigPlatform platform;
  
  protected final ConfigLoader loader; //file->str
  protected final ConfigPersister persister; //str->file
  protected final ConfigMapper mapper; //str > obj, obj>str
  protected final ConfigCreator creator; //null -> init
  
  protected HashMap configs = new HashMap<>();
  
  public ConfigManager(ConfigPlatform configPlatform,
                       ConfigLoader loader,
                       ConfigPersister persister,
                       ConfigMapper mapper,
                       ConfigCreator creator) {
    //
    this.platform = configPlatform;
    this.loader = loader;
    this.persister = persister;
    this.mapper = mapper;
    this.creator = creator;
    
    loader.setConfigManager(this);
    persister.setConfigManager(this);
    mapper.setConfigManager(this);
    creator.setConfigManager(this);
  }
  
  @NotNull
  private static ConfigPersistOptions loadOptions(Consumer options) {
    ConfigPersistOptions persistOptions = new ConfigPersistOptions();
    options.accept(persistOptions);
    return persistOptions;
  }
  
  public ConfigLoader loader() {
    return loader;
  }
  
  public ConfigPersister persister() {
    return persister;
  }
  
  public ConfigMapper mapper() {
    return mapper;
  }
  
  public ConfigPlatform platform() {
    return platform;
  }
  
  public  V load(String name, Class configClass) {
    return load(name, configClass, ConfigPersistOptions.DEFAULT);
  }
  
  public  V load(String name, Class configClass, Consumer options) {
    return load(name, configClass, loadOptions(options));
  }
  
  public  V load(String name, Class configClass, ConfigPersistOptions options) {
    AtomicBoolean shouldSave = new AtomicBoolean(false);
    
    Optional data = loader.load(name, options);
    Optional config = data.flatMap(x -> mapper.map(x, configClass, options));
    
    if (config.isEmpty()) {
      shouldSave.set(true);
      
      if (data.isPresent()) backupConfigFile(name, options);
      
      config = creator.create(name, configClass, options);
    }
    
    config.ifPresentOrElse(c -> {
      configs.put(name, c);
      c.setName(name);
      c.setManager(this);
      
      if (!options.isSilent()) {
        platform.info(l10n.get("config.manager.loaded", name));
      }
      
      if (shouldSave.get()) {
        save(c, options);
      }
    }, () -> {
      if (!options.isSilent()) {
        platform.info(l10n.get("config.manager.cantLoad", name));
      }
      platform.disable();
    });
    
    return config.orElse(null);
  }
  
  public void backupConfigFile(String name, Consumer options) {
    backupConfigFile(name, loadOptions(options));
  }
  
  public void backupConfigFile(String name, ConfigPersistOptions options) {
    Path original = getPath(name);
    Path backup = getPath(name + " " + new Timestamp(System.currentTimeMillis()).toString().replace(":", "-"));
    
    if (!options.isSilent()) {
      platform.warning(l10n.get("config.manager.backup", name, backup));
    }
    
    Utils.copy(original, backup);
  }
  
  public  void save(V config) {
    save(config, __ -> {});
  }
  
  public void save(C config, Consumer options) {
    save(config, loadOptions(options));
  }
  
  public void save(C config, ConfigPersistOptions options) {
    if (config == null) return;
    
    mapper.map(config, options)
          .ifPresentOrElse(data -> {
            persister.persist(config, data, getPath(config.name()), options);
          }, () -> {
            if (!options.isSilent()) {
              platform.info(l10n.get("config.manager.cantMap", config.name()));
            }
          });
  }
  
  public void saveAll() {
    saveAll(__ -> {});
  }
  
  public void saveAll(Consumer options) {
    saveAll(loadOptions(options));
  }
  
  public void saveAll(ConfigPersistOptions options) {
    if (options.isAsync()) {
      options.async(false); //не лучшая идея, но проблем пока что быть не должно
      
      platform.runAsync(() -> {
        saveAll0(options);
      });
    } else {
      saveAll0(options);
    }
  }
  
  public boolean reload(Sender sender, C config) {
    if (config instanceof Reloadable reloadable) {
      if (reloadable.reload()) {
        sender.sendMessage(l10n.get("config.manager.reloaded", config.name()));
        return true;
      } else {
        sender.sendMessage(l10n.get("config.manager.cantReload", config.name()));
        return false;
      }
    }
    
    return false;
  }
  
  public List reloadAll(Sender sender) {
    List reloaded = new ArrayList<>();
    
    configs.forEach((name, config) -> {
      if (reload(sender, config)) {
        findConfig(config.name()).ifPresent(reloaded::add);
      }
    });
    
    return reloaded;
  }
  
  protected void saveAll0(ConfigPersistOptions options) {
    if (!options.isSilent()) {
      platform.info(l10n.get("config.manager.saveAll"));
    }
    
    configs.values().forEach(config -> {
      if (config.saveAllEnabled()) save(config, options);
    });
  }
  
  public Path getPath(String name) {
    return platform.dataFolder().resolve(name + ".yml");
  }
  
  public  String toString(V config) {
    return mapper.map(config, ConfigPersistOptions.DEFAULT).orElse(null);
  }
  
  public Set getConfigNames(Predicate predicate) {
    return configs.values().stream()
                  .filter(predicate)
                  .map(Config::name)
                  .collect(Collectors.toSet());
  }
  
  public void scheduleAutosave(Duration frequency, Consumer options) {
    platform.schedule(() -> saveAll(loadOptions(options)), frequency, loadOptions(options).isAsync());
  }
  
  public Optional findConfig(String name) {
    return Optional.ofNullable(configs.get(name));
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy