JASKL is a simple config library supporting multiple different formats.
JASKL is based on Configs and ConfigEntrys.
Create a new Config by instantiating one of the following classes:
YamlConfig, JsonConfig, TomlConfig, PropertiesConfig, HoconConfig or MongodbConfig.
After that, new ConfigEntrys can be created and added to the config. The value of a ConfigEntry is retrieved via
ConfigEntry#getValue and can never be null.
File file = new File("path/to/config.yaml");
// Create a config based on a file
Config config = YamlConfig.of(file, "Config for example values");
// Create entries and add them to the config
StringConfigEntry stringValue = StringConfigEntry.of(config, "example.path.string", "An example String!", "This is the default value!");
EnumConfigEntry<ExampleEnum> enumValue = EnumConfigEntry.of(config, "example.path.enum", "An example String!", ExampleEnum.EXAMPLE);
config.load(); // Load the config from file (doesn't create missing entries)
config.write(); // Save the config to write missing entries
System.out.println(stringValue.getValue()); // "This is the default value!"
stringValue.setValue("This is another example!"); // Change values
System.out.println(stringValue.getValue()); // "This is another example!"
config.write(); // Save the config| Type | Description | Base |
|---|---|---|
| YAML | A human-readable data-serialization language. | SnakeYAML |
| Hocon | A more user friendly superset of JSON supporting many different data types. | Lightbend Config |
| JSON | JavaScript Object Notation | Jackson |
| TOML | A very easy to read config supporting sub categories and many different data types. | Jackson |
| Properties | A very simple implementation for minimalistic config systems. | java.util.Properties |
| MongoDB | A NoSQL database based implementation for complex configs with remote saves. | mongodb-driver |
| Type | YAML | Hocon | JSON | TOML | Properties | MongoDB |
|---|---|---|---|---|---|---|
| String | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Boolean | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Integer | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Long | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Float | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Double | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| BigInteger / BigDecimal | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| UUID | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Instant / OffsetDateTime / ZonedDateTime | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| LocalDate / LocalTime / LocalDateTime | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Duration / Period | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Enum | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| List / Set | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| Map | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| Custom Objects | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| Comments | ✅ | ✅² | ❌ | ❌ | ✅¹ | ❌ |
¹ Properties only allows for a single comment at the beginning of the file
² Comments on custom objects are ignored
JASKL can automatically validate config entries (e.g. ensure that a number is always greater than zero) and throws a
ValidationException if an invalid value is detected.
IntegerConfigEntry positiveIntegerConfigEntry = IntegerConfigEntry.of(config, "example.integer", "Example Integer", 1, Validator.INTEGER_POSITIVE);public class MyObject {
@Entry
@Validate.StringNotEmpty
public String myString = "Default String"; // Annotated fields must be public and default values should not be null
@Entry("some.other.path")
public int myInt = 5;
public MyObject() {} // An empty constructor is required
}You can than register a ConfigEntry:
ConfigEntry<MyObject> entry = CustomConfigEntry.of(config, "example.myObject", "Some description", new MyObject());If you don't want to use annotations, an ObjectMapper can be used instead.
ObjectMapper<MyObject> mapper = new ObjectMapper<MyObject>() {
@Override
public @NotNull MyObject createInstance(@Unmodifiable @NotNull Map<@NotNull String, @NotNull Object> values) throws InvalidTypeException, ValidationException {
return new MyObject((String) values.get("myString"), (int) values.get("myInt"));
}
@Override
public @Unmodifiable @NotNull Map<@NotNull String, @NotNull Object> readValues(@NotNull MyObject instance) throws InvalidTypeException {
Map<String, Object> values = new HashMap<>();
values.put("myString", instance.getMyString());
values.put("myInt", instance.getMyInt());
return Collections.unmodifiableMap(values);
}
@Override
public @NotNull Class<MyObject> getObjectClass() {
return MyObject.class;
}
@Override
public @NotNull Property<?> @NotNull [] getProperties() {
return new Property[] {
Property.of("myString", Type.validated(Type.STRING, Validator.STRING_NOT_EMPTY)),
Property.of("myInt", Type.INTEGER)
};
}
};
// register the entry
ConfigEntry<MyObject> entry = CustomConfigEntry.of(config, "example.mapper.myObject", "Some description", new MyObject(), mapper);You can also use annotation-based configs:
public class ExampleAnnotationConfig {
@Entry
@Validate.StringNotEmpty
public String myString = "Default String"; // Annotated fields must be public and default values should not be null
@Entry("some.other.path")
@Description("Enter description here") // May be ignored if the implementation does not support comments
public int myInt = 5;
public ExampleAnnotationConfig() {} // An empty constructor is required
}AnnotationManager annotationManager = AnnotationManager.create(); // Create an AnnotationManager. This instance can be reused.
Config yamlConfig = YamlConfig.of(file); // Create a config
// Register our annotated class
ExampleAnnotationConfig config = annotationManager.registerEntries(yamlConfig, ExampleAnnotationConfig.class);
yamlConfig.load(); // Load the config from storage
System.out.println(config.myString); // Print some value we just loaded
config.myString = "Hello World"; // Change the value
// Write the config to storage
// This also checks/validates changed values
yamlConfig.write();To build the project, open the terminal and type ./gradlew build. All jars will be located at /<implementation>/build/libs/<implementation>-<version>.jar.
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.almighty-satan.jaskl:jaskl-<implementation>:<version>")
}