|
|
|
@ -1,23 +1,28 @@
|
|
|
|
|
# ConfigLib
|
|
|
|
|
|
|
|
|
|
**A Minecraft library for mapping objects to YAML configuration files.**
|
|
|
|
|
**A Minecraft library for saving, loading, updating, and commenting YAML configuration files.**
|
|
|
|
|
|
|
|
|
|
This library facilitates creating, saving, loading, updating, and documenting YAML configuration
|
|
|
|
|
This library facilitates creating, saving, loading, updating, and commenting YAML configuration
|
|
|
|
|
files. It does so by automatically mapping instances of configuration classes to serializable maps
|
|
|
|
|
which are then transformed into YAML and saved to some specified file.
|
|
|
|
|
which are first transformed into YAML and then saved to some specified file.
|
|
|
|
|
|
|
|
|
|
For a step-by-step tutorial that shows most features of this library in action check out
|
|
|
|
|
the [Tutorial](https://github.com/Exlll/ConfigLib/wiki/Tutorial) page on the wiki!
|
|
|
|
|
|
|
|
|
|
## Features
|
|
|
|
|
|
|
|
|
|
* Automatic creation, saving, loading, and updating of configuration files
|
|
|
|
|
* Support for comments through annotations
|
|
|
|
|
* Support for all primitive types, their wrapper types, and Strings
|
|
|
|
|
* Support for `BigInteger`, `BigDecimal`, `LocalDate`, `LocalTime`, and `LocalDateTime`
|
|
|
|
|
* Support for (nested) lists, sets, arrays, and maps
|
|
|
|
|
* Support for enums and POJOs (+ inheritance!)
|
|
|
|
|
* Support for Bukkit's `ConfigurationSerializable` types (e.g. `ItemStack`)
|
|
|
|
|
* Option to exclude fields from being converted
|
|
|
|
|
* Option to add explanatory comments by annotating fields
|
|
|
|
|
* Option to format field names before conversion
|
|
|
|
|
* Option to customize null handling
|
|
|
|
|
* Option to provide custom serializers
|
|
|
|
|
* Option to customize serialization by providing your own serializers
|
|
|
|
|
* Option to add headers and footers to configuration files
|
|
|
|
|
* ...and a few more!
|
|
|
|
|
|
|
|
|
|
## Usage example
|
|
|
|
@ -26,6 +31,12 @@ This section contains a short usage example to get you started. The whole range
|
|
|
|
|
discussed in the following sections. Information on how to import this library is located at the end
|
|
|
|
|
of this documentation.
|
|
|
|
|
|
|
|
|
|
For a step-by-step tutorial with a more advanced example check out
|
|
|
|
|
the [Tutorial](https://github.com/Exlll/ConfigLib/wiki/Tutorial) page on the wiki.
|
|
|
|
|
|
|
|
|
|
If you want support Bukkit classes like `ItemStack`, check out
|
|
|
|
|
the [Configuration properties](#configuration-properties) section.
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
public final class Example {
|
|
|
|
|
// To create a configuration annotate the class with @Configuration and make sure that
|
|
|
|
@ -69,21 +80,20 @@ public final class Example {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
final var props = YamlConfigurationProperties.newBuilder().build();
|
|
|
|
|
final var store = new YamlConfigurationStore<>(UserConfiguration.class, props);
|
|
|
|
|
final var configFile = Paths.get("/tmp/config.yml");
|
|
|
|
|
var configFile = Paths.get("/tmp/config.yml");
|
|
|
|
|
var config = new UserConfiguration();
|
|
|
|
|
|
|
|
|
|
// Save a new instance to the configuration file
|
|
|
|
|
store.save(new UserConfiguration(), configFile);
|
|
|
|
|
Configurations.saveYamlConfiguration(configFile, UserConfiguration.class, config);
|
|
|
|
|
|
|
|
|
|
// Load a new instance from the configuration file
|
|
|
|
|
UserConfiguration configuration = store.load(configFile);
|
|
|
|
|
System.out.println(configuration.admin.username);
|
|
|
|
|
System.out.println(configuration.blockedUsers);
|
|
|
|
|
config = Configurations.loadYamlConfiguration(configFile, UserConfiguration.class);
|
|
|
|
|
System.out.println(config.admin.username);
|
|
|
|
|
System.out.println(config.blockedUsers);
|
|
|
|
|
|
|
|
|
|
// Modify and save the configuration file
|
|
|
|
|
configuration.blockedUsers.add(new User("user3", "pass3"));
|
|
|
|
|
store.save(configuration, configFile);
|
|
|
|
|
config.blockedUsers.add(new User("user3", "pass3"));
|
|
|
|
|
Configurations.saveYamlConfiguration(configFile, UserConfiguration.class, config);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
@ -137,23 +147,23 @@ them null. Handling of null values is discussed in one of the sections further b
|
|
|
|
|
|
|
|
|
|
A configuration type may only contain fields of the following types:
|
|
|
|
|
|
|
|
|
|
| Type class | Types |
|
|
|
|
|
|------------------------|--------------------------------------------------------------------|
|
|
|
|
|
| Boolean types | `boolean`, and `Boolean` |
|
|
|
|
|
| Integer types | `byte`, `short`, `int`, `long`, and their respective wrapper types |
|
|
|
|
|
| Floating point types | `float`, `double`, and their respective wrapper types |
|
|
|
|
|
| Characters and strings | `char`, `Character`, `String` |
|
|
|
|
|
| Big numeric types | `BigInteger`, `BigDecimal` |
|
|
|
|
|
| Time related types | `LocalTime`, `LocalDate`, `LocalDateTime` |
|
|
|
|
|
| Enums | Any Java enum |
|
|
|
|
|
| Configurations | Any configuration type |
|
|
|
|
|
| Collections | (Nested) Lists, sets, maps*, or arrays of previously listed types |
|
|
|
|
|
| Type class | Types |
|
|
|
|
|
|-----------------------------|--------------------------------------------------------------------|
|
|
|
|
|
| Boolean types | `boolean`, and `Boolean` |
|
|
|
|
|
| Integer types | `byte`, `short`, `int`, `long`, and their respective wrapper types |
|
|
|
|
|
| Floating point types | `float`, `double`, and their respective wrapper types |
|
|
|
|
|
| Characters and strings | `char`, `Character`, `String` |
|
|
|
|
|
| Big numeric types | `BigInteger`, `BigDecimal` |
|
|
|
|
|
| Time related types | `LocalTime`, `LocalDate`, `LocalDateTime` |
|
|
|
|
|
| Enums | Any Java enum |
|
|
|
|
|
| Configurations | Any configuration type |
|
|
|
|
|
| `ConfigurationSerializable` | All Bukkit classes that implement this interface, like `ItemStack` |
|
|
|
|
|
| Collections | (Nested) Lists, sets, maps*, or arrays of previously listed types |
|
|
|
|
|
|
|
|
|
|
(*) Map keys cannot be in the `Configurations` or `Collections` type class.
|
|
|
|
|
(*) Map keys can only be of simple or enum type, i.e. they cannot be in the `Collections`,
|
|
|
|
|
`Configurations`, or `ConfigurationSerializable` type class.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<details>
|
|
|
|
|
<summary>Examples of supported types</summary>
|
|
|
|
|
#### Examples of supported types
|
|
|
|
|
|
|
|
|
|
The following class contains examples of types that this library supports:
|
|
|
|
|
|
|
|
|
@ -161,23 +171,29 @@ The following class contains examples of types that this library supports:
|
|
|
|
|
public final class SupportedTypes {
|
|
|
|
|
boolean supported;
|
|
|
|
|
Character supported;
|
|
|
|
|
ExampleEnum supported; // where 'ExampleEnum' is some Java enum type
|
|
|
|
|
ExampleConf supported; // where 'ExampleConf' is another configuration type
|
|
|
|
|
java.awt.Point supported; // only if a custom serializer is registered
|
|
|
|
|
String supported;
|
|
|
|
|
ExampleEnum supported; // where 'ExampleEnum' is some Java enum type
|
|
|
|
|
ExampleConf supported; // where 'ExampleConf' is another configuration type
|
|
|
|
|
|
|
|
|
|
/* collection types */
|
|
|
|
|
List<BigInteger> supported;
|
|
|
|
|
Set<Double> supported;
|
|
|
|
|
LocalDate[] supported;
|
|
|
|
|
Map<ExampleEnum, ExampleConf> supported;
|
|
|
|
|
|
|
|
|
|
/* nested collection types */
|
|
|
|
|
List<Map<ExampleEnum, LocalDate>> supported;
|
|
|
|
|
int[][] supported;
|
|
|
|
|
Map<Integer, List<Map<Short, Set<ExampleConf>>>> supported;
|
|
|
|
|
|
|
|
|
|
// supported if a custom serializer is registered
|
|
|
|
|
java.awt.Point supported;
|
|
|
|
|
|
|
|
|
|
// supported when a special properties object is used (explained further below)
|
|
|
|
|
org.bukkit.inventory.ItemStack supported;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
|
|
|
|
|
<details>
|
|
|
|
|
<summary>Examples of unsupported types</summary>
|
|
|
|
|
|
|
|
|
@ -298,78 +314,31 @@ Config c2 = Configurations.loadYamlConfiguration(
|
|
|
|
|
);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### Configuration properties
|
|
|
|
|
### Configuration properties
|
|
|
|
|
|
|
|
|
|
Instances of the `ConfigurationProperties` class allow customization of how configurations are
|
|
|
|
|
stored and loaded. To create such an instance, instantiate a new builder using
|
|
|
|
|
the `YamlConfigurationProperties.newBuilder()` method, configure it, and finally call its `build()`
|
|
|
|
|
method. Check out the several methods of the builder to see which configuration options are
|
|
|
|
|
available.
|
|
|
|
|
method. Alternatively, you can use the `toBuilder()` method of an
|
|
|
|
|
existing `YamlConfigurationProperties` to create a new builder that is initialized with values
|
|
|
|
|
takes from the properties object.
|
|
|
|
|
|
|
|
|
|
#### Ignoring and filtering fields
|
|
|
|
|
Check out the methods of the builder class to see which configuration options are available.
|
|
|
|
|
|
|
|
|
|
Fields that are `final`, `static`, `transient` or annotated with `@Ignore` are neither serialized
|
|
|
|
|
nor updated during deserialization. You can filter out additional fields by providing an instance of
|
|
|
|
|
`FieldFilter` to the configuration properties.
|
|
|
|
|
|
|
|
|
|
#### Handling of `null` values
|
|
|
|
|
#### Support for Bukkit classes like `ItemStack`
|
|
|
|
|
|
|
|
|
|
Configuration properties let you configure how `null` values are handled when serializing and
|
|
|
|
|
deserializing a configuration:
|
|
|
|
|
|
|
|
|
|
* By setting `outputNulls` to false, fields and collection elements that are null are not output.
|
|
|
|
|
Any comments that belong to such fields are also not written.
|
|
|
|
|
* By setting `inputNulls` to false, fields and collection elements that are null are not input. That
|
|
|
|
|
means that fields will keep their default values.
|
|
|
|
|
|
|
|
|
|
<details>
|
|
|
|
|
<summary>Example <code>null</code> handling configuration</summary>
|
|
|
|
|
|
|
|
|
|
The following code forbids null values to be output but allows null values to be input. By default,
|
|
|
|
|
both are forbidden which makes the call to `outputNulls` in this case redundant.
|
|
|
|
|
There is a special `YamlConfigurationProperties` object with name `BUKKIT_DEFAULT_PROPERTIES`
|
|
|
|
|
that adds support for Bukkit's `ConfigurationSerializable` types. If you want to use any of these
|
|
|
|
|
types in your configuration, you have to use that object as a starting point:
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
YamlConfigurationProperties.newBuilder()
|
|
|
|
|
.outputNulls(false)
|
|
|
|
|
.inputNulls(true)
|
|
|
|
|
.build();
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
|
|
|
|
|
#### Field formatting
|
|
|
|
|
|
|
|
|
|
You can define how fields are formatted by configuring the configuration properties with a custom
|
|
|
|
|
formatter. Field formatters are implementations of the `FieldFormatter` interface. You can implement
|
|
|
|
|
this interface yourself or use one of the several formatters this library provides. These
|
|
|
|
|
pre-defined formatters can be found in the `FieldFormatters` class.
|
|
|
|
|
|
|
|
|
|
<details>
|
|
|
|
|
<summary>Example <code>FieldFormatter</code> configuration</summary>
|
|
|
|
|
|
|
|
|
|
The following code formats fields using the `IDENTITY` formatter (which is the default).
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
YamlConfigurationProperties.newBuilder()
|
|
|
|
|
.setFieldFormatter(FieldFormatters.IDENTITY)
|
|
|
|
|
.build();
|
|
|
|
|
YamlConfigurationProperties properties = ConfigLib.BUKKIT_DEFAULT_PROPERTIES.toBuilder()
|
|
|
|
|
// ...further configure the builder...
|
|
|
|
|
.build();
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
|
|
|
|
|
### Subclassing
|
|
|
|
|
|
|
|
|
|
Subclassing of configurations types is supported. Subclasses of configuration types don't need to be
|
|
|
|
|
annotated with `@Configuration`. When a configuration is written, the fields of parent classes
|
|
|
|
|
are written before the fields of the child in a top to bottom manner. Parent configurations can
|
|
|
|
|
be `abstract`.
|
|
|
|
|
|
|
|
|
|
#### Shadowing of fields
|
|
|
|
|
|
|
|
|
|
Shadowing of fields refers to the situation where a subclass of configuration has a field that has
|
|
|
|
|
the same name as a field in one of its super classes. Shadowing of fields is currently not
|
|
|
|
|
supported. (This restriction might easily be lifted. If you need this feature, please open an issue
|
|
|
|
|
and describe how to handle name clashes.)
|
|
|
|
|
To get access to this object, you have to import `configlib-paper` instead of `configlib-core` as
|
|
|
|
|
described in the [Import](#import) section.
|
|
|
|
|
|
|
|
|
|
### Comments
|
|
|
|
|
|
|
|
|
@ -377,9 +346,6 @@ The fields of a configuration can be annotated with the `@Comment` annotation. T
|
|
|
|
|
an array of strings. Each of these strings is written onto a new line as a comment. Empty strings
|
|
|
|
|
are written as newlines.
|
|
|
|
|
|
|
|
|
|
<details>
|
|
|
|
|
<summary>Example of <code>@Comment</code> usage </summary>
|
|
|
|
|
|
|
|
|
|
Serializing the following configuration as YAML ...
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
@ -400,44 +366,64 @@ public final class ExampleConfiguration {
|
|
|
|
|
commentedField: commented field
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
|
|
|
|
|
If a configuration type _C_ that defines comments is used (as a field) within another configuration
|
|
|
|
|
type, the comments of _C_ are written with the proper indentation. However, if instances of _C_ are
|
|
|
|
|
stored inside a collection, their comments are not printed when the collection is written.
|
|
|
|
|
|
|
|
|
|
### Recursive type definitions
|
|
|
|
|
### Subclassing
|
|
|
|
|
|
|
|
|
|
Recursive type definitions are currently not allowed but might be supported in a future version if
|
|
|
|
|
this feature is requested.
|
|
|
|
|
Subclassing of configurations types is supported. Subclasses of configuration types don't need to be
|
|
|
|
|
annotated with `@Configuration`. When a configuration is written, the fields of parent classes
|
|
|
|
|
are written before the fields of the child in a top to bottom manner. Parent configurations can
|
|
|
|
|
be `abstract`.
|
|
|
|
|
|
|
|
|
|
<details>
|
|
|
|
|
<summary>Examples of recursive type definitions</summary>
|
|
|
|
|
#### Shadowing of fields
|
|
|
|
|
|
|
|
|
|
Neither direct nor indirect recursive type definitions are supported.
|
|
|
|
|
Shadowing of fields refers to the situation where a subclass of configuration has a field that has
|
|
|
|
|
the same name as a field in one of its super classes. Shadowing of fields is currently not
|
|
|
|
|
supported. (This restriction might easily be lifted. If you need this feature, please open an issue
|
|
|
|
|
and describe how to handle name clashes.)
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
public final class RecursiveTypDefinitions {
|
|
|
|
|
// Direct recursive definition
|
|
|
|
|
@Configuration
|
|
|
|
|
static final class R {
|
|
|
|
|
R r;
|
|
|
|
|
}
|
|
|
|
|
### Ignoring and filtering fields
|
|
|
|
|
|
|
|
|
|
// Indirect recursive definition
|
|
|
|
|
@Configuration
|
|
|
|
|
static final class R1 {
|
|
|
|
|
R2 r2;
|
|
|
|
|
}
|
|
|
|
|
Fields that are `final`, `static`, `transient` or annotated with `@Ignore` are neither serialized
|
|
|
|
|
nor updated during deserialization. You can filter out additional fields by providing an instance of
|
|
|
|
|
`FieldFilter` to the configuration properties.
|
|
|
|
|
|
|
|
|
|
@Configuration
|
|
|
|
|
static final class R2 {
|
|
|
|
|
R1 r1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
### Handling of `null` values
|
|
|
|
|
|
|
|
|
|
Configuration properties let you configure how `null` values are handled when serializing and
|
|
|
|
|
deserializing a configuration:
|
|
|
|
|
|
|
|
|
|
* By setting `outputNulls` to false, fields and collection elements that are null are not output.
|
|
|
|
|
Any comments that belong to such fields are also not written.
|
|
|
|
|
* By setting `inputNulls` to false, fields and collection elements that are null are not input. That
|
|
|
|
|
means that fields will keep their default values.
|
|
|
|
|
|
|
|
|
|
The following code forbids null values to be output but allows null values to be input. By default,
|
|
|
|
|
both are forbidden which makes the call to `outputNulls` in this case redundant.
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
YamlConfigurationProperties.newBuilder()
|
|
|
|
|
.outputNulls(false)
|
|
|
|
|
.inputNulls(true)
|
|
|
|
|
.build();
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
### Field formatting
|
|
|
|
|
|
|
|
|
|
You can define how fields are formatted by configuring the configuration properties with a custom
|
|
|
|
|
formatter. Field formatters are implementations of the `FieldFormatter` interface. You can implement
|
|
|
|
|
this interface yourself or use one of the several formatters this library provides. These
|
|
|
|
|
pre-defined formatters can be found in the `FieldFormatters` class.
|
|
|
|
|
|
|
|
|
|
The following code formats fields using the `IDENTITY` formatter (which is the default).
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
YamlConfigurationProperties.newBuilder()
|
|
|
|
|
.setFieldFormatter(FieldFormatters.IDENTITY)
|
|
|
|
|
.build();
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Type conversion and custom serializers
|
|
|
|
|
|
|
|
|
@ -445,20 +431,21 @@ Before instances of the types listed in the [supported types](#supported-types)
|
|
|
|
|
stored, they need to be converted into serializable types (i.e. into types the underlying YAML
|
|
|
|
|
library knows how to handle). The conversion happens according to the following table:
|
|
|
|
|
|
|
|
|
|
| Source type | Target type |
|
|
|
|
|
|------------------------|------------------|
|
|
|
|
|
| Boolean types | `Boolean` |
|
|
|
|
|
| Integer types | `Long` |
|
|
|
|
|
| Floating point types | `Double` |
|
|
|
|
|
| Characters and strings | `String` |
|
|
|
|
|
| Big numeric types | `String` |
|
|
|
|
|
| Time related types | `String` |
|
|
|
|
|
| Enums | `String` |
|
|
|
|
|
| Configurations | `Map<String, ?>` |
|
|
|
|
|
| `Set<S>` | `List<T>`* |
|
|
|
|
|
| `List<S>` | `List<T>` |
|
|
|
|
|
| `S[]` | `List<T>` |
|
|
|
|
|
| `Map<S1, S2>` | `Map<T1, T2>` |
|
|
|
|
|
| Source type | Target type |
|
|
|
|
|
|-----------------------------|------------------|
|
|
|
|
|
| Boolean types | `Boolean` |
|
|
|
|
|
| Integer types | `Long` |
|
|
|
|
|
| Floating point types | `Double` |
|
|
|
|
|
| Characters and strings | `String` |
|
|
|
|
|
| Big numeric types | `String` |
|
|
|
|
|
| Time related types | `String` |
|
|
|
|
|
| Enums | `String` |
|
|
|
|
|
| Configurations | `Map<String, ?>` |
|
|
|
|
|
| `Set<S>` | `List<T>`* |
|
|
|
|
|
| `List<S>` | `List<T>` |
|
|
|
|
|
| `S[]` | `List<T>` |
|
|
|
|
|
| `Map<S1, S2>` | `Map<T1, T2>` |
|
|
|
|
|
| `ConfigurationSerializable` | `String` |
|
|
|
|
|
|
|
|
|
|
(*) By default, sets are serialized as lists. This can be changed through the configuration
|
|
|
|
|
properties. This also means that `Set`s are valid target types.
|
|
|
|
@ -471,6 +458,9 @@ the `de.exlll.configlib.Serializer` interface and are selected based on `S`. Put
|
|
|
|
|
serializers are always selected based on the compile-time type of `F` and never on the runtime type
|
|
|
|
|
of its value.
|
|
|
|
|
|
|
|
|
|
<details>
|
|
|
|
|
<summary>Why should I care about this?</summary>
|
|
|
|
|
|
|
|
|
|
This distinction makes a difference (and might lead to confusion) when you have fields whose type is
|
|
|
|
|
a configuration type or a collection of some configuration type, and you extend that configuration
|
|
|
|
|
type. Concretely, assume you have and written two configuration types `A` and `B`
|
|
|
|
@ -479,6 +469,8 @@ a `A` will be stored when you save your main configuration. That is because the
|
|
|
|
|
field `a` was selected based on the compile-time type of `a` which is `A` and not `B`. The same
|
|
|
|
|
happens if you have a `List<A>` and put instances of `B` (or some other subclass of `A`) in it.
|
|
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
|
|
|
|
|
#### Custom serializers
|
|
|
|
|
|
|
|
|
|
If you want to add support for a type whose class is not annotated with `@Configuration`, you can
|
|
|
|
@ -487,9 +479,6 @@ interface. When implementing that interface you have to make sure that you conve
|
|
|
|
|
into one of the valid target types listed in the table above. The serializer then has to be
|
|
|
|
|
registered through a `ConfigurationProperties` object.
|
|
|
|
|
|
|
|
|
|
<details>
|
|
|
|
|
<summary>Example <code>Serializer</code> implementation</summary>
|
|
|
|
|
|
|
|
|
|
The following `Serializer` serializes instances of `java.awt.Point` into strings.
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
@ -509,8 +498,6 @@ public final class PointSerializer implements Serializer<Point, String> {
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
|
|
|
|
|
Custom serializers takes precedence over the serializers provided by this library.
|
|
|
|
|
|
|
|
|
|
### Changing the type of fields
|
|
|
|
@ -519,6 +506,39 @@ Changing the type of fields is not supported. If you change the type of one of y
|
|
|
|
|
configuration file still contains a value of the old type, a type mismatch will occur when reading
|
|
|
|
|
that file. Instead, remove the old field and add a new one with a different name.
|
|
|
|
|
|
|
|
|
|
### Recursive type definitions
|
|
|
|
|
|
|
|
|
|
Recursive type definitions are currently not allowed but might be supported in a future version if
|
|
|
|
|
this feature is requested.
|
|
|
|
|
|
|
|
|
|
<details>
|
|
|
|
|
<summary>Examples of recursive type definitions</summary>
|
|
|
|
|
|
|
|
|
|
Neither direct nor indirect recursive type definitions are supported.
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
public final class RecursiveTypDefinitions {
|
|
|
|
|
// Direct recursive definition
|
|
|
|
|
@Configuration
|
|
|
|
|
static final class R {
|
|
|
|
|
R r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Indirect recursive definition
|
|
|
|
|
@Configuration
|
|
|
|
|
static final class R1 {
|
|
|
|
|
R2 r2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Configuration
|
|
|
|
|
static final class R2 {
|
|
|
|
|
R1 r1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
|
|
|
|
|
## Import
|
|
|
|
|
|
|
|
|
|
**INFO:** I'm currently looking for an easier way for you to import this library that does not
|
|
|
|
@ -543,6 +563,10 @@ dependencies array (for Velocity) of your own plugin.
|
|
|
|
|
Alternatively, if you don't want to use an extra plugin, you can shade the `-core` version and the
|
|
|
|
|
YAML parser yourself.
|
|
|
|
|
|
|
|
|
|
**NOTE:** If you want serialization support for Bukkit classes like `ItemStack`,
|
|
|
|
|
replace `configlib-core` with `configlib-paper`
|
|
|
|
|
(see [here](#support-for-bukkit-classes-like-itemstack)).
|
|
|
|
|
|
|
|
|
|
#### Maven
|
|
|
|
|
|
|
|
|
|
```xml
|
|
|
|
|