SnuviConfig.java 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. package me.hammerle.snuviscript.config;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.nio.charset.MalformedInputException;
  5. import java.nio.charset.StandardCharsets;
  6. import java.nio.file.Files;
  7. import java.nio.file.Path;
  8. import java.nio.file.Paths;
  9. import java.util.TreeMap;
  10. import java.util.stream.Collectors;
  11. import me.hammerle.snuviscript.code.FunctionRegistry;
  12. import me.hammerle.snuviscript.code.Script;
  13. import me.hammerle.snuviscript.code.ScriptManager;
  14. import me.hammerle.snuviscript.code.SnuviUtils;
  15. import me.hammerle.snuviscript.exceptions.StackTrace;
  16. public class SnuviConfig {
  17. private final TreeMap<String, Object> conf = new TreeMap<>();
  18. private final File file;
  19. private boolean dirty = false;
  20. public SnuviConfig(String path, String name) {
  21. StringBuilder sb = new StringBuilder("./");
  22. sb.append(path);
  23. sb.append("/");
  24. sb.append(name);
  25. sb.append(".snuvic");
  26. file = new File(sb.toString());
  27. }
  28. private void print(Script sc, String message, Exception ex) {
  29. if(sc == null) {
  30. System.out.println(message);
  31. ex.printStackTrace();
  32. return;
  33. }
  34. ScriptManager sm = sc.getScriptManager();
  35. final StackTrace trace = sc.getStackTrace();
  36. sm.getScheduler().scheduleTask("config_print", () -> {
  37. sm.getLogger().print(message, ex, null, sc.getName(), sc, trace);
  38. });
  39. }
  40. private void print(Script sc, String message) {
  41. print(sc, message, null);
  42. }
  43. public final synchronized void load(Script sc) {
  44. if(!exists()) {
  45. print(sc, "cannot load non existent file '" + file.getPath() + "'");
  46. return;
  47. }
  48. try {
  49. String warning = "wrong syntax in '" + file.getPath() + "'";
  50. Files.readAllLines(file.toPath()).stream().forEach(s -> {
  51. int b = s.indexOf("=");
  52. if(b == -1) {
  53. print(sc, warning);
  54. print(sc, s);
  55. } else {
  56. conf.put(s.substring(0, b).trim(), SnuviUtils.convert(s.substring(b + 1)));
  57. }
  58. });
  59. } catch(MalformedInputException ex) {
  60. print(sc,
  61. "'" + file.getPath() + "' contains an illegal character, change file encoding",
  62. ex);
  63. } catch(OutOfMemoryError ex) {
  64. print(sc, "'" + file.getPath() + "' is too big");
  65. } catch(SecurityException ex) {
  66. print(sc, "'" + file.getPath() + "' is not accessable", ex);
  67. } catch(IOException ex) {
  68. print(sc, "'" + file.getPath() + "' cannot be read", ex);
  69. }
  70. }
  71. public final boolean exists() {
  72. return file.exists();
  73. }
  74. public final synchronized boolean delete() {
  75. return file.delete();
  76. }
  77. public final synchronized boolean save(Script sc) {
  78. if(conf.isEmpty() || !dirty) {
  79. return false;
  80. }
  81. dirty = false;
  82. try {
  83. Path p = Paths.get(file.toURI());
  84. Files.write(p, conf.entrySet().stream().map(e -> {
  85. if(e.getValue().getClass() == String.class) {
  86. return String.format("%s=\"%s\"", e.getKey(),
  87. e.getValue().toString().replaceAll("\n", "\\n"));
  88. }
  89. return String.format("%s=%s", e.getKey(), e.getValue());
  90. }).collect(Collectors.toList()), StandardCharsets.UTF_8);
  91. Files.setPosixFilePermissions(p, FunctionRegistry.FILE_ACCESS);
  92. return true;
  93. } catch(UnsupportedOperationException ex) {
  94. print(sc, "an unsupported operation was used", ex);
  95. return false;
  96. } catch(SecurityException ex) {
  97. print(sc, "'" + file.getPath() + "' is not accessable", ex);
  98. return false;
  99. } catch(IOException ex) {
  100. print(sc, "cannot write to '" + file.getPath() + "'", ex);
  101. return false;
  102. }
  103. }
  104. public final synchronized <T> T get(Script sc, String key, Class<T> c, T error) {
  105. try {
  106. Object o = conf.get(key);
  107. if(o == null) {
  108. return error;
  109. }
  110. return c.cast(o);
  111. } catch(ClassCastException ex) {
  112. print(sc, "invalid get", ex);
  113. return error;
  114. }
  115. }
  116. public final String getString(Script sc, String key, String error) {
  117. return get(sc, key, String.class, error);
  118. }
  119. public final String getString(Script sc, String key) {
  120. return getString(sc, key, null);
  121. }
  122. public final float getFloat(Script sc, String key, float error) {
  123. return get(sc, key, Double.class, (double) error).floatValue();
  124. }
  125. public final double getDouble(Script sc, String key, double error) {
  126. return get(sc, key, Double.class, error);
  127. }
  128. public final long getLong(Script sc, String key, long error) {
  129. return get(sc, key, Double.class, (double) error).longValue();
  130. }
  131. public final int getInt(Script sc, String key, int error) {
  132. return get(sc, key, Double.class, (double) error).intValue();
  133. }
  134. public final boolean getBoolean(Script sc, String key, boolean error) {
  135. return get(sc, key, Boolean.class, error);
  136. }
  137. public final synchronized void set(String key, Object o) {
  138. dirty = true;
  139. conf.put(key, o);
  140. }
  141. }