Bukkit-API  1.7.9-R0.2
The inofficial Bukkit-API
YamlConfiguration.java
1 package org.bukkit.configuration.file;
2 
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.Reader;
8 import java.util.Map;
9 import java.util.logging.Level;
10 
11 import org.apache.commons.lang.Validate;
12 import org.bukkit.Bukkit;
16 import org.yaml.snakeyaml.DumperOptions;
17 import org.yaml.snakeyaml.Yaml;
18 import org.yaml.snakeyaml.error.YAMLException;
19 import org.yaml.snakeyaml.representer.Representer;
20 
21 /**
22  * An implementation of {@link Configuration} which saves all files in Yaml.
23  * Note that this implementation is not synchronized.
24  */
25 public class YamlConfiguration extends FileConfiguration {
26  protected static final String COMMENT_PREFIX = "# ";
27  protected static final String BLANK_CONFIG = "{}\n";
28  private final DumperOptions yamlOptions = new DumperOptions();
29  private final Representer yamlRepresenter = new YamlRepresenter();
30  private final Yaml yaml = new Yaml(new YamlConstructor(), yamlRepresenter, yamlOptions);
31 
32  @Override
33  public String saveToString() {
34  yamlOptions.setIndent(options().indent());
35  yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
36  yamlOptions.setAllowUnicode(SYSTEM_UTF);
37  yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
38 
39  String header = buildHeader();
40  String dump = yaml.dump(getValues(false));
41 
42  if (dump.equals(BLANK_CONFIG)) {
43  dump = "";
44  }
45 
46  return header + dump;
47  }
48 
49  @Override
50  public void loadFromString(String contents) throws InvalidConfigurationException {
51  Validate.notNull(contents, "Contents cannot be null");
52 
53  Map<?, ?> input;
54  try {
55  input = (Map<?, ?>) yaml.load(contents);
56  } catch (YAMLException e) {
57  throw new InvalidConfigurationException(e);
58  } catch (ClassCastException e) {
59  throw new InvalidConfigurationException("Top level is not a Map.");
60  }
61 
62  String header = parseHeader(contents);
63  if (header.length() > 0) {
64  options().header(header);
65  }
66 
67  if (input != null) {
68  convertMapsToSections(input, this);
69  }
70  }
71 
72  protected void convertMapsToSections(Map<?, ?> input, ConfigurationSection section) {
73  for (Map.Entry<?, ?> entry : input.entrySet()) {
74  String key = entry.getKey().toString();
75  Object value = entry.getValue();
76 
77  if (value instanceof Map) {
78  convertMapsToSections((Map<?, ?>) value, section.createSection(key));
79  } else {
80  section.set(key, value);
81  }
82  }
83  }
84 
85  protected String parseHeader(String input) {
86  String[] lines = input.split("\r?\n", -1);
87  StringBuilder result = new StringBuilder();
88  boolean readingHeader = true;
89  boolean foundHeader = false;
90 
91  for (int i = 0; (i < lines.length) && (readingHeader); i++) {
92  String line = lines[i];
93 
94  if (line.startsWith(COMMENT_PREFIX)) {
95  if (i > 0) {
96  result.append("\n");
97  }
98 
99  if (line.length() > COMMENT_PREFIX.length()) {
100  result.append(line.substring(COMMENT_PREFIX.length()));
101  }
102 
103  foundHeader = true;
104  } else if ((foundHeader) && (line.length() == 0)) {
105  result.append("\n");
106  } else if (foundHeader) {
107  readingHeader = false;
108  }
109  }
110 
111  return result.toString();
112  }
113 
114  @Override
115  protected String buildHeader() {
116  String header = options().header();
117 
118  if (options().copyHeader()) {
119  Configuration def = getDefaults();
120 
121  if ((def != null) && (def instanceof FileConfiguration)) {
122  FileConfiguration filedefaults = (FileConfiguration) def;
123  String defaultsHeader = filedefaults.buildHeader();
124 
125  if ((defaultsHeader != null) && (defaultsHeader.length() > 0)) {
126  return defaultsHeader;
127  }
128  }
129  }
130 
131  if (header == null) {
132  return "";
133  }
134 
135  StringBuilder builder = new StringBuilder();
136  String[] lines = header.split("\r?\n", -1);
137  boolean startedHeader = false;
138 
139  for (int i = lines.length - 1; i >= 0; i--) {
140  builder.insert(0, "\n");
141 
142  if ((startedHeader) || (lines[i].length() != 0)) {
143  builder.insert(0, lines[i]);
144  builder.insert(0, COMMENT_PREFIX);
145  startedHeader = true;
146  }
147  }
148 
149  return builder.toString();
150  }
151 
152  @Override
154  if (options == null) {
155  options = new YamlConfigurationOptions(this);
156  }
157 
159  }
160 
161  /**
162  * Creates a new {@link YamlConfiguration}, loading from the given file.
163  * <p>
164  * Any errors loading the Configuration will be logged and then ignored.
165  * If the specified input is not a valid config, a blank config will be
166  * returned.
167  * <p>
168  * The encoding used may follow the system dependent default.
169  *
170  * @param file Input file
171  * @return Resulting configuration
172  * @throws IllegalArgumentException Thrown if file is null
173  */
174  public static YamlConfiguration loadConfiguration(File file) {
175  Validate.notNull(file, "File cannot be null");
176 
177  YamlConfiguration config = new YamlConfiguration();
178 
179  try {
180  config.load(file);
181  } catch (FileNotFoundException ex) {
182  } catch (IOException ex) {
183  Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, ex);
184  } catch (InvalidConfigurationException ex) {
185  Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file , ex);
186  }
187 
188  return config;
189  }
190 
191  /**
192  * Creates a new {@link YamlConfiguration}, loading from the given stream.
193  * <p>
194  * Any errors loading the Configuration will be logged and then ignored.
195  * If the specified input is not a valid config, a blank config will be
196  * returned.
197  *
198  * @param stream Input stream
199  * @return Resulting configuration
200  * @throws IllegalArgumentException Thrown if stream is null
201  * @deprecated does not properly consider encoding
202  * @see #load(InputStream)
203  * @see #loadConfiguration(Reader)
204  */
205  @Deprecated
206  public static YamlConfiguration loadConfiguration(InputStream stream) {
207  Validate.notNull(stream, "Stream cannot be null");
208 
209  YamlConfiguration config = new YamlConfiguration();
210 
211  try {
212  config.load(stream);
213  } catch (IOException ex) {
214  Bukkit.getLogger().log(Level.SEVERE, "Cannot load configuration from stream", ex);
215  } catch (InvalidConfigurationException ex) {
216  Bukkit.getLogger().log(Level.SEVERE, "Cannot load configuration from stream", ex);
217  }
218 
219  return config;
220  }
221 
222 
223  /**
224  * Creates a new {@link YamlConfiguration}, loading from the given reader.
225  * <p>
226  * Any errors loading the Configuration will be logged and then ignored.
227  * If the specified input is not a valid config, a blank config will be
228  * returned.
229  *
230  * @param reader input
231  * @return resulting configuration
232  * @throws IllegalArgumentException Thrown if stream is null
233  */
234  public static YamlConfiguration loadConfiguration(Reader reader) {
235  Validate.notNull(reader, "Stream cannot be null");
236 
237  YamlConfiguration config = new YamlConfiguration();
238 
239  try {
240  config.load(reader);
241  } catch (IOException ex) {
242  Bukkit.getLogger().log(Level.SEVERE, "Cannot load configuration from stream", ex);
243  } catch (InvalidConfigurationException ex) {
244  Bukkit.getLogger().log(Level.SEVERE, "Cannot load configuration from stream", ex);
245  }
246 
247  return config;
248  }
249 }
void set(String path, Object value)
Map< String, Object > getValues(boolean deep)
ConfigurationSection createSection(String path)
static YamlConfiguration loadConfiguration(InputStream stream)
static Logger getLogger()
Definition: Bukkit.java:294
static YamlConfiguration loadConfiguration(Reader reader)
static YamlConfiguration loadConfiguration(File file)