瀏覽代碼

Initial import of util classes

tags/0.6.3
Chris Smith 14 年之前
當前提交
80d0cb4bf8

+ 370
- 0
src/com/dmdirc/util/ConfigFile.java 查看文件

@@ -0,0 +1,370 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import java.io.File;
26
+import java.io.FileNotFoundException;
27
+import java.io.IOException;
28
+import java.io.InputStream;
29
+import java.nio.charset.Charset;
30
+import java.util.ArrayList;
31
+import java.util.GregorianCalendar;
32
+import java.util.HashMap;
33
+import java.util.List;
34
+import java.util.Map;
35
+
36
+/**
37
+ * Reads and writes a standard DMDirc config file.
38
+ *
39
+ * @author chris
40
+ */
41
+public class ConfigFile extends TextFile {
42
+
43
+    /** A list of domains in this config file. */
44
+    private final List<String> domains = new ArrayList<String>();
45
+
46
+    /** The values associated with each flat domain. */
47
+    private final MapList<String, String> flatdomains = new MapList<String, String>();
48
+
49
+    /** The key/value sets associated with each key domain. */
50
+    private final Map<String, Map<String, String>> keydomains
51
+            = new HashMap<String, Map<String, String>>();
52
+    
53
+    /** Whether or not we should automatically create domains. */
54
+    private boolean automake;
55
+
56
+    /**
57
+     * Creates a new read-only Config File from the specified input stream.
58
+     * 
59
+     * @param is The input stream to read
60
+     */
61
+    public ConfigFile(final InputStream is) {
62
+        super(is, Charset.forName("UTF-8"));
63
+    }
64
+
65
+    /**
66
+     * Creates a new Config File from the specified file.
67
+     * 
68
+     * @param file The file to read/write
69
+     */
70
+    public ConfigFile(final File file) {
71
+        super(file, Charset.forName("UTF-8"));
72
+    }
73
+
74
+    /**
75
+     * Creates a new Config File from the specified file.
76
+     * 
77
+     * @param filename The name of the file to read/write
78
+     */
79
+    public ConfigFile(final String filename) {
80
+        this(new File(filename));
81
+    }
82
+
83
+    /**
84
+     * Sets the "automake" value of this config file. If automake is set to
85
+     * true, any calls to getKeyDomain will automatically create the domain
86
+     * if it did not previously exist.
87
+     * 
88
+     * @param automake The new value of the automake setting of this file
89
+     */
90
+    public void setAutomake(final boolean automake) {
91
+        this.automake = automake;
92
+    }
93
+
94
+    /**
95
+     * Reads the data from the file.
96
+     * 
97
+     * @throws FileNotFoundException if the file is not found
98
+     * @throws IOException if an i/o exception occured when reading
99
+     * @throws InvalidConfigFileException if the config file isn't valid
100
+     */
101
+    public void read() throws FileNotFoundException, IOException, InvalidConfigFileException {
102
+        String domain = null;
103
+        boolean keydomain = false;
104
+        int offset;
105
+        
106
+        keydomains.clear();
107
+        flatdomains.clear();
108
+        domains.clear();
109
+        
110
+        readLines();
111
+
112
+        for (String line : getLines()) {
113
+            String tline = line;
114
+            
115
+            while (!tline.isEmpty() && (tline.charAt(0) == '\t' || 
116
+                    tline.charAt(0) == ' ')) {
117
+                tline = tline.substring(1);
118
+            }
119
+
120
+            if (tline.indexOf('#') == 0 || tline.isEmpty()) {
121
+                continue;
122
+            } else if (
123
+                    (tline.endsWith(":") && !tline.endsWith("\\:"))
124
+                    && findEquals(tline) == -1) {
125
+                domain = unescape(tline.substring(0, tline.length() - 1));
126
+
127
+                domains.add(domain);
128
+
129
+                keydomain = keydomains.containsKey(domain)
130
+                        || flatdomains.containsValue("keysections", domain);
131
+                
132
+                if (keydomain && !keydomains.containsKey(domain)) {
133
+                    keydomains.put(domain, new HashMap<String, String>());
134
+                } else if (!keydomain && !flatdomains.containsKey(domain)) {
135
+                    flatdomains.add(domain);
136
+                }
137
+            } else if (domain != null && keydomain
138
+                    && (offset = findEquals(tline)) != -1) {
139
+                final String key = unescape(tline.substring(0, offset));
140
+                final String value = unescape(tline.substring(offset + 1));
141
+
142
+                keydomains.get(domain).put(key, value);
143
+            } else if (domain != null && !keydomain) {
144
+                flatdomains.add(domain, unescape(tline));
145
+            } else {
146
+                throw new InvalidConfigFileException("Unknown or unexpected" +
147
+                        " line encountered: " + tline);
148
+            }
149
+        }
150
+    }
151
+
152
+    /**
153
+     * Writes the contents of this ConfigFile to disk.
154
+     * 
155
+     * @throws IOException if the write operation fails
156
+     */
157
+    public void write() throws IOException {
158
+        if (!isWritable()) {
159
+            throw new UnsupportedOperationException("Cannot write to a file "
160
+                    + "that isn't writable");
161
+        }
162
+        
163
+        final List<String> lines = new ArrayList<String>();
164
+
165
+        lines.add("# This is a DMDirc configuration file.");
166
+        lines.add("# Written on: " + new GregorianCalendar().getTime().toString());
167
+
168
+        writeMeta(lines);
169
+
170
+        for (String domain : domains) {
171
+            if ("keysections".equals(domain)) {
172
+                continue;
173
+            }
174
+
175
+            lines.add("");
176
+
177
+            lines.add(escape(domain) + ':');
178
+
179
+            if (flatdomains.containsKey(domain)) {
180
+                for (String entry : flatdomains.get(domain)) {
181
+                    lines.add("  " + escape(entry));
182
+                }
183
+            } else {
184
+                for (Map.Entry<String, String> entry : keydomains.get(domain).entrySet()) {
185
+                    lines.add("  " + escape(entry.getKey()) + "="
186
+                            + escape(entry.getValue()));
187
+                }
188
+            }
189
+        }
190
+
191
+        writeLines(lines);
192
+    }
193
+    
194
+    /**
195
+     * Appends the meta-data (keysections) to the specified list of lines.
196
+     * 
197
+     * @param lines The set of lines to be appended to
198
+     */
199
+    private void writeMeta(final List<String> lines) {
200
+        lines.add("");
201
+        lines.add("# This section indicates which sections below take key/value");
202
+        lines.add("# pairs, rather than a simple list. It should be placed above");
203
+        lines.add("# any sections that take key/values.");
204
+        lines.add("keysections:");
205
+
206
+        for (String domain : domains) {
207
+            if ("keysections".equals(domain)) {
208
+                continue;
209
+            } else if (keydomains.containsKey(domain)) {
210
+                lines.add("  " + domain);
211
+            }
212
+        }
213
+    }
214
+    
215
+    /**
216
+     * Retrieves all the key domains for this config file.
217
+     * 
218
+     * @return This config file's key domains
219
+     */
220
+    public Map<String, Map<String, String>> getKeyDomains() {
221
+        return keydomains;
222
+    }
223
+    
224
+    /**
225
+     * Retrieves the key/values of the specified key domain.
226
+     * 
227
+     * @param domain The domain to be retrieved
228
+     * @return A map of keys to values in the specified domain
229
+     */
230
+    public Map<String, String> getKeyDomain(final String domain) {
231
+        if (automake && !isKeyDomain(domain)) {
232
+            domains.add(domain);
233
+            keydomains.put(domain, new HashMap<String, String>());
234
+        }
235
+        
236
+        return keydomains.get(domain);
237
+    }
238
+    
239
+    /**
240
+     * Retrieves the content of the specified flat domain.
241
+     * 
242
+     * @param domain The domain to be retrieved
243
+     * @return A list of lines in the specified domain
244
+     */
245
+    public List<String> getFlatDomain(final String domain) {
246
+        return flatdomains.get(domain);
247
+    }
248
+    
249
+    /**
250
+     * Determines if this config file has the specified domain.
251
+     * 
252
+     * @param domain The domain to check for
253
+     * @return True if the domain is known, false otherwise
254
+     */
255
+    public boolean hasDomain(final String domain) {
256
+        return keydomains.containsKey(domain) || flatdomains.containsKey(domain);
257
+    }
258
+
259
+    /**
260
+     * Determines if this config file has the specified domain, and the domain
261
+     * is a key domain.
262
+     * 
263
+     * @param domain The domain to check for
264
+     * @return True if the domain is known and keyed, false otherwise
265
+     */
266
+    public boolean isKeyDomain(final String domain) {
267
+        return keydomains.containsKey(domain);
268
+    }
269
+
270
+    /**
271
+     * Determines if this config file has the specified domain, and the domain
272
+     * is a flat domain.
273
+     * 
274
+     * @param domain The domain to check for
275
+     * @return True if the domain is known and flat, false otherwise
276
+     */
277
+    public boolean isFlatDomain(final String domain) {
278
+        return flatdomains.containsKey(domain);
279
+    }
280
+    
281
+    /**
282
+     * Adds a new flat domain to this config file.
283
+     * 
284
+     * @param name The name of the domain to be added
285
+     * @param data The content of the domain
286
+     */
287
+    public void addDomain(final String name, final List<String> data) {
288
+        domains.add(name);
289
+        flatdomains.add(name, data);
290
+    }
291
+
292
+    /**
293
+     * Adds a new key domain to this config file.
294
+     * 
295
+     * @param name The name of the domain to be added
296
+     * @param data The content of the domain
297
+     */    
298
+    public void addDomain(final String name, final Map<String, String> data) {
299
+        domains.add(name);
300
+        keydomains.put(name, data);
301
+    }
302
+    
303
+    /**
304
+     * Unescapes any escaped characters in the specified input string.
305
+     * 
306
+     * @param input The string to unescape
307
+     * @return The string with all escape chars (\) resolved
308
+     */
309
+    protected static String unescape(final String input) {
310
+        boolean escaped = false;
311
+        final StringBuilder temp = new StringBuilder();
312
+
313
+        for (int i = 0; i < input.length(); i++) {
314
+            final char ch = input.charAt(i);
315
+
316
+            if (escaped) {
317
+                if (ch == 'n') {
318
+                    temp.append('\n');
319
+                } else if (ch == 'r') {
320
+                    temp.append('\r');
321
+                } else {
322
+                    temp.append(ch);
323
+                }
324
+                
325
+                escaped = false;
326
+            } else if (ch == '\\') {
327
+                escaped = true;
328
+            } else {
329
+                temp.append(ch);
330
+            }
331
+        }
332
+        
333
+        return temp.toString();
334
+    }
335
+    
336
+    /**
337
+     * Escapes the specified input string by prefixing all occurances of
338
+     * \, \n, \r, =, # and : with backslashes.
339
+     * 
340
+     * @param input The string to be escaped
341
+     * @return A backslash-armoured version of the string
342
+     */
343
+    protected static String escape(final String input) {
344
+        return input.replaceAll("\\\\", "\\\\\\\\").replaceAll("\n", "\\\\n")
345
+                .replaceAll("\r", "\\\\r").replaceAll("=", "\\\\=")
346
+                .replaceAll(":", "\\\\:").replaceAll("#", "\\\\#");
347
+    }
348
+    
349
+    /**
350
+     * Finds the first non-escaped instance of '=' in the specified string.
351
+     * 
352
+     * @param input The string to be searched
353
+     * @return The offset of the first non-escaped instance of '=', or -1.
354
+     */
355
+    protected static int findEquals(final String input) {
356
+        boolean escaped = false;
357
+        
358
+        for (int i = 0; i < input.length(); i++) {
359
+            if (escaped) {
360
+                escaped = false;
361
+            } else if (input.charAt(i) == '\\') {
362
+                escaped = true;
363
+            } else if (input.charAt(i) == '=') {
364
+                return i;
365
+            }
366
+        }
367
+        
368
+        return -1;
369
+    }
370
+}

+ 97
- 0
src/com/dmdirc/util/DoubleMap.java 查看文件

@@ -0,0 +1,97 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+package com.dmdirc.util;
23
+
24
+import java.util.ArrayList;
25
+import java.util.HashSet;
26
+import java.util.List;
27
+import java.util.Set;
28
+
29
+/**
30
+ * An object that maps keys to values, and values back to keys. Currently
31
+ * does no checking for duplicates. Does not allow null values.
32
+ * 
33
+ * @param <A> The first type of data to be mapped
34
+ * @param <B> The second type of data to be mapped 
35
+ * @author chris
36
+ */
37
+public class DoubleMap<A,B> {
38
+    
39
+    /** The keys in this map. */
40
+    protected final List<A> keys = new ArrayList<A>();
41
+    /** The values in this map. */
42
+    protected final List<B> values = new ArrayList<B>();
43
+    
44
+    /**
45
+     * Adds the specified pair to this map.
46
+     * 
47
+     * @param key The key for the map
48
+     * @param value The value for the map
49
+     */
50
+    public void put(final A key, final B value) {
51
+        if (key == null || value == null) {
52
+            throw new NullPointerException();
53
+        }
54
+        
55
+        keys.add(key);
56
+        values.add(value);
57
+    }
58
+    
59
+    /**
60
+     * Retrieves the value associated with the specified key.
61
+     * 
62
+     * @param key The key to search for 
63
+     * @return The value of the specified key
64
+     */
65
+    public B getValue(final A key) {
66
+        return values.get(keys.indexOf(key));
67
+    }
68
+    
69
+    /**
70
+     * Retrieves the key associated with the specified value.
71
+     * 
72
+     * @param value The value to search for
73
+     * @return The key of the specified value
74
+     */
75
+    public A getKey(final B value) {
76
+        return keys.get(values.indexOf(value));
77
+    }
78
+    
79
+    /**
80
+     * Retrieves the set of keys in this double map.
81
+     * 
82
+     * @return This map's key set
83
+     */
84
+    public Set<A> keySet() {
85
+        return new HashSet<A>(keys);
86
+    }
87
+    
88
+    /**
89
+     * Retrieves the set of values in this double map.
90
+     * 
91
+     * @return This map's value set
92
+     */
93
+    public Set<B> valueSet() {
94
+        return new HashSet<B>(values);
95
+    }
96
+
97
+}

+ 62
- 0
src/com/dmdirc/util/EquatableWeakReference.java 查看文件

@@ -0,0 +1,62 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import java.lang.ref.Reference;
26
+import java.lang.ref.WeakReference;
27
+
28
+/**
29
+ * An extension of WeakReference that implements a sane equals and hashcode
30
+ * method.
31
+ * 
32
+ * @param <T> The type of object that this reference contains
33
+ * @author chris
34
+ */
35
+public class EquatableWeakReference<T> extends WeakReference<T> {
36
+    
37
+    /**
38
+     * Creates a new instance of EquatableWeakReference.
39
+     * 
40
+     * @param referent The object that this weak reference should reference.
41
+     */
42
+    public EquatableWeakReference(T referent) {
43
+        super(referent);
44
+    }
45
+
46
+    /** {@inheritDoc} */
47
+    @Override
48
+    public boolean equals(Object obj) {
49
+        if (obj instanceof Reference) {
50
+            return get().equals(((Reference) obj).get());
51
+        } else {
52
+            return get().equals(obj);
53
+        }
54
+    }
55
+
56
+    /** {@inheritDoc} */
57
+    @Override
58
+    public int hashCode() {
59
+        return get().hashCode();
60
+    }
61
+    
62
+}

+ 47
- 0
src/com/dmdirc/util/InvalidConfigFileException.java 查看文件

@@ -0,0 +1,47 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+/**
26
+ * Thrown to indicate that a config file is invalid.
27
+ * @author chris
28
+ */
29
+public class InvalidConfigFileException extends Exception {
30
+    
31
+    /**
32
+     * A version number for this class. It should be changed whenever the class
33
+     * structure is changed (or anything else that would prevent serialized
34
+     * objects being unserialized with the new class).
35
+     */    
36
+    private static final long serialVersionUID = 1;
37
+
38
+    /**
39
+     * Creates a new InvalidConfigFileException.
40
+     * 
41
+     * @param string A description of the exception that occured.
42
+     */
43
+    public InvalidConfigFileException(String string) {
44
+        super(string);
45
+    }
46
+
47
+}

+ 118
- 0
src/com/dmdirc/util/ListenerList.java 查看文件

@@ -0,0 +1,118 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import java.util.List;
26
+
27
+/**
28
+ * Represents a list of event listeners, similar to EventListenerList, but
29
+ * not swing specific.
30
+ * 
31
+ * @author chris
32
+ */
33
+public class ListenerList {
34
+    
35
+    /** The map of class->listener or string->listener that we're using. */
36
+    private final MapList<Object, Object> listeners
37
+            = new MapList<Object, Object>();
38
+    
39
+    /**
40
+     * Creates a new instance of ListenerList.
41
+     */
42
+    public ListenerList() {
43
+        // Do nothing
44
+    }
45
+    
46
+    /**
47
+     * Adds a new listener of the specified type to this listener list.
48
+     * 
49
+     * @param listenerType The type of listener to be added
50
+     * @param listener The listener to be added
51
+     */
52
+    public <T> void add(final Class<T> listenerType, final T listener) {
53
+        listeners.add(listenerType, listener);
54
+    }
55
+    
56
+    /**
57
+     * Adds a new listener of the specified type to this listener list.
58
+     * 
59
+     * @param listenerType The name of the type of listener that's being added
60
+     * @param listener The listener to be added
61
+     */
62
+    public void add(final String listenerType, final Object listener) {
63
+        listeners.add(listenerType, listener);
64
+    }
65
+    
66
+    /**
67
+     * Removes the specified listener from the list of listeners for the
68
+     * specified type.
69
+     * 
70
+     * @param listenerType The type that the listener should be removed from
71
+     * @param listener The listener to be removed
72
+     */
73
+    public <T> void remove(final Class<T> listenerType, final T listener) {
74
+        listeners.remove(listenerType, listener);
75
+    }
76
+    
77
+    /**
78
+     * Removes the specified listener from the list of listeners for the
79
+     * specified type.
80
+     * 
81
+     * @param listenerType The name of the type that the listener should be
82
+     * removed from
83
+     * @param listener The listener to be removed
84
+     */
85
+    public void remove(final String listenerType, final Object listener) {
86
+        listeners.remove(listenerType, listener);
87
+    }
88
+    
89
+    /**
90
+     * Retrieves the list of listeners for the specified type.
91
+     * 
92
+     * @param listenerType The type of listener that's being retrieved
93
+     * @return A list of listeners for the specified type
94
+     */
95
+    @SuppressWarnings("unchecked")
96
+    public <T> List<T> get(final Class<T> listenerType) {
97
+        if (listeners.containsKey(listenerType)) {
98
+            return (List<T>) listeners.get(listenerType);
99
+        } else {
100
+            return new WeakList<T>();
101
+        }
102
+    }
103
+    
104
+    /**
105
+     * Retrieves the list of listeners for the specified type.
106
+     * 
107
+     * @param listenerType The type of listener to be retrieved
108
+     * @return A list of listeners for the specified type
109
+     */
110
+    public List<Object> get(final String listenerType) {
111
+        if (listeners.containsKey(listenerType)) {
112
+            return listeners.get(listenerType);
113
+        } else {
114
+            return new WeakList<Object>();
115
+        }
116
+    }
117
+
118
+}

+ 252
- 0
src/com/dmdirc/util/MapList.java 查看文件

@@ -0,0 +1,252 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import java.util.ArrayList;
26
+import java.util.Collection;
27
+import java.util.HashMap;
28
+import java.util.List;
29
+import java.util.Map;
30
+import java.util.Set;
31
+
32
+/**
33
+ * Wraps a Map&lt;S, List&lt;T&gt;&gt; with various convenience methods for
34
+ * accessing the data. Implements a Map-like interface for easier transition.
35
+ * 
36
+ * @param <S> the type of keys maintained by this map
37
+ * @param <T> the type of mapped values
38
+ * @author chris
39
+ */
40
+public class MapList<S,T> {
41
+    
42
+    /** Our internal map. */
43
+    protected final Map<S, List<T>> map;
44
+
45
+    /**
46
+     * Creates a new, empty MapList.
47
+     */
48
+    public MapList() {
49
+        map = new HashMap<S, List<T>>();
50
+    }
51
+
52
+    /**
53
+     * Creates a new MapList with the values from the specified list.
54
+     * 
55
+     * @param list The MapList whose values should be used
56
+     */
57
+    public MapList(final MapList<S,T> list) {
58
+        map = list.getMap();
59
+    }
60
+
61
+    /**
62
+     * Determines if this MapList is empty. An empty MapList is one that either
63
+     * contains no keys, or contains only keys which have no associated values.
64
+     * 
65
+     * @return True if this MapList is empty, false otherwise
66
+     */
67
+    public boolean isEmpty() {
68
+        for (List<T> list : map.values()) {
69
+            if (!list.isEmpty()) {
70
+                return false;
71
+            }
72
+        }
73
+        
74
+        return true;
75
+    }
76
+
77
+    /**
78
+     * Determines if this MapList contains the specified key.
79
+     * 
80
+     * @param key The key to look for
81
+     * @return True if this MapList contains the specified key, false otherwise
82
+     */
83
+    public boolean containsKey(final S key) {
84
+        return map.containsKey(key);
85
+    }
86
+
87
+    /**
88
+     * Determines if this MapList contains the specified value as a child of
89
+     * the specified key.
90
+     * 
91
+     * @param key The key to search under
92
+     * @param value The value to look for
93
+     * @return True if this MapList contains the specified key/value pair, 
94
+     * false otherwise
95
+     */
96
+    public boolean containsValue(final S key, final T value) {
97
+        return map.containsKey(key) && map.get(key).contains(value);
98
+    }
99
+
100
+    /**
101
+     * Retrieves the list of values associated with the specified key.
102
+     * 
103
+     * @param key The key whose values are being retrieved
104
+     * @return The values belonging to the specified key
105
+     */
106
+    public List<T> get(final S key) {
107
+        return map.get(key);
108
+    }
109
+    
110
+    /**
111
+     * Retrieves the value at the specified offset of the specified key.
112
+     * 
113
+     * @param key The key whose values are being retrieved
114
+     * @param index The index of the value to retrieve
115
+     * @return The specified value of the key
116
+     */    
117
+    public T get(final S key, final int index) {
118
+        return map.get(key).get(index);
119
+    }    
120
+    
121
+    /**
122
+     * Retrieves the list of values associated with the specified key, creating
123
+     * the key if neccessary.
124
+     * 
125
+     * @param key The key to retrieve
126
+     * @return A list of the specified key's values
127
+     */
128
+    public List<T> safeGet(final S key) {
129
+        if (!map.containsKey(key)) {
130
+            map.put(key, new ArrayList<T>());
131
+        }
132
+        
133
+        return map.get(key);
134
+    }
135
+    
136
+    /**
137
+     * Adds the specified key to the MapList.
138
+     * 
139
+     * @param key The key to be added
140
+     */
141
+    public void add(final S key) {
142
+        safeGet(key);
143
+    }    
144
+
145
+    /**
146
+     * Adds the specified value as a child of the specified key. If the key
147
+     * didn't previous exist, it is created.
148
+     * 
149
+     * @param key The key to which the value is being added
150
+     * @param value The value to be added
151
+     */
152
+    public void add(final S key, final T value) {
153
+        safeGet(key).add(value);
154
+    }
155
+
156
+    /**
157
+     * Adds the specified set of values to the specified key. If the key
158
+     * didn't previous exist, it is created.
159
+     * 
160
+     * @param key The key to which the value is being added
161
+     * @param values The values to be added
162
+     */    
163
+    public void add(final S key, final Collection<T> values) {
164
+        safeGet(key).addAll(values);
165
+    }    
166
+
167
+    /**
168
+     * Removes the specified key and all of its values.
169
+     * 
170
+     * @param key The key to remove
171
+     */    
172
+    public void remove(final S key) {
173
+        map.remove(key);
174
+    }
175
+    
176
+    /**
177
+     * Removes the specified value from all keys.
178
+     * 
179
+     * @param value The value to remove
180
+     */
181
+    public void removeFromAll(final T value) {
182
+        for (List<T> list : map.values()) {
183
+            list.remove(value);
184
+        }
185
+    }
186
+
187
+    /**
188
+     * Removes the specified value from the specified key.
189
+     * 
190
+     * @param key The key whose value is being removed
191
+     * @param value The value to be removed
192
+     */
193
+    public void remove(final S key, final T value) {
194
+        if (map.containsKey(key)) {
195
+            map.get(key).remove(value);
196
+        }
197
+    }    
198
+
199
+    /**
200
+     * Entirely clears this MapList.
201
+     */
202
+    public void clear() {
203
+        map.clear();
204
+    }
205
+    
206
+    /**
207
+     * Clears all values of the specified key.
208
+     * 
209
+     * @param key The key to be cleared
210
+     */
211
+    public void clear(final S key) {
212
+        safeGet(key).clear();
213
+    }    
214
+
215
+    /**
216
+     * Returns the set of all keys belonging to this MapList.
217
+     * 
218
+     * @return This MapList's keyset
219
+     */
220
+    public Set<S> keySet() {
221
+        return map.keySet();
222
+    }
223
+
224
+    /**
225
+     * Returns a collection of all values belonging to the specified key.
226
+     * 
227
+     * @param key The key whose values are being sought
228
+     * @return A collection of values belonging to the key
229
+     */
230
+    public Collection<T> values(final S key) {
231
+        return map.get(key);
232
+    }
233
+    
234
+    /**
235
+     * Retrieves the entry set for this MapList.
236
+     * 
237
+     * @return This MapList's entry set
238
+     */
239
+    public Set<Map.Entry<S, List<T>>> entrySet() {
240
+        return map.entrySet();
241
+    }
242
+    
243
+    /**
244
+     * Retrieves the map behind this maplist.
245
+     * 
246
+     * @return This MapList's map.
247
+     */
248
+    public Map<S, List<T>> getMap() {
249
+        return new HashMap<S, List<T>>(map);
250
+    }
251
+
252
+}

+ 56
- 0
src/com/dmdirc/util/ReturnableThread.java 查看文件

@@ -0,0 +1,56 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+/**
26
+ * Normal thread with the potential to return a value.
27
+ * 
28
+ * @param T Type to be returned
29
+ */
30
+public abstract class ReturnableThread<T> extends Thread {
31
+
32
+    /** Returnable object. */
33
+    private T value;
34
+
35
+    /** {@inheritDoc} */
36
+    @Override
37
+    public abstract void run();
38
+
39
+    /**
40
+     * Sets the returnable object.
41
+     * 
42
+     * @param value new returnable object
43
+     */
44
+    public void setObject(final T value) {
45
+        this.value = value;
46
+    }
47
+
48
+    /**
49
+     * Returns the object set by this thread.
50
+     * 
51
+     * @return Returnable object
52
+     */
53
+    public T getObject() {
54
+        return value;
55
+    }
56
+}

+ 219
- 0
src/com/dmdirc/util/RollingList.java 查看文件

@@ -0,0 +1,219 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import java.util.ArrayList;
26
+import java.util.List;
27
+
28
+/**
29
+ * Implements a "rolling list". A rolling list has a maximum capacity, and
30
+ * removes the oldest elements from the list to maintain this capacity.
31
+ * 
32
+ * @param <T> The type if items that this list contains 
33
+ * @author chris
34
+ */
35
+public class RollingList<T> {
36
+   
37
+    /** The items in this rolling list. */
38
+    private final List<T> items = new ArrayList<T>();
39
+    
40
+    /** The maximum capacity of this list. */
41
+    private final int capacity;
42
+    
43
+    /** This list's position pointer. */
44
+    private int position = 0;
45
+    
46
+    /** Whether or not to add a fake empty item to the end of this list. */
47
+    private boolean addEmpty;
48
+    /** The "empty" item to be added. */
49
+    private T empty;
50
+    
51
+    /**
52
+     * Creates a new RollingList of the specified capacity.
53
+     * 
54
+     * @param capacity The capacity of this list.
55
+     */
56
+    public RollingList(final int capacity) {
57
+        this.capacity = capacity;
58
+        this.addEmpty = false;
59
+    }
60
+
61
+    /**
62
+     * Creates a new RollingList of the specified capacity, with the specified
63
+     * "empty" element appended to the end.
64
+     * 
65
+     * @param capacity The capacity of this list.
66
+     * @param empty The "empty" element to be added
67
+     */    
68
+    public RollingList(final int capacity, final T empty) {
69
+        this.capacity = capacity;
70
+        this.addEmpty = true;
71
+        this.empty = empty;
72
+    }
73
+
74
+    /**
75
+     * Removes the specified element from this list.
76
+     * 
77
+     * @param o The object to be removed from the list.
78
+     * @return True if the list contained the specified element, false otherwise.
79
+     */
80
+    public boolean remove(final Object o) {
81
+        return items.remove(o);
82
+    }
83
+
84
+    /**
85
+     * Determines if this list is currently empty.
86
+     * 
87
+     * @return True if the list is empty, false otherwise.
88
+     */
89
+    public boolean isEmpty() {
90
+        return items.isEmpty();
91
+    }
92
+
93
+    /**
94
+     * Retrieves the item at the specified index in this list.
95
+     * 
96
+     * @param index The index to look up
97
+     * @return The item at the specified index
98
+     */
99
+    public T get(final int index) {
100
+        return items.get(index);
101
+    }
102
+
103
+    /**
104
+     * Determines if this list contains the specified object.
105
+     * 
106
+     * @param o The object to be checked
107
+     * @return True if this list contains the item, false otherwise.
108
+     */
109
+    public boolean contains(final Object o) {
110
+        return items.contains(o);
111
+    }
112
+
113
+    /**
114
+     * Clears all items from this list.
115
+     */
116
+    public void clear() {
117
+        items.clear();
118
+    }  
119
+    
120
+    /**
121
+     * Adds the specified item to this list. If the list has reached its
122
+     * maximum capacity, this method will remove elements from the start of the
123
+     * list until there is sufficient room for the new element.
124
+     * 
125
+     * @param e The element to be added to the list.
126
+     * @return True
127
+     */
128
+    public boolean add(T e) {
129
+        while (items.size() > capacity - 1) {
130
+            items.remove(0);
131
+            position--;
132
+        }
133
+        
134
+        return items.add(e);
135
+    }
136
+    
137
+    /**
138
+     * Retrieves the current position within the list.
139
+     * 
140
+     * @return This list's positional pointer
141
+     */
142
+    public int getPosition() {
143
+        return position;
144
+    }
145
+
146
+    /**
147
+     * Sets the positional pointer of this list.
148
+     * 
149
+     * @param position The new position
150
+     */
151
+    public void setPosition(int position) {
152
+        this.position = position;
153
+    }    
154
+    
155
+    /**
156
+     * Determines if there is an element after the positional pointer of the list.
157
+     * 
158
+     * @return True if there is an element, false otherwise.
159
+     */
160
+    public boolean hasNext() {
161
+        return (items.size() > position + 1) || ((items.size() > position) && addEmpty);
162
+    }
163
+    
164
+    /**
165
+     * Retrieves the element after the positional pointer of the list.
166
+     * 
167
+     * @return The next element in the list
168
+     */
169
+    public T getNext() {
170
+        if (items.size() > position + 1 || !addEmpty) {
171
+            return get(++position);
172
+        } else {
173
+            position++;
174
+            return empty;
175
+        }
176
+    }
177
+    
178
+    /**
179
+     * Determines if there is an element befpre the positional pointer of the list.
180
+     * 
181
+     * @return True if there is an element, false otherwise.
182
+     */    
183
+    public boolean hasPrevious() {
184
+        return 0 < position;
185
+    }
186
+    
187
+    /**
188
+     * Retrieves the element before the positional pointer of the list.
189
+     * 
190
+     * @return The previous element in the list
191
+     */    
192
+    public T getPrevious() {
193
+        return get(--position);
194
+    }    
195
+    
196
+    /**
197
+     * Sets the positional pointer of this list to the end.
198
+     */
199
+    public void seekToEnd() {
200
+        position = items.size();
201
+    }
202
+    
203
+    /**
204
+     * Sets the positional pointer of this list to the start.
205
+     */
206
+    public void seekToStart() {
207
+        position = 0;
208
+    }
209
+    
210
+    /**
211
+     * Retrieves a list of items that this rolling list contains.
212
+     * 
213
+     * @return A list of items in this rolling list.
214
+     */
215
+    public List<T> getList() {
216
+        return new ArrayList<T>(items);
217
+    }
218
+
219
+}

+ 52
- 0
src/com/dmdirc/util/StreamUtil.java 查看文件

@@ -0,0 +1,52 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import java.io.Closeable;
26
+import java.io.IOException;
27
+
28
+/**
29
+ * Utilities for dealing with streams.
30
+ *
31
+ * @since 0.6.3m2
32
+ * @author chris
33
+ */
34
+public abstract class StreamUtil {
35
+
36
+    /**
37
+     * Closes the stream if it is non-null, and ignores any IOExceptions
38
+     * raised by doing so.
39
+     *
40
+     * @param stream The stream to be closed
41
+     */
42
+    public static void close(final Closeable stream) {
43
+        if (stream != null) {
44
+            try {
45
+                stream.close();
46
+            } catch (IOException ex) {
47
+                // Do nothing. We don't care.
48
+            }
49
+        }
50
+    }
51
+
52
+}

+ 211
- 0
src/com/dmdirc/util/TextFile.java 查看文件

@@ -0,0 +1,211 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import java.io.BufferedReader;
26
+import java.io.BufferedWriter;
27
+import java.io.File;
28
+import java.io.FileInputStream;
29
+import java.io.FileWriter;
30
+import java.io.IOException;
31
+import java.io.InputStream;
32
+import java.io.InputStreamReader;
33
+import java.nio.charset.Charset;
34
+import java.util.ArrayList;
35
+import java.util.List;
36
+
37
+/**
38
+ * Allows reading and writing to a plain text file via a list of lines.
39
+ * 
40
+ * @author chris
41
+ */
42
+public class TextFile {
43
+    
44
+    /** The file we're dealing with. */
45
+    private File file;
46
+    
47
+    /** The input stream we're dealing with. */
48
+    private InputStream is;
49
+    
50
+    /** The lines we've read from the file. */
51
+    private List<String> lines;
52
+
53
+    /** The charset to use to read the file. */
54
+    private final Charset charset;
55
+    
56
+    /**
57
+     * Creates a new instance of TextFile for the specified file, and uses the
58
+     * default charset.
59
+     * 
60
+     * @param filename The file to be read/written
61
+     */
62
+    public TextFile(final String filename) {
63
+        this(new File(filename));
64
+    }
65
+
66
+    /**
67
+     * Creates a new instance of TextFile for the specified File, and uses the
68
+     * default charset.
69
+     * 
70
+     * @param file The file to read
71
+     */
72
+    public TextFile(final File file) {
73
+        this(file, Charset.defaultCharset());
74
+    }
75
+    
76
+    /**
77
+     * Creates a new instance of TextFile for an input stream, and uses the
78
+     * default charset.
79
+     * 
80
+     * @param is The input stream to read from
81
+     */
82
+    public TextFile(final InputStream is) {
83
+        this(is, Charset.defaultCharset());
84
+    }
85
+
86
+    /**
87
+     * Creates a new instance of TextFile for the specified File, which is to
88
+     * be read using the specified charset.
89
+     *
90
+     * @param file The file to read
91
+     * @param charset The charset to read the file in
92
+     * @since 0.6.3m1
93
+     */
94
+    public TextFile(final File file, final Charset charset) {
95
+        this.file = file;
96
+        this.charset = charset;
97
+    }
98
+
99
+    /**
100
+     * Creates a new instance of TextFile for an input stream, which is to
101
+     * be read using the specified charset.
102
+     *
103
+     * @param is The input stream to read from
104
+     * @param charset The charset to read the file in
105
+     * @since 0.6.3m1
106
+     */
107
+    public TextFile(final InputStream is, final Charset charset) {
108
+        this.is = is;
109
+        this.charset = charset;
110
+    }
111
+    
112
+    /**
113
+     * Retrieves the contents of the file as a list of lines. If getLines() or
114
+     * readLines() has previously been called, a cached version is returned.
115
+     * 
116
+     * @return A list of lines in the file
117
+     * @throws IOException if an I/O exception occurs
118
+     */
119
+    public List<String> getLines() throws IOException {
120
+        if (lines == null) {
121
+            readLines();
122
+        }
123
+        
124
+        return lines;
125
+    }
126
+    
127
+    /**
128
+     * Reads the contents of the file into this TextFile's line cache.
129
+     * 
130
+     * @throws IOException If an I/O exception occurs
131
+     */
132
+    public void readLines() throws IOException {
133
+        BufferedReader reader = null;
134
+        InputStreamReader inputReader = null;
135
+        InputStream inputStream = null;
136
+
137
+        try {
138
+            inputStream = file == null ? is : new FileInputStream(file);
139
+            inputReader = new InputStreamReader(inputStream, charset);
140
+            reader = new BufferedReader(inputReader);
141
+            lines = new ArrayList<String>();
142
+
143
+            String line;
144
+
145
+            while ((line = reader.readLine()) != null) {
146
+                lines.add(line);
147
+            }
148
+        } finally {
149
+            StreamUtil.close(reader);
150
+            StreamUtil.close(inputReader);
151
+            StreamUtil.close(inputStream);
152
+        }
153
+    }
154
+    
155
+    /**
156
+     * Determines if this file is writable or not.
157
+     * 
158
+     * @return True if the file is writable, false otherwise
159
+     */
160
+    public boolean isWritable() {
161
+        return file != null;
162
+    }
163
+    
164
+    /**
165
+     * Writes the specified list of lines to the file.
166
+     * 
167
+     * @param lines The lines to be written
168
+     * @throws IOException if an I/O exception occurs
169
+     */
170
+    public void writeLines(final List<String> lines) throws IOException {
171
+        if (file == null) {
172
+            throw new UnsupportedOperationException("Cannot write to TextFile "
173
+                    + "opened with an InputStream");
174
+        }
175
+        
176
+        BufferedWriter writer = null;
177
+
178
+        try {
179
+            writer = new BufferedWriter(new FileWriter(file));
180
+        
181
+            for (String line : lines) {
182
+                writer.write(line);
183
+                writer.newLine();
184
+            }
185
+        } finally {
186
+            StreamUtil.close(writer);
187
+        }
188
+    }
189
+
190
+    /**
191
+     * Retrieves the File for this TextFile, if there is one.
192
+     * 
193
+     * @return This TextFile's file, or null
194
+     */
195
+    public File getFile() {
196
+        return file;
197
+    }
198
+    
199
+    /**
200
+     * Deletes the file associated with this textfile, if there is one.
201
+     */
202
+    public void delete() {
203
+        if (file == null) {
204
+            throw new UnsupportedOperationException("Cannot delete TextFile "
205
+                    + "opened with an InputStream");
206
+        }
207
+        
208
+        file.delete();
209
+    }
210
+
211
+}

+ 252
- 0
src/com/dmdirc/util/WeakList.java 查看文件

@@ -0,0 +1,252 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import java.lang.ref.WeakReference;
26
+import java.util.ArrayList;
27
+import java.util.Collection;
28
+import java.util.Iterator;
29
+import java.util.List;
30
+import java.util.ListIterator;
31
+
32
+/**
33
+ * Implements a list of weak references. The weak references (and subsequent
34
+ * garbage collection) are handled transparently.
35
+ * 
36
+ * @param <T> The type of object that this list will contain.
37
+ * @author chris
38
+ */
39
+public class WeakList<T> implements List<T> {
40
+
41
+    /** The items in this list. */
42
+    private final List<WeakReference<T>> list = new ArrayList<WeakReference<T>>();
43
+
44
+    /**
45
+     * Creates a new instance of WeakList.
46
+     */
47
+    public WeakList() {
48
+        super();
49
+    }
50
+
51
+    /**
52
+     * Removes any entries from the list that have been GC'd.
53
+     */
54
+    private void cleanUp() {
55
+        for (int i = 0; i < list.size(); i++) {
56
+            if (list.get(i).get() == null) {
57
+                list.remove(i--);
58
+            }
59
+        }
60
+    }
61
+
62
+    /**
63
+     * Dereferences the specified list of WeakReferences to get a plain List.
64
+     * 
65
+     * @param list The list to be dereferenced
66
+     * @return A list containing the items referenced by the specified list
67
+     */
68
+    private List<T> dereferenceList(final List<WeakReference<T>> list) {
69
+        final List<T> res = new ArrayList<T>();
70
+
71
+        for (WeakReference<T> item : list) {
72
+            if (item.get() != null) {
73
+                res.add(item.get());
74
+            }
75
+        }
76
+
77
+        return res;
78
+    }
79
+
80
+    /**
81
+     * Creates a new collection of weak references to elements in the specified
82
+     * collection.
83
+     * 
84
+     * @param c The collection whose elements should be referenced
85
+     * @return A copy of the specified collection, with each item wrapped in
86
+     * a weak reference.
87
+     */
88
+    @SuppressWarnings(value = "unchecked")
89
+    private Collection<WeakReference<T>> referenceCollection(final Collection<?> c) {
90
+        final Collection<WeakReference<T>> res = new ArrayList<WeakReference<T>>();
91
+
92
+        for (Object item : c) {
93
+            res.add(new EquatableWeakReference(item));
94
+        }
95
+
96
+        return res;
97
+    }
98
+
99
+    /** {@inheritDoc} */
100
+    @Override
101
+    public int size() {
102
+        cleanUp();
103
+
104
+        return list.size();
105
+    }
106
+
107
+    /** {@inheritDoc} */
108
+    @Override
109
+    public boolean isEmpty() {
110
+        cleanUp();
111
+
112
+        return list.isEmpty();
113
+    }
114
+
115
+    /** {@inheritDoc} */
116
+    @Override @SuppressWarnings("unchecked")
117
+    public boolean contains(final Object o) {
118
+        return list.contains(new EquatableWeakReference(o));
119
+    }
120
+
121
+    /** {@inheritDoc} */
122
+    @Override
123
+    public Iterator<T> iterator() {
124
+        return dereferenceList(list).iterator();
125
+    }
126
+
127
+    /** {@inheritDoc} */
128
+    @Override
129
+    public Object[] toArray() {
130
+        return dereferenceList(list).toArray();
131
+    }
132
+
133
+    /** {@inheritDoc} */
134
+    @Override
135
+    public <T> T[] toArray(final T[] a) {
136
+        return dereferenceList(list).toArray(a);
137
+    }
138
+
139
+    /** {@inheritDoc} */
140
+    @Override
141
+    public boolean add(final T e) {
142
+        return list.add(new EquatableWeakReference<T>(e));
143
+    }
144
+
145
+    /** {@inheritDoc} */
146
+    @Override @SuppressWarnings(value = "unchecked")
147
+    public boolean remove(final Object o) {
148
+        return list.remove(new EquatableWeakReference(o));
149
+    }
150
+
151
+    /** {@inheritDoc} */
152
+    @Override
153
+    public boolean containsAll(final Collection<?> c) {
154
+        return dereferenceList(list).containsAll(c);
155
+    }
156
+
157
+    /** {@inheritDoc} */
158
+    @Override
159
+    public boolean addAll(final Collection<? extends T> c) {
160
+        return list.addAll(referenceCollection(c));
161
+    }
162
+
163
+    /** {@inheritDoc} */
164
+    @Override
165
+    public boolean addAll(final int index, final Collection<? extends T> c) {
166
+        return list.addAll(index, referenceCollection(c));
167
+    }
168
+
169
+    /** {@inheritDoc} */
170
+    @Override
171
+    public boolean removeAll(final Collection<?> c) {
172
+        return list.removeAll(referenceCollection(c));
173
+    }
174
+
175
+    /** {@inheritDoc} */
176
+    @Override
177
+    public boolean retainAll(final Collection<?> c) {
178
+        return list.retainAll(referenceCollection(c));
179
+    }
180
+
181
+    /** {@inheritDoc} */
182
+    @Override
183
+    public void clear() {
184
+        list.clear();
185
+    }
186
+
187
+    /** {@inheritDoc} */
188
+    @Override
189
+    public T get(final int index) {
190
+        cleanUp();
191
+
192
+        return list.get(index).get();
193
+    }
194
+
195
+    /** {@inheritDoc} */
196
+    @Override
197
+    public T set(final int index, final T element) {
198
+        list.set(index, new EquatableWeakReference<T>(element));
199
+
200
+        return element;
201
+    }
202
+
203
+    /** {@inheritDoc} */
204
+    @Override
205
+    public void add(final int index, final T element) {
206
+        list.add(index, new EquatableWeakReference<T>(element));
207
+    }
208
+
209
+    /** {@inheritDoc} */
210
+    @Override
211
+    public T remove(final int index) {
212
+        return list.remove(index).get();
213
+    }
214
+
215
+    /** {@inheritDoc} */
216
+    @Override @SuppressWarnings(value = "unchecked")
217
+    public int indexOf(final Object o) {
218
+        cleanUp();
219
+
220
+        return list.indexOf(o);
221
+    }
222
+
223
+    /** {@inheritDoc} */
224
+    @Override @SuppressWarnings(value = "unchecked")
225
+    public int lastIndexOf(final Object o) {
226
+        cleanUp();
227
+
228
+        return list.lastIndexOf(o);
229
+    }
230
+
231
+    /** {@inheritDoc} */
232
+    @Override
233
+    public ListIterator<T> listIterator() {
234
+        cleanUp();
235
+
236
+        return dereferenceList(list).listIterator();
237
+    }
238
+
239
+    /** {@inheritDoc} */
240
+    @Override
241
+    public ListIterator<T> listIterator(final int index) {
242
+        cleanUp();
243
+
244
+        return dereferenceList(list).listIterator(index);
245
+    }
246
+
247
+    /** {@inheritDoc} */
248
+    @Override
249
+    public List<T> subList(final int fromIndex, final int toIndex) {
250
+        return dereferenceList(list.subList(fromIndex, toIndex));
251
+    }
252
+}

+ 54
- 0
src/com/dmdirc/util/WeakMapList.java 查看文件

@@ -0,0 +1,54 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import java.util.List;
26
+
27
+/**
28
+ * Wraps a Map&lt;S, List&lt;T&gt;&gt; with various convenience methods for
29
+ * accessing the data. Implements a Map-like interface for easier transition.
30
+ * This implementation uses WeakLists (i.e., lists of weak references) - all
31
+ * references to values are wrapped in WeakReferences.
32
+ * 
33
+ * @param <S> the type of keys maintained by this map
34
+ * @param <T> the type of mapped values
35
+ * @author chris
36
+ */
37
+public class WeakMapList<S,T> extends MapList<S,T> {
38
+    
39
+    /**
40
+     * Retrieves the list of values associated with the specified key, creating
41
+     * the key if neccessary.
42
+     * 
43
+     * @param key The key to retrieve
44
+     * @return A list of the specified key's values
45
+     */
46
+    @Override
47
+    public List<T> safeGet(final S key) {
48
+        if (!map.containsKey(key)) {
49
+            map.put(key, new WeakList<T>());
50
+        }
51
+        
52
+        return map.get(key);
53
+    }
54
+}

+ 248
- 0
test/com/dmdirc/addons/ConfigFileTest.java 查看文件

@@ -0,0 +1,248 @@
1
+
2
+/*
3
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in
13
+ * all copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+
24
+package com.dmdirc.util;
25
+
26
+import java.io.File;
27
+import java.io.FileNotFoundException;
28
+import java.io.IOException;
29
+import java.util.HashMap;
30
+import java.util.Map;
31
+
32
+import org.junit.Before;
33
+import org.junit.Test;
34
+import static org.junit.Assert.*;
35
+
36
+public class ConfigFileTest {
37
+    
38
+    private ConfigFile cf;
39
+    
40
+    @Before
41
+    public void setUp() throws Exception {
42
+        cf = new ConfigFile(getClass().getClassLoader().
43
+                    getResourceAsStream("com/dmdirc/util/test2.txt"));
44
+    }    
45
+
46
+    @Test
47
+    public void testRead() {
48
+        boolean err = false;
49
+        
50
+        try {
51
+            cf.read(); 
52
+        } catch (FileNotFoundException ex) {
53
+            err = true;
54
+        } catch (IOException ex) {
55
+            err = true;
56
+        } catch (InvalidConfigFileException ex) {
57
+            err = true;
58
+        }
59
+        
60
+        assertFalse(err);
61
+    }
62
+    
63
+    @Test
64
+    public void testDomains() {
65
+        testRead();
66
+        assertTrue(cf.hasDomain("keysections"));
67
+        assertTrue(cf.hasDomain("section alpha"));
68
+        assertTrue(cf.hasDomain("section one point one"));
69
+        assertTrue(cf.hasDomain("section one"));
70
+        assertFalse(cf.hasDomain("random domain"));
71
+    }
72
+    
73
+    @Test
74
+    public void testKeyDomains() {
75
+        testRead();
76
+        assertTrue(cf.isKeyDomain("section one"));
77
+        assertFalse(cf.isKeyDomain("section one point one"));
78
+        assertFalse(cf.isKeyDomain("section two"));
79
+    }
80
+    
81
+    @Test
82
+    public void testFlatDomains() {
83
+        testRead();
84
+        assertTrue(cf.isFlatDomain("keysections"));
85
+        assertTrue(cf.isFlatDomain("section alpha"));
86
+        assertTrue(cf.isFlatDomain("section one point one"));
87
+        assertFalse(cf.isFlatDomain("section one"));
88
+        assertFalse(cf.hasDomain("random domain"));        
89
+    }
90
+    
91
+    @Test
92
+    public void testFlatDomainContents() {
93
+        testRead();
94
+        assertEquals(2, cf.getFlatDomain("section alpha").size());
95
+        assertEquals("line 1", cf.getFlatDomain("section alpha").get(0));
96
+        assertEquals("line 2", cf.getFlatDomain("section alpha").get(1));
97
+    }
98
+    
99
+    @Test
100
+    public void testKeyDomainContents() {
101
+        testRead();
102
+        assertEquals(3, cf.getKeyDomain("section one").size());
103
+        assertEquals("one", cf.getKeyDomain("section one").get("1"));
104
+        assertEquals("two", cf.getKeyDomain("section one").get("2"));
105
+        assertEquals("three", cf.getKeyDomain("section one").get("3"));
106
+    }
107
+    
108
+    @Test
109
+    public void testColons() throws IOException, InvalidConfigFileException {
110
+        final File file = File.createTempFile("DMDirc.unittest", null);
111
+        ConfigFile config = new ConfigFile(file);
112
+        Map<String, String> data = new HashMap<String, String>();
113
+        data.put("test1", "hello");
114
+        data.put("test:2", "hello");
115
+        data.put("test3", "hello:");
116
+        config.addDomain("test", data);
117
+        config.write();
118
+        
119
+        config = new ConfigFile(file);
120
+        config.read();
121
+        
122
+        assertTrue(config.isKeyDomain("test"));
123
+        data = config.getKeyDomain("test");
124
+        assertEquals("hello", data.get("test1"));
125
+        assertEquals("hello", data.get("test:2"));
126
+        assertEquals("hello:", data.get("test3"));
127
+    }
128
+    
129
+    @Test
130
+    public void testEquals() throws IOException, InvalidConfigFileException {
131
+        final File file = File.createTempFile("DMDirc.unittest", null);
132
+        ConfigFile config = new ConfigFile(file);
133
+        Map<String, String> data = new HashMap<String, String>();
134
+        data.put("test1", "hello");
135
+        data.put("test=2", "hello");
136
+        data.put("test3", "hello=");
137
+        config.addDomain("test", data);
138
+        config.write();
139
+        
140
+        config = new ConfigFile(file);
141
+        config.read();
142
+        
143
+        assertTrue(config.isKeyDomain("test"));
144
+        data = config.getKeyDomain("test");
145
+        assertEquals("hello", data.get("test1"));
146
+        assertEquals("hello", data.get("test=2"));
147
+        assertEquals("hello=", data.get("test3"));
148
+    }
149
+    
150
+    @Test
151
+    public void testNewlines() throws IOException, InvalidConfigFileException {
152
+        final File file = File.createTempFile("DMDirc.unittest", null);
153
+        ConfigFile config = new ConfigFile(file);
154
+        Map<String, String> data = new HashMap<String, String>();
155
+        data.put("test1", "hello");
156
+        data.put("test2", "hello\ngoodbye");
157
+        data.put("test3", "hello\n");
158
+        data.put("test4", "hello\r\ngoodbye");
159
+        config.addDomain("test", data);
160
+        config.write();
161
+        
162
+        config = new ConfigFile(file);
163
+        config.read();
164
+        
165
+        assertTrue(config.isKeyDomain("test"));
166
+        data = config.getKeyDomain("test");
167
+        assertEquals("hello", data.get("test1"));
168
+        assertEquals("hello\ngoodbye", data.get("test2"));
169
+        assertEquals("hello\n", data.get("test3"));
170
+        assertEquals("hello\r\ngoodbye", data.get("test4"));
171
+    }
172
+    
173
+    @Test
174
+    public void testBackslash() throws IOException, InvalidConfigFileException {
175
+        final File file = File.createTempFile("DMDirc.unittest", null);
176
+        ConfigFile config = new ConfigFile(file);
177
+        Map<String, String> data = new HashMap<String, String>();
178
+        data.put("test1", "hello\\");
179
+        data.put("test2", "\\nhello");
180
+        data.put("test3\\", "hello");
181
+        config.addDomain("test", data);
182
+        config.write();
183
+        
184
+        config = new ConfigFile(file);
185
+        config.read();
186
+        
187
+        assertTrue(config.isKeyDomain("test"));
188
+        data = config.getKeyDomain("test");
189
+        assertEquals("hello\\", data.get("test1"));
190
+        assertEquals("\\nhello", data.get("test2"));
191
+        assertEquals("hello", data.get("test3\\"));
192
+    }
193
+    
194
+    @Test
195
+    public void testHash() throws IOException, InvalidConfigFileException {
196
+        final File file = File.createTempFile("DMDirc.unittest", null);
197
+        ConfigFile config = new ConfigFile(file);
198
+        Map<String, String> data = new HashMap<String, String>();
199
+        data.put("test1#", "hello");
200
+        data.put("#test2", "hello");
201
+        data.put("test3", "#hello");
202
+        config.addDomain("test", data);
203
+        config.write();
204
+        
205
+        config = new ConfigFile(file);
206
+        config.read();
207
+        
208
+        assertTrue(config.isKeyDomain("test"));
209
+        data = config.getKeyDomain("test");
210
+        assertEquals("hello", data.get("test1#"));
211
+        assertEquals("hello", data.get("#test2"));
212
+        assertEquals("#hello", data.get("test3"));
213
+    }    
214
+    
215
+    @Test
216
+    public void testEscape() {
217
+        final String input = "blah blah\\foo\r\nbar=:";
218
+        final String output = "blah blah\\\\foo\\r\\nbar\\=\\:";
219
+        assertEquals(output, ConfigFile.escape(input));
220
+    }
221
+    
222
+    @Test
223
+    public void testUnescape() {
224
+        final String input = "blah blah\\foo\r\nbar=:";
225
+        assertEquals(input, ConfigFile.unescape(ConfigFile.escape(input)));
226
+    }
227
+    
228
+    @Test
229
+    public void testDelete() throws IOException {
230
+        final File file = File.createTempFile("DMDirc_unittest", null);
231
+        ConfigFile config = new ConfigFile(file);
232
+        config.write();
233
+        assertTrue(file.exists());
234
+        config.delete();
235
+        assertFalse(file.exists());
236
+    }
237
+    
238
+    @Test
239
+    public void testDuplicateKeys() throws IOException, InvalidConfigFileException {
240
+        final ConfigFile file = new ConfigFile(getClass().getResourceAsStream("test2.txt"));
241
+        file.read();
242
+        
243
+        assertTrue(file.isKeyDomain("section one"));
244
+        assertEquals(3, file.getKeyDomain("section one").size());
245
+        assertTrue(file.isFlatDomain("section one point one"));
246
+    }
247
+
248
+}

+ 65
- 0
test/com/dmdirc/addons/DoubleMapTest.java 查看文件

@@ -0,0 +1,65 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import org.junit.Test;
26
+import static org.junit.Assert.*;
27
+
28
+public class DoubleMapTest {
29
+
30
+    @Test
31
+    public void testPut() {
32
+        final DoubleMap<String, String> dm = new DoubleMap<String, String>();
33
+        dm.put("a", "b");
34
+        
35
+        assertEquals(1, dm.keySet().size());
36
+        assertEquals(1, dm.valueSet().size());
37
+        assertTrue(dm.keySet().contains("a"));
38
+        assertTrue(dm.valueSet().contains("b"));
39
+    }
40
+    
41
+    @Test(expected=NullPointerException.class)
42
+    public void testPutNull1() {
43
+        final DoubleMap<String, String> dm = new DoubleMap<String, String>();
44
+        dm.put(null, "b");
45
+    }
46
+    
47
+    @Test(expected=NullPointerException.class)
48
+    public void testPutNull2() {
49
+        final DoubleMap<String, String> dm = new DoubleMap<String, String>();
50
+        dm.put("a", null);
51
+    }    
52
+    
53
+    @Test
54
+    public void testGet() {
55
+        final DoubleMap<String, String> dm = new DoubleMap<String, String>();
56
+        dm.put("a", "b");
57
+        dm.put("b", "c");
58
+        dm.put("c", "a");
59
+        
60
+        assertEquals("b", dm.getValue("a"));
61
+        assertEquals("b", dm.getKey("c"));
62
+        assertEquals("c", dm.getKey("a"));
63
+    }    
64
+
65
+}

+ 51
- 0
test/com/dmdirc/addons/EquatableWeakReferenceTest.java 查看文件

@@ -0,0 +1,51 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+package com.dmdirc.util;
23
+
24
+import java.lang.ref.Reference;
25
+import java.lang.ref.WeakReference;
26
+import org.junit.Test;
27
+import static org.junit.Assert.*;
28
+
29
+public class EquatableWeakReferenceTest {
30
+
31
+    @Test
32
+    public void testEquals() {
33
+        final Object myObject = "moo";
34
+        final Reference<Object> myRef = new WeakReference<Object>(myObject);
35
+        final EquatableWeakReference<Object> ewf = new EquatableWeakReference<Object>(myObject);
36
+
37
+        assertTrue(ewf.equals(myObject));
38
+        assertTrue(ewf.equals(myRef));
39
+        assertFalse(ewf.equals("bar"));
40
+        assertFalse(ewf.equals(new WeakReference<Object>("bar")));
41
+    }
42
+
43
+    @Test
44
+    public void testHashCode() {
45
+        final Object myObject = "moo";
46
+        final EquatableWeakReference<Object> ewf = new EquatableWeakReference<Object>(myObject);
47
+        
48
+        assertEquals(myObject.hashCode(), ewf.hashCode());
49
+    }
50
+
51
+}

+ 36
- 0
test/com/dmdirc/addons/InvalidConfigFileExceptionTest.java 查看文件

@@ -0,0 +1,36 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+package com.dmdirc.util;
23
+
24
+import org.junit.Test;
25
+import static org.junit.Assert.*;
26
+
27
+public class InvalidConfigFileExceptionTest {
28
+
29
+    @Test
30
+    public void testMessage() {
31
+        final InvalidConfigFileException iae = new InvalidConfigFileException("message");
32
+        
33
+        assertEquals("message", iae.getMessage());
34
+    }
35
+
36
+}

+ 146
- 0
test/com/dmdirc/addons/MapListTest.java 查看文件

@@ -0,0 +1,146 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import java.util.ArrayList;
26
+import java.util.List;
27
+import org.junit.Test;
28
+import static org.junit.Assert.*;
29
+
30
+public class MapListTest {
31
+
32
+    @Test
33
+    public void testIsEmpty() {
34
+        final MapList<String, String> test = new MapList<String, String>();
35
+        assertTrue(test.isEmpty());
36
+
37
+        test.add("a", "b");
38
+        assertFalse(test.isEmpty());
39
+        test.removeFromAll("b");
40
+        assertTrue(test.isEmpty());
41
+    }
42
+    
43
+    @Test
44
+    public void testAddCollection() {
45
+        final MapList<String, String> test = new MapList<String, String>();
46
+        final List<String> testList = new ArrayList<String>();
47
+        testList.add("d");
48
+        testList.add("e");
49
+        test.add("key", testList);
50
+        
51
+        assertTrue(test.containsKey("key"));
52
+        assertTrue(test.containsValue("key", "d"));
53
+        assertTrue(test.containsValue("key", "e"));
54
+    }
55
+    
56
+    @Test
57
+    public void testClear() {
58
+        final MapList<String, String> test = new MapList<String, String>();
59
+        test.add("a", "b");
60
+        test.add("d", "e");
61
+        test.clear();
62
+        assertTrue(test.isEmpty());
63
+    }
64
+    
65
+    @Test
66
+    public void testClearKey() {
67
+        final MapList<String, String> test = new MapList<String, String>();
68
+        test.add("a", "b");
69
+        test.add("d", "e");
70
+        test.clear("a");
71
+        assertTrue(test.values("a").isEmpty());
72
+        assertFalse(test.isEmpty());
73
+    }
74
+    
75
+    @Test
76
+    public void testRemove() {
77
+        final MapList<String, String> test = new MapList<String, String>();
78
+        test.add("a", "b");
79
+        test.add("d", "e");
80
+        test.remove("z", "b");
81
+        
82
+        assertEquals(2, test.keySet().size());
83
+        assertEquals(1, test.values("a").size());
84
+        assertEquals(1, test.values("d").size());
85
+        
86
+        test.remove("a", "b");
87
+        assertEquals(2, test.keySet().size());
88
+        assertEquals(0, test.values("a").size());
89
+        assertEquals(1, test.values("d").size());        
90
+    }    
91
+    
92
+    @Test
93
+    public void testKeySet() {
94
+        final MapList<String, String> test = new MapList<String, String>();
95
+        test.add("a", "b");
96
+        test.add("d", "e");
97
+        assertEquals(2, test.keySet().size());
98
+        assertTrue(test.keySet().contains("a"));
99
+        assertTrue(test.keySet().contains("d"));
100
+    }    
101
+
102
+    @Test
103
+    public void testContainsKey() {
104
+        final MapList<String, String> test = new MapList<String, String>();
105
+        test.add("a", "b");
106
+        assertTrue(test.containsKey("a"));
107
+    }
108
+
109
+    @Test
110
+    public void testContainsValue() {
111
+        final MapList<String, String> test = new MapList<String, String>();
112
+        test.add("a", "b");
113
+        assertTrue(test.containsValue("a", "b"));
114
+    }
115
+
116
+    @Test
117
+    public void testGet() {
118
+        final MapList<String, String> test = new MapList<String, String>();
119
+        test.add("a", "b");
120
+        assertEquals(1, test.get("a").size());
121
+        assertEquals("b", test.get("a").get(0));
122
+        assertEquals("b", test.get("a", 0));
123
+    }
124
+    
125
+    @Test
126
+    public void testInherit() {
127
+        final MapList<String, String> test1 = new MapList<String, String>();
128
+        test1.add("a", "b");
129
+        
130
+        final MapList<String, String> test2 = new MapList<String, String>(test1);
131
+        assertEquals(1, test2.get("a").size());
132
+        assertEquals("b", test2.get("a").get(0));
133
+        assertEquals("b", test2.get("a", 0));        
134
+    }
135
+    
136
+    @Test
137
+    public void testGetMap() {
138
+        final MapList<String, String> test1 = new MapList<String, String>();
139
+        test1.add("a", "b");
140
+        assertNotSame(test1.getMap(), test1.getMap());
141
+        
142
+        final MapList<String, String> test2 = new MapList<String, String>(test1);
143
+        assertEquals(test1.getMap(), test2.getMap());
144
+    }    
145
+
146
+}

+ 120
- 0
test/com/dmdirc/addons/RollingListTest.java 查看文件

@@ -0,0 +1,120 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import org.junit.Test;
26
+import static org.junit.Assert.*;
27
+
28
+public class RollingListTest {
29
+
30
+    @Test
31
+    public void testIsEmpty() {
32
+        final RollingList<String> rl = new RollingList<String>(1);
33
+        assertTrue(rl.isEmpty());
34
+        assertTrue(rl.getList().isEmpty());
35
+        
36
+        rl.add("Foo");
37
+        assertFalse(rl.isEmpty());
38
+        assertFalse(rl.getList().isEmpty());
39
+    }
40
+    
41
+    @Test
42
+    public void testRolling() {
43
+        final RollingList<String> rl = new RollingList<String>(1);
44
+        
45
+        rl.add("Foo");
46
+        rl.add("Bar");
47
+        rl.add("Baz");
48
+
49
+        assertEquals("Baz", rl.get(0));
50
+        assertEquals(1, rl.getList().size());
51
+        assertFalse(rl.contains("Bar"));
52
+    }
53
+    
54
+    @Test
55
+    public void testClear() {
56
+        final RollingList<String> rl = new RollingList<String>(3);
57
+        
58
+        rl.add("Foo");
59
+        rl.add("Bar");
60
+        rl.add("Baz");
61
+        rl.clear();
62
+        
63
+        assertTrue(rl.isEmpty());
64
+        assertTrue(rl.getList().isEmpty());
65
+    }
66
+    
67
+    @Test
68
+    public void testPositions() {
69
+        final RollingList<String> rl = new RollingList<String>(3);
70
+        
71
+        rl.add("Foo");
72
+        rl.add("Bar");
73
+        rl.add("Baz");
74
+        
75
+        assertEquals(0, rl.getPosition());
76
+        
77
+        rl.seekToEnd();
78
+        assertEquals(3, rl.getPosition());
79
+        
80
+        rl.seekToStart();
81
+        assertEquals(0, rl.getPosition());
82
+    }
83
+    
84
+    @Test
85
+    public void testPrevNext() {
86
+        final RollingList<String> rl = new RollingList<String>(3);
87
+        
88
+        rl.add("Foo");
89
+        rl.add("Bar");
90
+        rl.add("Baz");
91
+        
92
+        assertEquals("Bar", rl.getNext());
93
+        assertEquals("Baz", rl.getNext());
94
+        assertFalse(rl.hasNext());
95
+        assertTrue(rl.hasPrevious());
96
+        
97
+        assertEquals("Bar", rl.getPrevious());
98
+        assertEquals("Foo", rl.getPrevious());
99
+        assertFalse(rl.hasPrevious());
100
+        assertTrue(rl.hasNext());
101
+    }
102
+    
103
+    @Test
104
+    public void testEmpty() {
105
+        final RollingList<String> rl = new RollingList<String>(1, "Meep");
106
+        rl.add("Foo");
107
+        
108
+        assertEquals("Meep", rl.getNext());
109
+        assertFalse(rl.hasNext());
110
+        
111
+        rl.add("Bar");
112
+        
113
+        // The position moves when adding
114
+        assertTrue(rl.hasNext());
115
+        assertFalse(rl.hasPrevious());
116
+        assertEquals("Meep", rl.getNext());
117
+        assertEquals("Bar", rl.getPrevious());
118
+    }
119
+
120
+}

+ 104
- 0
test/com/dmdirc/addons/TextFileTest.java 查看文件

@@ -0,0 +1,104 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import java.io.File;
26
+import java.io.FileNotFoundException;
27
+import java.io.IOException;
28
+import java.net.URISyntaxException;
29
+import java.util.Arrays;
30
+import java.util.List;
31
+
32
+import org.junit.Test;
33
+import static org.junit.Assert.*;
34
+
35
+public class TextFileTest {
36
+    
37
+    private static File tfile;
38
+
39
+    @Test
40
+    public void testGetLines() throws IOException {
41
+        final TextFile file =
42
+                new TextFile(getClass().getClassLoader().
43
+                getResource("com/dmdirc/util/test1.txt").openStream());
44
+        final List<String> lines = file.getLines();
45
+
46
+        assertEquals(7, lines.size());
47
+        assertEquals("Line 1", lines.get(0));
48
+    }
49
+    
50
+    @Test
51
+    public void testGetLines2() throws IOException {
52
+        final TextFile file =
53
+                new TextFile(getClass().getClassLoader().
54
+                getResource("com/dmdirc/util/test1.txt").openStream());
55
+        final List<String> lines = file.getLines();
56
+
57
+        assertEquals(7, lines.size());
58
+        assertEquals("Line 1", lines.get(0));
59
+    }
60
+    
61
+    @Test
62
+    public void testWrite() throws IOException {
63
+        tfile = File.createTempFile("dmdirc_unit_test", null);
64
+        TextFile file = new TextFile(tfile);
65
+        
66
+        final List<String> lines = Arrays.asList(new String[]{
67
+            "hello", "this is a test", "meep"
68
+        });
69
+        
70
+        file.writeLines(lines);
71
+        
72
+        file = new TextFile(tfile);
73
+        final List<String> newLines = file.getLines();
74
+        
75
+        assertEquals(lines, newLines);
76
+    }
77
+    
78
+    @Test(expected=UnsupportedOperationException.class)
79
+    public void testIllegalWrite() throws IOException {
80
+        final TextFile file =
81
+                new TextFile(getClass().getClassLoader().
82
+                getResource("com/dmdirc/util/test1.txt").openStream());
83
+        file.writeLines(Arrays.asList(new String[]{
84
+            "hello", "this is a test", "meep"
85
+        }));
86
+    }
87
+    
88
+    @Test(expected=UnsupportedOperationException.class)
89
+    public void testIllegalDelete() throws IOException {
90
+        final TextFile file =
91
+                new TextFile(getClass().getClassLoader().
92
+                getResource("com/dmdirc/util/test1.txt").openStream());
93
+        file.delete();
94
+    }
95
+    
96
+    @Test
97
+    public void testDelete() {
98
+        assertTrue(tfile.exists());
99
+        TextFile file = new TextFile(tfile);
100
+        file.delete();
101
+        assertFalse(tfile.exists());
102
+    }
103
+    
104
+}

+ 50
- 0
test/com/dmdirc/addons/WeakListTest.java 查看文件

@@ -0,0 +1,50 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import org.junit.Test;
26
+import static org.junit.Assert.*;
27
+
28
+public class WeakListTest {
29
+
30
+    @Test
31
+    public void testBasics() {
32
+        final WeakList<String> test = new WeakList<String>();
33
+        assertTrue(test.isEmpty());
34
+        
35
+        test.add("abcdef");
36
+        test.add("123");
37
+        
38
+        assertEquals(2, test.size());
39
+        assertTrue(test.get(0).equals("abcdef"));
40
+        assertTrue(test.contains("123"));
41
+        assertFalse(test.isEmpty());
42
+        
43
+        test.remove("abcdef");
44
+        assertFalse(test.contains("abcdef"));
45
+        
46
+        test.remove("123");
47
+        assertTrue(test.isEmpty());
48
+    }
49
+
50
+}

+ 7
- 0
test/com/dmdirc/addons/test1.txt 查看文件

@@ -0,0 +1,7 @@
1
+Line 1
2
+Line 2
3
+Line 3
4
+Line 4
5
+Line 5
6
+Line 6
7
+Line 7

+ 21
- 0
test/com/dmdirc/addons/test2.txt 查看文件

@@ -0,0 +1,21 @@
1
+# This is a DMDirc configuration file.
2
+# Written on: Mon Dec 17 23:32:19 GMT 2007
3
+
4
+# This section indicates which sections below take key/value
5
+# pairs, rather than a simple list. It should be placed above
6
+# any sections that take key/values.
7
+
8
+keysections:
9
+  section one
10
+
11
+section alpha:
12
+  line 1
13
+  line 2
14
+
15
+section one point one:
16
+  line 1
17
+
18
+section one:
19
+  1=one
20
+  2=two
21
+  3=three

+ 25
- 0
test/com/dmdirc/addons/test3.txt 查看文件

@@ -0,0 +1,25 @@
1
+# This is a DMDirc configuration file.
2
+# Written on: Mon Dec 17 23:32:19 GMT 2007
3
+
4
+# This section indicates which sections below take key/value
5
+# pairs, rather than a simple list. It should be placed above
6
+# any sections that take key/values.
7
+
8
+keysections:
9
+  section one
10
+
11
+section alpha:
12
+  line 1
13
+  line 2
14
+
15
+section one point one:
16
+  line 1
17
+
18
+section one:
19
+  1=one
20
+  2=two
21
+  3=three
22
+
23
+section one:
24
+
25
+section one point one:

Loading…
取消
儲存