001/* 002 * Configurate 003 * Copyright (C) zml and Configurate contributors 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.spongepowered.configurate.examples; 018 019import static java.util.Objects.requireNonNull; 020 021import org.checkerframework.checker.nullness.qual.MonotonicNonNull; 022import org.checkerframework.checker.nullness.qual.Nullable; 023import org.spongepowered.configurate.CommentedConfigurationNode; 024import org.spongepowered.configurate.ConfigurateException; 025import org.spongepowered.configurate.hocon.HoconConfigurationLoader; 026import org.spongepowered.configurate.objectmapping.ConfigSerializable; 027import org.spongepowered.configurate.objectmapping.meta.Comment; 028 029import java.nio.file.Path; 030import java.nio.file.Paths; 031import java.util.ArrayList; 032import java.util.List; 033import java.util.UUID; 034import java.util.regex.Pattern; 035 036/** 037 * Example of how to use the ObjectMapper for a simple configuration that is 038 * read to and written from. 039 * 040 * <p>Error handling is not considered in this example, but for a fully fledged 041 * application it would be essential.</p> 042 */ 043public final class ObjectMapperExample { 044 045 private ObjectMapperExample() {} 046 047 public static void main(final String[] args) throws ConfigurateException { 048 final Path file = Paths.get(args[0]); 049 final HoconConfigurationLoader loader = HoconConfigurationLoader.builder() 050 .defaultOptions(opts -> opts.shouldCopyDefaults(true)) 051 .path(file) // or setUrl(), or setFile(), or setSource/Sink 052 .build(); 053 054 final CommentedConfigurationNode node = loader.load(); // Load from file 055 final MyConfiguration config = node.get(MyConfiguration.class); // Populate object 056 057 // Do whatever actions with the configuration, then... 058 config.itemName("Steve"); 059 060 node.set(MyConfiguration.class, config); // Update the backing node 061 loader.save(node); // Write to the original file 062 } 063 064 @ConfigSerializable 065 static class MyConfiguration { 066 067 // Fields must be non-final to be modified 068 069 private @Nullable String itemName; 070 071 @Comment("Here is a comment to describe the purpose of this field") 072 private Pattern filter = Pattern.compile("cars?"); // Set defaults by initializing the field 073 074 // As long as custom classes are annotated with @ConfigSerializable, they can be nested as ordinary fields. 075 private List<Section> sections = new ArrayList<>(); 076 077 // This won't be written to the file because it's marked as `transient` 078 private transient @MonotonicNonNull String decoratedName; 079 080 public @Nullable String itemName() { 081 return this.itemName; 082 } 083 084 public void itemName(final String itemName) { 085 this.itemName = requireNonNull(itemName, "itemName"); 086 } 087 088 public Pattern filter() { 089 return this.filter; 090 } 091 092 public List<Section> sections() { 093 return this.sections; 094 } 095 096 public String decoratedItemName() { 097 if (this.decoratedName == null) { 098 this.decoratedName = "[" + this.itemName + "]"; 099 } 100 return this.decoratedName; 101 } 102 103 } 104 105 @ConfigSerializable 106 static class Section { 107 108 private String name; 109 private UUID id; 110 111 // the ObjectMapper resolves settings based on fields -- these methods are provided as a convenience 112 public String name() { 113 return this.name; 114 } 115 116 public UUID id() { 117 return this.id; 118 } 119 120 } 121 122}