Make configurations with ease
JavaDocs: https://jd.mrivanplays.com/annotationconfig/
WARNING: You may want to read CHANGELOG.md before seeing anything from this section.
Config example
importcom.mrivanplays.annotationconfig.core.annotations.ConfigObject;
importcom.mrivanplays.annotationconfig.core.annotations.Ignore;
importcom.mrivanplays.annotationconfig.core.annotations.Key;
importcom.mrivanplays.annotationconfig.core.annotations.Max;
importcom.mrivanplays.annotationconfig.core.annotations.Min;
importcom.mrivanplays.annotationconfig.core.annotations.comment.Comment;
importcom.mrivanplays.annotationconfig.core.serialization.DataObject;
importcom.mrivanplays.annotationconfig.core.serialization.FieldTypeSerializer;
importjava.lang.reflect.Field;
importjava.util.Arrays;
importjava.util.LinkedHashMap;
importjava.util.List;
importjava.util.Map;
@Comment("Generated by AnnotatedConfig v2.1.0")
@Comment("This is a config example for developers.")
publicclassExampleAnnotatedConfig {
@Comment("This value can only be between 1 and 3 ( 1 and 3 included )")
@Min(minInt = 1)
@Max(maxInt = 3)
privateintfoo = 2;
@Comment("This string cannot be longer than 20 characters ( spaces are included )")
@Max(maxInt = 20)
privateStringbar = "This is some string";
@ConfigObjectprivateMessagesSectionmessages = newMessagesSection();
@Comment("All configurable messages")
publicstaticfinalclassMessagesSection {
@Comment("The no permission message")
@Key("no-permission")
privateStringnoPermission = "You don't have permission to perform this command";
@Comment("The no spamming message")
@Key("no-spamming")
privateStringnoSpamming = "You can't spam this";
publicStringgetNoPermission() {
returnnoPermission;
}
publicStringgetNoSpamming() {
returnnoSpamming;
}
}
@IgnoreprivateStringimportantClass = "com.mrivanplays.something.Important"; // this is ignored@Comment("This is also going to be serialized as a config object,")
@Comment("but it is much more controllable rather than @ConfigObject")
privateSomethingToSerializeserialize = newSomethingToSerialize("foo", 1, (byte) 0x2);
publicstaticfinalclassSomethingToSerialize {
privatefinalStringfoo;
privatefinalintbar;
privatefinalbytebaz;
publicSomethingToSerialize(Stringfoo, intbar, bytebaz) {
this.foo = foo;
this.bar = bar;
this.baz = baz;
}
publicStringgetFoo() {
returnfoo;
}
publicintgetBar() {
returnbar;
}
publicbytegetBaz() {
returnbaz;
}
}
/** * This should be registered before calling the dump method for this annotated config using the * SerializerRegistry */publicstaticfinalclassSomethingToSerializeSerializerimplementsFieldTypeSerializer<SomethingToSerialize> {
@OverridepublicSomethingToSerializedeserialize(DataObjectdata, Fieldfield) {
returnnewSomethingToSerialize(
data.get("foo").getAsString(), data.get("bar").getAsInt(), data.get("baz").getAsByte());
}
@OverridepublicDataObjectserialize(SomethingToSerializevalue, Fieldfield) {
DataObjectret = newDataObject();
ret.put("foo", value.getFoo());
ret.put("bar", value.getBar());
ret.put("baz", value.getBaz());
returnret;
}
}
@Comment("This cannot have a negative value")
@Min(minDouble = 0)
@Key("barxtwo") // you can also apply @Key to regular fields, not just in config objectsprivatedoublebaz = 0.2;
@Comment("AnnotatedConfig can also read & write lists")
@Key("foo-list")
privateList<String> fooList = Arrays.asList("This is", "a lore", "as an example", "for list");
@Comment("Lists can be of all primitive types")
@Key("bar-list")
privateList<Integer> barList = Arrays.asList(1, 2, 3, 4);
@Comment("Same for maps, but a map can only be Map<String, Object>")
@Comment("otherwise you will need another object")
@Key("foo-map")
privateMap<String, Object> fooMap =
newLinkedHashMap<String, Object>() {
{
put("foo", 1);
put("bar", "This is a section value");
put("baz", 3);
}
};
@Comment("This doesn't have a serializer registered")
@Comment("so it gets serialized by the default serializer")
@Key("default-serializer-example")
privateDefaultSerializationExampledefaultSerExample =
newDefaultSerializationExample("bar", 1, 5.6);
publicstaticfinalclassDefaultSerializationExample {
privateStringfoo;
privateintbar;
privatedoublebaz;
publicDefaultSerializationExample(Stringfoo, intbar, doublebaz) {
this.foo = foo;
this.bar = bar;
this.baz = baz;
}
publicStringgetFoo() {
returnfoo;
}
publicintgetBar() {
returnbar;
}
publicdoublegetBaz() {
returnbaz;
}
}
@Comment("You can create sections like this too")
@Key("inside.section.foo")
privateStringfooInsideSection = "foo";
@ConfigObject@Key("section-inside-section")
privateSectionInsideSectioninsideSection = newSectionInsideSection();
@Comment("This is a section inside a section example")
publicstaticclassSectionInsideSection {
@Comment("Comments are supported here too!")
@Key("pp.baz")
privateintbaz = 69420;
@Comment("And here!")
@Key("pp.foo")
privatedoublefoo = 3.3;
publicintgetBaz() {
returnbaz;
}
publicdoublegetFoo() {
returnfoo;
}
}
// this is featured in the next examplepublicstaticclassSectionObject {
privateintaabb;
privateStringccdd;
publicSectionObject(intaabb, Stringccdd) {
this.aabb = aabb;
this.ccdd = ccdd;
}
publicintgetAabb() {
returnaabb;
}
publicStringgetCcdd() {
returnccdd;
}
}
@Comment("This is a section object list")
privateSectionObjectList<SectionObject> sectionObjectList =
SectionObjectList.newBuilderForType(SectionObject.class)
.defaultValue("asdfp", newSectionObject(1, "lorem"))
.defaultValue("pepepepepe", newSectionObject(2, "ipsum"))
.build();
publicintgetFoo() {
returnfoo;
}
publicStringgetBar() {
returnbar;
}
publicMessagesSectiongetMessages() {
returnmessages;
}
publicStringgetImportantClass() {
returnimportantClass;
}
publicSomethingToSerializegetSerialize() {
returnserialize;
}
publicdoublegetBaz() {
returnbaz;
}
publicList<String> getFooList() {
returnfooList;
}
publicList<Integer> getBarList() {
returnbarList;
}
publicMap<String, Object> getFooMap() {
returnfooMap;
}
publicDefaultSerializationExamplegetDefaultSerExample() {
returndefaultSerExample;
}
publicStringgetFooInsideSection() {
returnfooInsideSection;
}
publicSectionInsideSectiongetInsideSection() {
returninsideSection;
}
publicSectionObjectList<SectionObject> getSectionObjectList() {
returnsectionObjectList;
}
}Config example output (YAML)
Keep in mind in order to show you all of the features of AnnotatedConfig, everything has been stuffed in 1 class. Don't forget that in Java you can do multiple classes ;) . Line count doesn't matter.
# Generated by AnnotatedConfig v2.1.0# This is a config example for developers.# This cannot have a negative valuebarxtwo: 0.2# This is a section object listsectionObjectList:
asdfp:
aabb: 1ccdd: "lorem"pepepepepe:
aabb: 2ccdd: "ipsum"# This is also going to be serialized as a config object,# but it is much more controllable rather than @ConfigObjectserialize:
foo: "foo"bar: 1baz: 2# This string cannot be longer than 20 characters ( spaces are included )bar: "This is some string"# Same for maps, but a map can only be Map<String, Object># otherwise you will need another objectfoo-map:
foo: 1bar: "This is a section value"baz: 3# This value can only be between 1 and 3 ( 1 and 3 included )foo: 2# AnnotatedConfig can also read & write listsfoo-list:
- "This is"
- "a lore"
- "as an example"
- "for list"# All configurable messagesmessages:
# The no spamming messageno-spamming: "You can't spam this"# The no permission messageno-permission: "You don't have permission to perform this command"# This doesn't have a serializer registered# so it gets serialized by the default serializerdefault-serializer-example:
foo: "bar"bar: 1baz: 5.6# This is a section inside a section examplesection-inside-section:
pp:
# Comments are supported here too!baz: 69420# And here!foo: 3.3# Lists can be of all primitive typesbar-list:
- 1
- 2
- 3
- 4inside:
section:
# You can create sections like this toofoo: "foo"Config dump/load
Keep in mind these are the simplest examples
Base code for all examples:
importcom.mrivanplays.annotationconfig.utils.TypeToken;
Filefile = // ...SerializerRegistryserializerRegistry = SerializerRegistry.INSTANCE;
serializerRegistry.registerSerializer(
ExampleAnnotatedConfig.SomethingToSerialize.class,
newExampleAnnotatedConfig.SomethingToSerializeSerializer());
serializerRegistry.registerSerializer(
newTypeToken<SectionObjectList<SectionObject>>() {}.getType(),
newSectionObjectListSerializer<SectionObject>());
ExampleAnnotatedConfigannotatedConfig = newExampleAnnotatedConfig();YAML example:
YamlConfig.getConfigResolver().loadOrDump(anotatedConfig, file, /* loader settings */);.conf/.properties example:
PropertyConfig.getConfigResolver().loadOrDump(annotatedConfig, file, /* loader settings */);TOML example:
TomlConfig.getConfigResolver().loadOrDump(annotatedConfig, file, /* loader settings */);Custom config type example:
// all values specified in the builder should be for the specific config typeConfigResolverconfigResolver = ConfigResolver.newBuilder()
/* other options inside the builder */
.withCommentPrefix("# ") // comment prefix for the config type
.withValueWriter(() -> /* insert value writer here */)
.withValueReader(/* insert value reader here */)
.shouldReverseFields(true/* should we reverse fields */)
.build();
configResolver.loadOrDump(annotatedConfig, file, /* loader settings */);Maven:
<build>
<plugins>
<plugin>
<version>3.7.0</version>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<relocations>
<!-- Relocating is only necessary if you're shading for other library addition -->
<relocation>
<pattern>com.mrivanplays.annotationconfig</pattern>
<shadedPattern>[YOUR PLUGIN PACKAGE].annotationconfig
</shadedPattern> <!-- Replace this -->
</relocation>
</relocations>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>ivan</id>
<url>https://repo.mrivanplays.com/repository/ivan/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.mrivanplays</groupId>
<!-- Types: toml, yaml --><!-- If you want .conf/.properties, or custom implementation configuration, you can set the type to core -->
<artifactId>annotationconfig-(type)</artifactId> <!-- Replace type -->
<version>VERSION</version> <!-- Replace with latest version -->
<scope>compile</scope>
</dependency>
</dependencies>