load config comments

This commit is contained in:
jascotty2 2019-10-11 11:19:29 -05:00
parent 27fbe34c03
commit 67bbfceae4
4 changed files with 132 additions and 20 deletions

View File

@ -60,6 +60,14 @@ public class Comment {
public String toString() {
return lines.isEmpty() ? "" : lines.stream().collect(Collectors.joining("\n"));
}
public static Comment loadComment(List<String> lines) {
CommentStyle style = ConfigFormattingRules.parseStyle(lines);
int linePad = (style.drawBorder ? 1 : 0) + (style.drawSpace ? 1 : 0);
int prefix = style.commentPrefix.length();
int suffix = style.commentSuffix.length();
return new Comment(style, lines.subList(linePad, lines.size() - linePad).stream().map(s -> s.substring(prefix, s.length() - suffix).trim()).collect(Collectors.toList()));
}
public void writeComment(Writer output, int offset, CommentStyle defaultStyle) throws IOException {
CommentStyle style = commentStyle != null ? commentStyle : defaultStyle;

View File

@ -16,6 +16,7 @@ import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
@ -59,11 +60,12 @@ public class Config extends ConfigSection {
// public static valueOf(Map<String, ?> args);
// public new (Map<String, ?> args)
*/
protected static final String COMMENT_PREFIX = "# ";
protected static final String BLANK_CONFIG = "{}\n";
protected File file;
protected final ConfigFileConfigurationAdapter config = new ConfigFileConfigurationAdapter(this);
protected Comment headerComment = null;
protected Comment footerComment = null;
final String dirName, fileName;
final Plugin plugin;
final DumperOptions yamlOptions = new DumperOptions();
@ -306,9 +308,9 @@ public class Config extends ConfigSection {
@NotNull
public Config setHeader(@NotNull String... description) {
if (description.length == 0) {
configComments.remove(null);
headerComment = null;
} else {
configComments.put(null, new Comment(description));
headerComment = new Comment(description);
}
return this;
}
@ -316,9 +318,9 @@ public class Config extends ConfigSection {
@NotNull
public Config setHeader(@Nullable ConfigFormattingRules.CommentStyle commentStyle, @NotNull String... description) {
if (description.length == 0) {
configComments.remove(null);
headerComment = null;
} else {
configComments.put(null, new Comment(commentStyle, description));
headerComment = new Comment(commentStyle, description);
}
return this;
}
@ -326,9 +328,9 @@ public class Config extends ConfigSection {
@NotNull
public Config setHeader(@Nullable List<String> description) {
if (description == null || description.isEmpty()) {
configComments.remove(null);
headerComment = null;
} else {
configComments.put(null, new Comment(description));
headerComment = new Comment(description);
}
return this;
}
@ -336,17 +338,17 @@ public class Config extends ConfigSection {
@NotNull
public Config setHeader(@Nullable ConfigFormattingRules.CommentStyle commentStyle, @Nullable List<String> description) {
if (description == null || description.isEmpty()) {
configComments.remove(null);
headerComment = null;
} else {
configComments.put(null, new Comment(commentStyle, description));
headerComment = new Comment(commentStyle, description);
}
return this;
}
@NotNull
public List<String> getHeader() {
if (configComments.containsKey(null)) {
return configComments.get(null).getLines();
if (headerComment != null) {
return headerComment.getLines();
} else {
return Collections.EMPTY_LIST;
}
@ -442,6 +444,67 @@ public class Config extends ConfigSection {
// if starts with a comment, load all nonbreaking comments as a header
// then load all comments and assign to the next valid node loaded
// (Only load comments that are on their own line)
BufferedReader in = new BufferedReader(new StringReader(contents));
String line;
boolean insideScalar = false;
boolean firstNode = true;
int index = 0;
LinkedList<String> currentPath = new LinkedList();
ArrayList<String> commentBlock = new ArrayList();
try {
while ((line = in.readLine()) != null) {
if (line.isEmpty()) {
if (firstNode && !commentBlock.isEmpty()) {
// header comment
firstNode = false;
headerComment = Comment.loadComment(commentBlock);
commentBlock.clear();
}
continue;
} else if (line.trim().startsWith("#")) {
// only load full-line comments
commentBlock.add(line.trim());
continue;
}
// check to see if this is a line that we can process
int lineOffset = getOffset(line);
insideScalar &= lineOffset <= index;
Matcher m;
if (!insideScalar && (m = yamlNode.matcher(line)).find()) {
// we found a config node! ^.^
// check to see what the full path is
int depth = (m.group(1).length() / indentation);
while (depth < currentPath.size()) {
currentPath.removeLast();
}
currentPath.add(m.group(2));
// do we have a comment for this node?
if (!commentBlock.isEmpty()) {
String path = currentPath.stream().collect(Collectors.joining(String.valueOf(pathChar)));
Comment comment = Comment.loadComment(commentBlock);
commentBlock.clear();
setComment(path, comment);
}
firstNode = false; // we're no longer on the first node
// ignore scalars
index = lineOffset;
if (m.group(3).trim().equals("|") || m.group(3).trim().equals(">")) {
insideScalar = true;
}
}
}
if (!commentBlock.isEmpty()) {
footerComment = Comment.loadComment(commentBlock);
commentBlock.clear();
}
} catch (IOException ex) {
}
}
public void deleteNonDefaultSettings() {
@ -510,7 +573,7 @@ public class Config extends ConfigSection {
public boolean save(@NotNull File file) {
Validate.notNull(file, "File cannot be null");
if (!file.getParentFile().exists()) {
if (file.getParentFile() != null && !file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
String data = this.saveToString();
@ -525,22 +588,26 @@ public class Config extends ConfigSection {
@NotNull
public String saveToString() {
try {
if(autoremove) {
if (autoremove) {
deleteNonDefaultSettings();
}
yamlOptions.setIndent(indentation);
yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
StringWriter str = new StringWriter();
Comment header = configComments.get(null);
if (header != null) {
header.writeComment(str, 0, ConfigFormattingRules.CommentStyle.SPACED);
if (headerComment != null) {
headerComment.writeComment(str, 0, ConfigFormattingRules.CommentStyle.BLOCKED);
str.write("\n"); // add one space after the header
}
String dump = yaml.dump(this.getValues(false));
if (!dump.equals(BLANK_CONFIG)) {
writeComments(dump, str);
}
if (footerComment != null) {
str.write("\n");
footerComment.writeComment(str, 0, ConfigFormattingRules.CommentStyle.BLOCKED);
str.write("\n"); // add one space at the end of the file
}
return str.toString();
} catch (Throwable ex) {
Logger.getLogger(Config.class.getName()).log(Level.SEVERE, "Error saving config", ex);

View File

@ -1,5 +1,7 @@
package com.songoda.core.configuration;
import java.util.List;
public class ConfigFormattingRules {
int spacesBetweenMainCategories;
@ -66,4 +68,27 @@ public class ConfigFormattingRules {
}
}
public static CommentStyle parseStyle(List<String> lines) {
if(lines == null || lines.size() <= 2) {
return CommentStyle.SIMPLE;
} else if(lines.size() > 2 && lines.get(0).trim().equals("#") && lines.get(lines.size() - 1).trim().equals("#")) {
return CommentStyle.SPACED;
}
boolean hasBorders = lines.size() > 2 && lines.get(0).trim().matches("^##+$") && lines.get(lines.size() - 1).trim().matches("^##+$");
if(!hasBorders) {
// default return
return CommentStyle.SIMPLE;
}
// now need to figure out if this is blocked or not
if(lines.size() > 4 && lines.get(1).trim().matches(("^#"
+ CommentStyle.BLOCKSPACED.spacePrefixTop + CommentStyle.BLOCKSPACED.spaceCharTop + "+"
+ CommentStyle.BLOCKSPACED.spaceSuffixTop + "#$").replace("|", "\\|"))
&& lines.get(1).trim().matches(("^#"
+ CommentStyle.BLOCKSPACED.spacePrefixTop + CommentStyle.BLOCKSPACED.spaceCharTop + "+"
+ CommentStyle.BLOCKSPACED.spaceSuffixTop + "#$").replace("|", "\\|"))) {
return CommentStyle.BLOCKSPACED;
}
return CommentStyle.BLOCKED;
}
}

View File

@ -168,16 +168,21 @@ public class ConfigSection extends MemoryConfiguration {
@NotNull
public ConfigSection setComment(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, String... lines) {
return setComment(path, commentStyle, lines.length == 0 ? (List) null : Arrays.asList(lines));
return setComment(path, lines != null ? new Comment(commentStyle, lines) : null);
}
@NotNull
public ConfigSection setComment(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, @Nullable List<String> lines) {
return setComment(path, lines != null ? new Comment(commentStyle, lines) : null);
}
@NotNull
public ConfigSection setComment(@NotNull String path, @Nullable Comment comment) {
synchronized (root.lock) {
if (isDefault) {
root.defaultComments.put(fullPath + path, lines != null ? new Comment(commentStyle, lines) : null);
root.defaultComments.put(fullPath + path, comment);
} else {
root.configComments.put(fullPath + path, lines != null ? new Comment(commentStyle, lines) : null);
root.configComments.put(fullPath + path, comment);
}
}
return this;
@ -195,7 +200,6 @@ public class ConfigSection extends MemoryConfiguration {
}
return this;
}
@NotNull
public ConfigSection setDefaultComment(@NotNull String path, ConfigFormattingRules.CommentStyle commentStyle, String... lines) {
return setDefaultComment(path, commentStyle, lines.length == 0 ? (List) null : Arrays.asList(lines));
@ -209,6 +213,14 @@ public class ConfigSection extends MemoryConfiguration {
return this;
}
@NotNull
public ConfigSection setDefaultComment(@NotNull String path, @Nullable Comment comment) {
synchronized (root.lock) {
root.defaultComments.put(fullPath + path, comment);
}
return this;
}
@Nullable
public Comment getComment(@NotNull String path) {
Comment result = root.configComments.get(fullPath + path);