Bukkit-API  1.7.9-R0.2
The inofficial Bukkit-API
FileConfiguration.java
1 package org.bukkit.configuration.file;
2 
3 import com.google.common.base.Charsets;
4 import com.google.common.io.Files;
5 
6 import org.apache.commons.lang.Validate;
8 
9 import java.io.BufferedReader;
10 import java.io.File;
11 import java.io.FileInputStream;
12 import java.io.FileNotFoundException;
13 import java.io.FileOutputStream;
14 import java.io.IOException;
15 import java.io.InputStream;
16 import java.io.InputStreamReader;
17 import java.io.OutputStreamWriter;
18 import java.io.Reader;
19 import java.io.Writer;
20 import java.nio.charset.Charset;
21 
24 import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
25 
26 /**
27  * This is a base class for all File based implementations of {@link
28  * Configuration}
29  */
30 public abstract class FileConfiguration extends MemoryConfiguration {
31  /**
32  * This value specified that the system default encoding should be
33  * completely ignored, as it cannot handle the ASCII character set, or it
34  * is a strict-subset of UTF8 already (plain ASCII).
35  *
36  * @deprecated temporary compatibility measure
37  */
38  @Deprecated
39  public static final boolean UTF8_OVERRIDE;
40  /**
41  * This value specifies if the system default encoding is unicode, but
42  * cannot parse standard ASCII.
43  *
44  * @deprecated temporary compatibility measure
45  */
46  @Deprecated
47  public static final boolean UTF_BIG;
48  /**
49  * This value specifies if the system supports unicode.
50  *
51  * @deprecated temporary compatibility measure
52  */
53  @Deprecated
54  public static final boolean SYSTEM_UTF;
55  static {
56  final byte[] testBytes = Base64Coder.decode("ICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX4NCg==");
57  final String testString = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\r\n";
58  final Charset defaultCharset = Charset.defaultCharset();
59  final String resultString = new String(testBytes, defaultCharset);
60  final boolean trueUTF = defaultCharset.name().contains("UTF");
61  UTF8_OVERRIDE = !testString.equals(resultString) || defaultCharset.equals(Charset.forName("US-ASCII"));
62  SYSTEM_UTF = trueUTF || UTF8_OVERRIDE;
63  UTF_BIG = trueUTF && UTF8_OVERRIDE;
64  }
65 
66  /**
67  * Creates an empty {@link FileConfiguration} with no default values.
68  */
69  public FileConfiguration() {
70  super();
71  }
72 
73  /**
74  * Creates an empty {@link FileConfiguration} using the specified {@link
75  * Configuration} as a source for all default values.
76  *
77  * @param defaults Default value provider
78  */
79  public FileConfiguration(Configuration defaults) {
80  super(defaults);
81  }
82 
83  /**
84  * Saves this {@link FileConfiguration} to the specified location.
85  * <p>
86  * If the file does not exist, it will be created. If already exists, it
87  * will be overwritten. If it cannot be overwritten or created, an
88  * exception will be thrown.
89  * <p>
90  * This method will save using the system default encoding, or possibly
91  * using UTF8.
92  *
93  * @param file File to save to.
94  * @throws IOException Thrown when the given file cannot be written to for
95  * any reason.
96  * @throws IllegalArgumentException Thrown when file is null.
97  */
98  public void save(File file) throws IOException {
99  Validate.notNull(file, "File cannot be null");
100 
101  Files.createParentDirs(file);
102 
103  String data = saveToString();
104 
105  Writer writer = new OutputStreamWriter(new FileOutputStream(file), UTF8_OVERRIDE && !UTF_BIG ? Charsets.UTF_8 : Charset.defaultCharset());
106 
107  try {
108  writer.write(data);
109  } finally {
110  writer.close();
111  }
112  }
113 
114  /**
115  * Saves this {@link FileConfiguration} to the specified location.
116  * <p>
117  * If the file does not exist, it will be created. If already exists, it
118  * will be overwritten. If it cannot be overwritten or created, an
119  * exception will be thrown.
120  * <p>
121  * This method will save using the system default encoding, or possibly
122  * using UTF8.
123  *
124  * @param file File to save to.
125  * @throws IOException Thrown when the given file cannot be written to for
126  * any reason.
127  * @throws IllegalArgumentException Thrown when file is null.
128  */
129  public void save(String file) throws IOException {
130  Validate.notNull(file, "File cannot be null");
131 
132  save(new File(file));
133  }
134 
135  /**
136  * Saves this {@link FileConfiguration} to a string, and returns it.
137  *
138  * @return String containing this configuration.
139  */
140  public abstract String saveToString();
141 
142  /**
143  * Loads this {@link FileConfiguration} from the specified location.
144  * <p>
145  * All the values contained within this configuration will be removed,
146  * leaving only settings and defaults, and the new values will be loaded
147  * from the given file.
148  * <p>
149  * If the file cannot be loaded for any reason, an exception will be
150  * thrown.
151  * <p>
152  * This will attempt to use the {@link Charset#defaultCharset()} for
153  * files, unless {@link #UTF8_OVERRIDE} but not {@link #UTF_BIG} is
154  * specified.
155  *
156  * @param file File to load from.
157  * @throws FileNotFoundException Thrown when the given file cannot be
158  * opened.
159  * @throws IOException Thrown when the given file cannot be read.
160  * @throws InvalidConfigurationException Thrown when the given file is not
161  * a valid Configuration.
162  * @throws IllegalArgumentException Thrown when file is null.
163  */
164  public void load(File file) throws FileNotFoundException, IOException, InvalidConfigurationException {
165  Validate.notNull(file, "File cannot be null");
166 
167  final FileInputStream stream = new FileInputStream(file);
168 
169  load(new InputStreamReader(stream, UTF8_OVERRIDE && !UTF_BIG ? Charsets.UTF_8 : Charset.defaultCharset()));
170  }
171 
172  /**
173  * Loads this {@link FileConfiguration} from the specified stream.
174  * <p>
175  * All the values contained within this configuration will be removed,
176  * leaving only settings and defaults, and the new values will be loaded
177  * from the given stream.
178  * <p>
179  * This will attempt to use the {@link Charset#defaultCharset()}, unless
180  * {@link #UTF8_OVERRIDE} or {@link #UTF_BIG} is specified.
181  *
182  * @param stream Stream to load from
183  * @throws IOException Thrown when the given file cannot be read.
184  * @throws InvalidConfigurationException Thrown when the given file is not
185  * a valid Configuration.
186  * @throws IllegalArgumentException Thrown when stream is null.
187  * @deprecated This does not consider encoding
188  * @see #load(Reader)
189  */
190  @Deprecated
191  public void load(InputStream stream) throws IOException, InvalidConfigurationException {
192  Validate.notNull(stream, "Stream cannot be null");
193 
194  load(new InputStreamReader(stream, UTF8_OVERRIDE ? Charsets.UTF_8 : Charset.defaultCharset()));
195  }
196 
197  /**
198  * Loads this {@link FileConfiguration} from the specified reader.
199  * <p>
200  * All the values contained within this configuration will be removed,
201  * leaving only settings and defaults, and the new values will be loaded
202  * from the given stream.
203  *
204  * @param reader the reader to load from
205  * @throws IOException thrown when underlying reader throws an IOException
206  * @throws InvalidConfigurationException thrown when the reader does not
207  * represent a valid Configuration
208  * @throws IllegalArgumentException thrown when reader is null
209  */
210  public void load(Reader reader) throws IOException, InvalidConfigurationException {
211  BufferedReader input = reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
212 
213  StringBuilder builder = new StringBuilder();
214 
215  try {
216  String line;
217 
218  while ((line = input.readLine()) != null) {
219  builder.append(line);
220  builder.append('\n');
221  }
222  } finally {
223  input.close();
224  }
225 
226  loadFromString(builder.toString());
227  }
228 
229  /**
230  * Loads this {@link FileConfiguration} from the specified location.
231  * <p>
232  * All the values contained within this configuration will be removed,
233  * leaving only settings and defaults, and the new values will be loaded
234  * from the given file.
235  * <p>
236  * If the file cannot be loaded for any reason, an exception will be
237  * thrown.
238  *
239  * @param file File to load from.
240  * @throws FileNotFoundException Thrown when the given file cannot be
241  * opened.
242  * @throws IOException Thrown when the given file cannot be read.
243  * @throws InvalidConfigurationException Thrown when the given file is not
244  * a valid Configuration.
245  * @throws IllegalArgumentException Thrown when file is null.
246  */
247  public void load(String file) throws FileNotFoundException, IOException, InvalidConfigurationException {
248  Validate.notNull(file, "File cannot be null");
249 
250  load(new File(file));
251  }
252 
253  /**
254  * Loads this {@link FileConfiguration} from the specified string, as
255  * opposed to from file.
256  * <p>
257  * All the values contained within this configuration will be removed,
258  * leaving only settings and defaults, and the new values will be loaded
259  * from the given string.
260  * <p>
261  * If the string is invalid in any way, an exception will be thrown.
262  *
263  * @param contents Contents of a Configuration to load.
264  * @throws InvalidConfigurationException Thrown if the specified string is
265  * invalid.
266  * @throws IllegalArgumentException Thrown if contents is null.
267  */
268  public abstract void loadFromString(String contents) throws InvalidConfigurationException;
269 
270  /**
271  * Compiles the header for this {@link FileConfiguration} and returns the
272  * result.
273  * <p>
274  * This will use the header from {@link #options()} -> {@link
275  * FileConfigurationOptions#header()}, respecting the rules of {@link
276  * FileConfigurationOptions#copyHeader()} if set.
277  *
278  * @return Compiled header
279  */
280  protected abstract String buildHeader();
281 
282  @Override
284  if (options == null) {
285  options = new FileConfigurationOptions(this);
286  }
287 
289  }
290 }
abstract void loadFromString(String contents)