All source projects
MrUltimateLibrary Source
Standalone source project / 68 files
MrUltimateLibrary is the backbone of all my plugins; it offers features that facilitate plugin creation, maintenance, and updates.
java
MrUltimateLibrary/src/main/java/eu/mrneznamy/mrultimatelibrary/config/MrLibYamlConfiguration.java
JAVA · Read-only source
package eu.mrneznamy.mrultimatelibrary.config;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.*;
/**
* Extended YAML configuration with comment support
* Inspired by CMILib's ConfigReader
*/
public class MrLibYamlConfiguration extends YamlConfiguration {
private final Map<String, String> comments = new HashMap<>();
private final List<String> headerComments = new ArrayList<>();
/**
* Adds a comment to a specific path
* @param path Config path (e.g. "MrSellChests.Database.Type")
* @param comment Comment text (without #)
*/
public void addComment(String path, String comment) {
if (path.equals("_HEADER_")) {
headerComments.add(comment);
} else {
comments.put(path, comment);
}
}
public Map<String, String> getComments() {
return comments;
}
/**
* Adds multiple comment lines to a path
*/
public void addComments(String path, String... commentLines) {
StringBuilder sb = new StringBuilder();
for (String line : commentLines) {
sb.append(line).append(System.lineSeparator());
}
addComment(path, sb.toString().trim());
}
/**
* Sets header comments for the file
*/
public void setHeaderComments(List<String> comments) {
this.headerComments.clear();
this.headerComments.addAll(comments);
}
@Override
public void save(File file) throws IOException {
if (file == null) {
throw new IllegalArgumentException("File cannot be null");
}
file.getParentFile().mkdirs();
String yaml = saveToString();
String yamlWithComments = insertComments(yaml);
try (PrintWriter writer = new PrintWriter(file, StandardCharsets.UTF_8.name())) {
writer.write(yamlWithComments);
}
}
/**
* Inserts comments into YAML string
*/
private String insertComments(String yaml) {
if (comments.isEmpty() && headerComments.isEmpty()) {
return yaml;
}
StringBuilder result = new StringBuilder();
if (!headerComments.isEmpty()) {
for (String comment : headerComments) {
result.append(comment).append(System.lineSeparator());
}
result.append(System.lineSeparator());
}
String[] lines = yaml.split(System.lineSeparator());
StringBuilder currentPath = new StringBuilder();
int depth = 0;
for (String line : lines) {
if (line.trim().isEmpty() && result.length() == 0) {
continue;
}
if (isKeyLine(line)) {
int lineDepth = getDepth(line);
String key = extractKey(line);
if (key != null && !key.isEmpty()) {
updatePath(currentPath, key, lineDepth, depth);
depth = lineDepth;
String comment = comments.get(currentPath.toString());
if (comment != null && !comment.isEmpty()) {
String indent = getIndent(lineDepth);
String[] commentLines = comment.split(System.lineSeparator());
for (String commentLine : commentLines) {
result.append(indent).append(commentLine).append(System.lineSeparator());
}
}
}
}
result.append(line).append(System.lineSeparator());
}
return result.toString();
}
/**
* Checks if line is a key line
*/
private boolean isKeyLine(String line) {
String trimmed = line.trim();
return !trimmed.isEmpty() &&
!trimmed.startsWith("#") &&
!trimmed.startsWith("-") &&
(trimmed.contains(": ") || trimmed.endsWith(":"));
}
/**
* Gets the depth (indentation level) of a line
*/
private int getDepth(String line) {
int spaces = 0;
for (char c : line.toCharArray()) {
if (c == ' ') {
spaces++;
} else {
break;
}
}
return spaces / 2;
}
/**
* Extracts the key from a line
*/
private String extractKey(String line) {
String trimmed = line.trim();
int colonIndex = trimmed.indexOf(':');
if (colonIndex > 0) {
return trimmed.substring(0, colonIndex).trim();
}
return null;
}
/**
* Updates the current path based on depth
*/
private void updatePath(StringBuilder currentPath, String key, int newDepth, int oldDepth) {
if (newDepth == 0) {
currentPath.setLength(0);
currentPath.append(key);
} else if (newDepth > oldDepth) {
currentPath.append(".").append(key);
} else if (newDepth < oldDepth) {
int levelsUp = oldDepth - newDepth;
for (int i = 0; i < levelsUp; i++) {
int lastDot = currentPath.lastIndexOf(".");
if (lastDot > 0) {
currentPath.setLength(lastDot);
}
}
int lastDot = currentPath.lastIndexOf(".");
if (lastDot > 0) {
currentPath.setLength(lastDot + 1);
currentPath.append(key);
} else {
currentPath.setLength(0);
currentPath.append(key);
}
} else {
int lastDot = currentPath.lastIndexOf(".");
if (lastDot > 0) {
currentPath.setLength(lastDot + 1);
currentPath.append(key);
} else {
currentPath.setLength(0);
currentPath.append(key);
}
}
}
/**
* Gets indentation string for a given depth
*/
private String getIndent(int depth) {
StringBuilder indent = new StringBuilder();
for (int i = 0; i < depth * 2; i++) {
indent.append(" ");
}
return indent.toString();
}
/**
* Loads configuration from file and preserves comments
*/
public void loadWithComments(File file) throws Exception {
this.load(file);
}
}
216 linesGNU GENERAL PUBLIC LICENSE · Version 3, 29 June 2007 · UTF-8 · Read only