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 ninja.leaping.configurate.examples; 018 019import com.google.common.reflect.TypeToken; 020import ninja.leaping.configurate.commented.CommentedConfigurationNode; 021import ninja.leaping.configurate.hocon.HoconConfigurationLoader; 022import ninja.leaping.configurate.objectmapping.ObjectMappingException; 023import ninja.leaping.configurate.objectmapping.Setting; 024import ninja.leaping.configurate.reference.ConfigurationReference; 025import ninja.leaping.configurate.reference.ValueReference; 026import ninja.leaping.configurate.reference.WatchServiceListener; 027import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable; 028import ninja.leaping.configurate.transformation.NodePath; 029 030import java.io.IOException; 031import java.nio.file.Path; 032import java.nio.file.Paths; 033import java.util.List; 034import java.util.Objects; 035import java.util.UUID; 036 037public class ValueReferences { 038 private final WatchServiceListener listener; 039 private final ConfigurationReference<CommentedConfigurationNode> base; 040 private final ValueReference<String> name; 041 private final ValueReference<Integer> cookieCount; 042 private final ValueReference<List<TestObject>> complex; 043 044 @ConfigSerializable 045 static class TestObject { 046 @Setting 047 String name; 048 @Setting 049 UUID id = UUID.randomUUID(); 050 051 @Override 052 public boolean equals(Object o) { 053 if (this == o) return true; 054 if (!(o instanceof TestObject)) return false; 055 TestObject that = (TestObject) o; 056 return name.equals(that.name) && 057 id.equals(that.id); 058 } 059 060 @Override 061 public int hashCode() { 062 return Objects.hash(name, id); 063 } 064 065 @Override 066 public String toString() { 067 return "TestObject{" + 068 "name='" + name + '\'' + 069 ", id=" + id + 070 '}'; 071 } 072 } 073 074 public ValueReferences(Path configFile) throws IOException, ObjectMappingException { 075 this.listener = WatchServiceListener.create(); 076 this.base = listener.listenToConfiguration(file -> HoconConfigurationLoader.builder().setDefaultOptions(o -> o.withShouldCopyDefaults(true)).setPath(file).build(), configFile); 077 this.base.updates().subscribe($ -> System.out.println("Configuration auto-reloaded")); 078 this.base.errors().subscribe(err -> { 079 Throwable t = err.getValue(); 080 System.out.println("Unable to " + err.getKey() + " the configuration: " + t.getMessage()); 081 if (t.getCause() != null) { 082 System.out.println(t.getCause().getMessage()); 083 } 084 }); 085 086 name = this.base.referenceTo(String.class, "name"); 087 this.name.subscribe(newName -> System.out.println("Reloaded, name is: " + newName)); 088 cookieCount = this.base.referenceTo(Integer.class, new Object[] {"cookie-count"}, 5); 089 this.complex = this.base.referenceTo(new TypeToken<List<TestObject>>() {}, "complex"); 090 this.base.save(); 091 } 092 093 public void repl() { 094 boolean running = true; 095 if (System.console() == null) { 096 System.err.println("Not at an interactive prompt"); 097 this.printData(); 098 return; 099 } 100 101 while (running) { 102 String next = System.console().readLine(">"); 103 if (next == null) { 104 break; 105 } 106 String[] cmd = next.split(" "); 107 if (cmd.length == 0) { 108 continue; 109 } 110 111 switch (cmd[0]) { 112 case "stop": 113 running = false; 114 break; 115 case "name": 116 if (cmd.length < 2) { 117 System.err.println("Not enough arguments, usage: name <new-name>"); 118 break; 119 } 120 name.setAndSave(cmd[1]); 121 System.out.println("Name: " + this.name.get()); 122 break; 123 case "dump": 124 printData(); 125 break; 126 case "help": 127 System.out.println("Value reference tester\n" + 128 "Commands:\n\n" + 129 "stop: Exit the loop\n" + 130 "name <name>: Update the name in the config file\n" + 131 "dump: Dump all accessed data in the config file\n" + 132 "help: Show this message" 133 ); 134 break; 135 default: 136 System.err.println("Unknown command '" + next + "'"); 137 System.err.println("help for help"); 138 } 139 } 140 } 141 142 public void printData() { 143 System.out.println("Name: " + this.name.get()); 144 System.out.println("Cookie count: " + this.cookieCount.get()); 145 System.out.println("Complex: "); 146 if (this.complex.get().isEmpty()) { 147 System.out.println("(empty)"); 148 } else { 149 for (TestObject obj : this.complex.get()) { 150 System.out.println("- " + obj); 151 } 152 } 153 } 154 155 public static void main(String[] args) { 156 if (args.length != 1) { 157 System.err.println("Usage: ./reference-example <file>"); 158 return; 159 } 160 final Path path = Paths.get(args[0]); 161 try { 162 new ValueReferences(path).repl(); 163 } catch (IOException | ObjectMappingException e) { 164 System.out.println("Error loading configuration: " + e.getMessage()); 165 e.printStackTrace(); 166 } 167 } 168 169}