-
-
Notifications
You must be signed in to change notification settings - Fork 68
Object Mapper
zml edited this page Apr 21, 2020
·
15 revisions
Can only create objects that have no-arg constructor, otherwise restricted to populating already existing objects
- String, float, double, int, long, byte, char
- Maps
- Lists
- URIs
- URLs
- Objects annotated with
@ConfigSerializable
(which are loaded from the object mapper) - Enum values
Other supported types may be added by registering custom TypeSerializers, explained below.
TypeSerializers.getDefaultSerializers().registerType(TypeToken, TypeSerializer)
with custom implementations of TypeSerializer. Newly registered serializers are added with highest priority.
collectFields(Map<String, FieldData> fields, Class<? super T> clazz)
: To control how fields that are settings are discovered from a class
constructObject()
: To control how the object is created
Here's a example of a standalone ObjectMapper setup. This uses a few value types, some nodes, and shows that type parameters are interpreted where specified.
class ObjectMapperDemo {
public static void main(String[] args) throws IOException, ObjectMappingException {
final Path file = Path.of(args[0]);
final GsonConfigurationLoader loader = GsonConfigurationLoader.builder()
.setPath(file) // or setUrl(), or setFile(), or setSource/Sink
.build();
final ConfigurationNode node = loader.load(); // Load from file
final MyConfiguration config = MyConfiguration.loadFrom(node); // Populate object
// Do whatever actions with the configuration, then...
config.setItemName("Steve");
config.saveTo(node); // Update the backing node
loader.save(node); // Write to the original file
}
}
@ConfigSerializable
class MyConfiguration {
private static final ObjectMapper<MyConfiguration> MAPPER;
static {
try {
MAPPER = ObjectMapper.forClass(MyConfiguration.class); // We hold on to the instance of our ObjectMapper
} catch (ObjectMappingException e) {
throw new ExceptionInInitializerError(e);
}
}
public static MyConfiguration loadFrom(ConfigurationNode node) throws ObjectMappingException {
return MAPPER.bindToNew().populate(node);
}
@Setting(value = "item-name") // The key for a setting is normally provided by the field name, but can be overridden
private @Nullable String itemName;
@Setting(comment = "Here is a comment to describe the purpose of this field")
private Pattern filter = Pattern.compile("cars?"); // Set defaults by initializing the field
// As long as custom classes are annotated with @ConfigSerializable, they can be nested as ordinary fields.
private List<Section> sections = new ArrayList<>();
public @Nullable String getItemName() {
return this.itemName;
}
public void setItemName(String itemName) {
this.itemName = requireNonNull(itemName, "itemName");
}
public Pattern getFilter() {
return this.filter;
}
public List<Section> getSections() {
return this.sections;
}
public void saveTo(ConfigurationNode node) {
MAPPER.bind(this).serialize(node);
}
}
@ConfigSerializable
class Section {
@Setting
private String name;
@Setting
private UUID id;
// the ObjectMapper resolves settings based on fields -- these methods are provided as a convenience
public String getName() {
return name;
}
public UUID getId() {
return id;
}
}