Skip to content
This repository has been archived by the owner on Apr 5, 2024. It is now read-only.

Commit

Permalink
for the comments
Browse files Browse the repository at this point in the history
  • Loading branch information
KrLite committed Dec 23, 2022
1 parent fbb207e commit 096301c
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 35 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ org.gradle.parallel = true
loader_version = 0.14.11

# Mod Properties
mod_version = 3.2.0
mod_version = 3.2.1
maven_group = net.krlite
archives_base_name = plumeconfig-1.19

Expand Down
16 changes: 9 additions & 7 deletions src/main/java/example/Example.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,35 @@
import net.krlite.plumeconfig.annotation.Category;
import net.krlite.plumeconfig.annotation.Comment;
import net.krlite.plumeconfig.annotation.Option;
import net.krlite.plumeconfig.io.LineBreak;

import java.awt.*;

@Comment("This is a comment")
@Comment(value = "at the top of the file", newLine = LineBreak.AFTER)
public class Example {
public @Comment int comment = 1; // Integer comment

public @Comment String comment2 = "comment2\ncommented line"; // Multi-line comment

@Comment("Multi-line\ncomment")
@Option(name = "String", comment = "A String\n Comment")
@Category("abc")
public String s = "string"; // A String option named "String" with a comment(line breaks will be ignored)

@Comment("An integer")
@Option(key = "integer", name = "Int") // An Integer option named "Int" with a specified key "integer"
public int i = 1;

@Category("abc")
private final @Comment String comment3 = "comment3"; // A comment in the category "abc"

@Category("abc")
private static final @Option double d = 1.0; // A double option in the category "abc"

public static int silent = 1; // No annotations, will be ignored

@Comment("This comment is useless and won't appear")
private static final int silent2 = 1;

@Comment("A color")
@Comment("Which is under supported")
@Category("def")
public static @Option Color color = Color.BLACK; // A Color option in the category "def"

@Comment("A boolean")
public static @Option boolean bool; // A boolean option
}
12 changes: 7 additions & 5 deletions src/main/java/net/krlite/plumeconfig/annotation/Comment.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package net.krlite.plumeconfig.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import net.krlite.plumeconfig.io.LineBreak;

@Target(ElementType.FIELD)
import java.lang.annotation.*;

@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Comments.class)
public @interface Comment {
String value() default "";
LineBreak newLine() default LineBreak.NONE;
}
12 changes: 12 additions & 0 deletions src/main/java/net/krlite/plumeconfig/annotation/Comments.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package net.krlite.plumeconfig.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Comments {
Comment[] value();
}
66 changes: 45 additions & 21 deletions src/main/java/net/krlite/plumeconfig/base/ConfigFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import net.krlite.plumeconfig.PlumeConfigMod;
import net.krlite.plumeconfig.annotation.Category;
import net.krlite.plumeconfig.annotation.Comment;
import net.krlite.plumeconfig.annotation.Comments;
import net.krlite.plumeconfig.annotation.Option;
import net.krlite.plumeconfig.api.EnumLocalizable;
import net.krlite.plumeconfig.exception.ClassException;
Expand All @@ -12,7 +13,6 @@
import net.krlite.plumeconfig.io.MappedString;
import net.krlite.plumeconfig.io.Reader;
import net.krlite.plumeconfig.io.Writer;
import org.jetbrains.annotations.Nullable;
import org.tomlj.TomlParseResult;

import java.io.File;
Expand Down Expand Up @@ -106,9 +106,24 @@ public <T> void save(T instance) {
FileException.traceFileWritingException(PlumeConfigMod.LOGGER, ioException, file);
}

// Writes the class comments if annotated by @Comments, otherwise writes the comment if annotated by @Comment
if (instance.getClass().isAnnotationPresent(Comments.class)) {
Comments comments = instance.getClass().getAnnotation(Comments.class);
Arrays.stream(comments.value()).filter(Objects::nonNull).forEach(comment -> {
if (comment.newLine().isBefore()) writeLine("");
writeLine(comment.value());
if (comment.newLine().isAfter()) writeLine("");
});
} else if (instance.getClass().isAnnotationPresent(Comment.class)) {
Comment comment = instance.getClass().getAnnotation(Comment.class);
if (comment.newLine().isBefore()) writeLine("");
writeLine(comment.value());
if (comment.newLine().isAfter()) writeLine("");
}

// Fields annotated by @Comment or @Option
Field[] fields = Arrays.stream(instance.getClass().getDeclaredFields())
.filter(field -> field.isAnnotationPresent(Option.class) || field.isAnnotationPresent(Comment.class)).toArray(Field[]::new);
.filter(field -> field.isAnnotationPresent(Option.class)).toArray(Field[]::new);

// Save Uncategorized fields
Arrays.stream(fields).filter(field -> !field.isAnnotationPresent(Category.class)).forEach(field -> iteratorFieldSave(instance, field));
Expand Down Expand Up @@ -171,36 +186,41 @@ private void iteratorFieldSave(Object instance, Field field) {
if (field.isAnnotationPresent(Category.class)) writeCategory(field.getAnnotation(Category.class));
field.setAccessible(true);

// Writes the field as a comment, if annotated by @Comment
if (field.isAnnotationPresent(Comment.class)) {
try {
writeLine(field.get(instance));
} catch (IllegalAccessException illegalAccessException) {
FieldException.traceFieldAccessingException(PlumeConfigMod.LOGGER, illegalAccessException, file, field);
}
return;
// Writes the field comments if annotated by @Comments, otherwise writes the comment if annotated by @Comment
if (field.isAnnotationPresent(Comments.class)) {
Comments comments = field.getAnnotation(Comments.class);
Arrays.stream(comments.value()).filter(Objects::nonNull).forEach(comment -> {
if (comment.newLine().isBefore()) writeLine("");
writeLine(comment.value());
if (comment.newLine().isAfter()) writeLine("");
});
} else if (field.isAnnotationPresent(Comment.class)) {
Comment comment = field.getAnnotation(Comment.class);
if (comment.newLine().isBefore()) writeLine("");
writeLine(comment.value());
if (comment.newLine().isAfter()) writeLine("");
}

// Writes the field as an option, if annotated by @Option and not annotated by @Comment
// Writes the field option
if (field.isAnnotationPresent(Option.class)) {
Option option = field.getAnnotation(Option.class);
String key = !option.key().isEmpty() ? option.key() : field.getName();
try {
if (field.getType().isEnum()) {
if (EnumLocalizable.class.isAssignableFrom(field.getType())) {
if (EnumLocalizable.class.isAssignableFrom(field.getType())) { // Localizable enum (Enum<?> extends EnumLocalizable)
writeLine(
key, FieldFunction.savingFunctions(modid,
((EnumLocalizable) field.get(instance)).getLocalizedName()),
option.name(), option.comment()
);
} else {
} else { // Non-localizable enum (Enum<?>)
writeLine(
key, FieldFunction.savingFunctions(modid,
((Enum<?>) field.get(instance)).name()),
option.name(), option.comment()
);
}
} else {
} else { // Non-enum
writeLine(
key, FieldFunction.savingFunctions(modid,
field.get(instance)),
Expand Down Expand Up @@ -230,22 +250,22 @@ private void iteratorFieldLoad(Object instance, Field field, TomlParseResult tom
try {
if (field.getType().isEnum()) {
String value = toml.getString(key);
if (EnumLocalizable.class.isAssignableFrom(field.getType())) {
if (EnumLocalizable.class.isAssignableFrom(field.getType())) { // Localizable enum (Enum<?> extends EnumLocalizable)
field.set(
instance,
Arrays.stream((EnumLocalizable[]) field.get(instance).getClass().getEnumConstants())
.filter(enumLocalizable -> enumLocalizable.getLocalizedName().equals(value))
.findFirst().orElse((EnumLocalizable) field.get(instance))
);
} else {
} else { // Non-localizable enum (Enum<?>)
field.set(
instance,
Arrays.stream((Enum<?>[]) field.get(instance).getClass().getEnumConstants())
.filter(enumConstant -> enumConstant.name().equals(value))
.findFirst().orElse((Enum<?>) field.get(instance))
);
}
} else {
} else { // Non-enum
field.set(instance, FieldFunction.functions(modid, field.getType(), toml.get(key)));
}
} catch (IllegalAccessException illegalAccessException) {
Expand All @@ -264,11 +284,15 @@ private void iteratorFieldLoad(Object instance, Field field, TomlParseResult tom
private void writeLine(Object... contents) {
if (contents.length == 0) return;
Writer writer = new Writer(file);
contents = Arrays.stream(contents).filter(Objects::nonNull).filter(value -> !value.toString().isEmpty()).toArray(); // Filter null and empty values
if (contents.length <= 1) { // It's a comment
contents = Arrays.stream(contents).filter(Objects::nonNull).toArray(); // Filter null values
if (contents.length <= 1) { // A comment
Arrays.stream(contents[0].toString().split("\n"))
.forEach(line -> writer.writeAndEndLine("# " + line.replaceAll("\n", "")));
} else { // It's an option (contents are at least key+value)
.forEach(line -> {
if (!line.isEmpty()) writer.writeAndEndLine("# " + new MappedString(line).mapLineBreaks().get());
else writer.writeAndEndLine("");
});
} else { // An option (contents are at least key+value)
contents = Arrays.stream(contents).filter(content -> !content.toString().isEmpty()).toArray(); // Filter empty values
writer.write(contents[0].toString() + " = " + contents[1].toString()); // key = value
if (contents.length >= 4) {
// It has both a name and a comment
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/net/krlite/plumeconfig/io/LineBreak.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package net.krlite.plumeconfig.io;

public enum LineBreak {
NONE(false, false),
BEFORE(true, false),
AFTER(false, true),
BOTH(true, true);

private final boolean before;
private final boolean after;

LineBreak(boolean before, boolean after) {
this.before = before;
this.after = after;
}

public boolean isBefore() {
return before;
}

public boolean isAfter() {
return after;
}
}
3 changes: 2 additions & 1 deletion src/main/java/net/krlite/plumeconfig/io/Writer.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ public void format() {
}
lastLine = line;
}
raw = raw.stream().dropWhile(String::isEmpty).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
flipStream(raw);
// The flipped content is prepared for removing empty lines at tail
// Remove empty lines at the start of the stream
ArrayList<String> formatted = raw.stream().dropWhile(String::isEmpty).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
// Flip it again to get the original order
flipStream(formatted);
Expand Down

0 comments on commit 096301c

Please sign in to comment.