Commits
Wesley Wolfe authored 8ac95b65e07
1 1 | package org.bukkit.configuration.file; |
2 2 | |
3 + | import com.google.common.base.Charsets; |
3 4 | import com.google.common.io.Files; |
4 5 | |
5 6 | import org.apache.commons.lang.Validate; |
6 7 | import org.bukkit.configuration.InvalidConfigurationException; |
8 + | |
7 9 | import java.io.BufferedReader; |
8 10 | import java.io.File; |
9 11 | import java.io.FileInputStream; |
10 12 | import java.io.FileNotFoundException; |
11 - | import java.io.FileWriter; |
13 + | import java.io.FileOutputStream; |
12 14 | import java.io.IOException; |
13 15 | import java.io.InputStream; |
14 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 + | |
15 22 | import org.bukkit.configuration.Configuration; |
16 23 | import org.bukkit.configuration.MemoryConfiguration; |
24 + | import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; |
17 25 | |
18 26 | /** |
19 27 | * This is a base class for all File based implementations of {@link |
20 28 | * Configuration} |
21 29 | */ |
22 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 + | |
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 + | |
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 + | |
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 + | |
23 66 | /** |
24 67 | * Creates an empty {@link FileConfiguration} with no default values. |
25 68 | */ |
26 69 | public FileConfiguration() { |
27 70 | super(); |
28 71 | } |
29 72 | |
30 73 | /** |
31 74 | * Creates an empty {@link FileConfiguration} using the specified {@link |
32 75 | * Configuration} as a source for all default values. |
36 79 | public FileConfiguration(Configuration defaults) { |
37 80 | super(defaults); |
38 81 | } |
39 82 | |
40 83 | /** |
41 84 | * Saves this {@link FileConfiguration} to the specified location. |
42 85 | * <p> |
43 86 | * If the file does not exist, it will be created. If already exists, it |
44 87 | * will be overwritten. If it cannot be overwritten or created, an |
45 88 | * exception will be thrown. |
89 + | * <p> |
90 + | * This method will save using the system default encoding, or possibly |
91 + | * using UTF8. |
46 92 | * |
47 93 | * @param file File to save to. |
48 94 | * @throws IOException Thrown when the given file cannot be written to for |
49 95 | * any reason. |
50 96 | * @throws IllegalArgumentException Thrown when file is null. |
51 97 | */ |
52 98 | public void save(File file) throws IOException { |
53 99 | Validate.notNull(file, "File cannot be null"); |
54 100 | |
55 101 | Files.createParentDirs(file); |
56 102 | |
57 103 | String data = saveToString(); |
58 104 | |
59 - | FileWriter writer = new FileWriter(file); |
105 + | Writer writer = new OutputStreamWriter(new FileOutputStream(file), UTF8_OVERRIDE && !UTF_BIG ? Charsets.UTF_8 : Charset.defaultCharset()); |
60 106 | |
61 107 | try { |
62 108 | writer.write(data); |
63 109 | } finally { |
64 110 | writer.close(); |
65 111 | } |
66 112 | } |
67 113 | |
68 114 | /** |
69 115 | * Saves this {@link FileConfiguration} to the specified location. |
70 116 | * <p> |
71 117 | * If the file does not exist, it will be created. If already exists, it |
72 118 | * will be overwritten. If it cannot be overwritten or created, an |
73 119 | * exception will be thrown. |
120 + | * <p> |
121 + | * This method will save using the system default encoding, or possibly |
122 + | * using UTF8. |
74 123 | * |
75 124 | * @param file File to save to. |
76 125 | * @throws IOException Thrown when the given file cannot be written to for |
77 126 | * any reason. |
78 127 | * @throws IllegalArgumentException Thrown when file is null. |
79 128 | */ |
80 129 | public void save(String file) throws IOException { |
81 130 | Validate.notNull(file, "File cannot be null"); |
82 131 | |
83 132 | save(new File(file)); |
92 141 | |
93 142 | /** |
94 143 | * Loads this {@link FileConfiguration} from the specified location. |
95 144 | * <p> |
96 145 | * All the values contained within this configuration will be removed, |
97 146 | * leaving only settings and defaults, and the new values will be loaded |
98 147 | * from the given file. |
99 148 | * <p> |
100 149 | * If the file cannot be loaded for any reason, an exception will be |
101 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. |
102 155 | * |
103 156 | * @param file File to load from. |
104 157 | * @throws FileNotFoundException Thrown when the given file cannot be |
105 158 | * opened. |
106 159 | * @throws IOException Thrown when the given file cannot be read. |
107 160 | * @throws InvalidConfigurationException Thrown when the given file is not |
108 161 | * a valid Configuration. |
109 162 | * @throws IllegalArgumentException Thrown when file is null. |
110 163 | */ |
111 164 | public void load(File file) throws FileNotFoundException, IOException, InvalidConfigurationException { |
112 165 | Validate.notNull(file, "File cannot be null"); |
113 166 | |
114 - | load(new FileInputStream(file)); |
167 + | final FileInputStream stream = new FileInputStream(file); |
168 + | |
169 + | load(new InputStreamReader(stream, UTF8_OVERRIDE && !UTF_BIG ? Charsets.UTF_8 : Charset.defaultCharset())); |
115 170 | } |
116 171 | |
117 172 | /** |
118 173 | * Loads this {@link FileConfiguration} from the specified stream. |
119 174 | * <p> |
120 175 | * All the values contained within this configuration will be removed, |
121 176 | * leaving only settings and defaults, and the new values will be loaded |
122 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. |
123 181 | * |
124 182 | * @param stream Stream to load from |
125 183 | * @throws IOException Thrown when the given file cannot be read. |
126 184 | * @throws InvalidConfigurationException Thrown when the given file is not |
127 185 | * a valid Configuration. |
128 186 | * @throws IllegalArgumentException Thrown when stream is null. |
187 + | * @deprecated This does not consider encoding |
188 + | * @see #load(Reader) |
129 189 | */ |
190 + | |
130 191 | public void load(InputStream stream) throws IOException, InvalidConfigurationException { |
131 192 | Validate.notNull(stream, "Stream cannot be null"); |
132 193 | |
133 - | InputStreamReader reader = new InputStreamReader(stream); |
134 - | StringBuilder builder = new StringBuilder(); |
135 - | BufferedReader input = new BufferedReader(reader); |
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); |
136 212 | |
213 + | StringBuilder builder = new StringBuilder(); |
137 214 | |
138 215 | try { |
139 216 | String line; |
140 217 | |
141 218 | while ((line = input.readLine()) != null) { |
142 219 | builder.append(line); |
143 220 | builder.append('\n'); |
144 221 | } |
145 222 | } finally { |
146 223 | input.close(); |