Browse Source

Rework how config sources handle invalid and disabled settings

Fixes CLIENT-46

Depends-On: I8434b810ba3ee5548467c3fd2b72faed4046a586
Change-Id: I79e9a19acf452c831ee6e671f50b54e8f674f2cd
Reviewed-on: http://gerrit.dmdirc.com/1569
Automatic-Compile: DMDirc Local Commits <dmdirc@googlemail.com>
Reviewed-by: Greg Holmes <greg@dmdirc.com>
tags/0.6.5b1
Chris Smith 13 years ago
parent
commit
39693ea024

+ 10
- 7
src/com/dmdirc/config/ConfigManager.java View File

24
 
24
 
25
 import com.dmdirc.interfaces.ConfigChangeListener;
25
 import com.dmdirc.interfaces.ConfigChangeListener;
26
 import com.dmdirc.util.MapList;
26
 import com.dmdirc.util.MapList;
27
+import com.dmdirc.util.validators.Validator;
27
 
28
 
28
 import java.util.ArrayList;
29
 import java.util.ArrayList;
29
 import java.util.Collections;
30
 import java.util.Collections;
119
 
120
 
120
     /** {@inheritDoc} */
121
     /** {@inheritDoc} */
121
     @Override
122
     @Override
122
-    public String getOption(final String domain, final String option) {
123
+    public String getOption(final String domain, final String option,
124
+            final Validator<String> validator) {
123
         doStats(domain, option);
125
         doStats(domain, option);
124
 
126
 
125
         synchronized (sources) {
127
         synchronized (sources) {
126
             for (Identity source : sources) {
128
             for (Identity source : sources) {
127
-                if (source.hasOption(domain, option)) {
128
-                    return source.getOption(domain, option);
129
+                if (source.hasOption(domain, option, validator)) {
130
+                    return source.getOption(domain, option, validator);
129
                 }
131
                 }
130
             }
132
             }
131
         }
133
         }
132
 
134
 
133
-        throw new IllegalArgumentException("Config option not found: " + domain + "." + option);
135
+        return null;
134
     }
136
     }
135
 
137
 
136
     /** {@inheritDoc} */
138
     /** {@inheritDoc} */
137
     @Override
139
     @Override
138
-    protected boolean hasOption(final String domain, final String option) {
140
+    protected boolean hasOption(final String domain, final String option,
141
+            final Validator<String> validator) {
139
         doStats(domain, option);
142
         doStats(domain, option);
140
 
143
 
141
         synchronized (sources) {
144
         synchronized (sources) {
142
             for (Identity source : sources) {
145
             for (Identity source : sources) {
143
-                if (source.hasOption(domain, option)) {
146
+                if (source.hasOption(domain, option, validator)) {
144
                     return true;
147
                     return true;
145
                 }
148
                 }
146
             }
149
             }
211
     protected Identity getScope(final String domain, final String option) {
214
     protected Identity getScope(final String domain, final String option) {
212
         synchronized (sources) {
215
         synchronized (sources) {
213
             for (Identity source : sources) {
216
             for (Identity source : sources) {
214
-                if (source.hasOption(domain, option)) {
217
+                if (source.hasOptionString(domain, option)) {
215
                     return source;
218
                     return source;
216
                 }
219
                 }
217
             }
220
             }

+ 156
- 49
src/com/dmdirc/config/ConfigSource.java View File

23
 package com.dmdirc.config;
23
 package com.dmdirc.config;
24
 
24
 
25
 import com.dmdirc.ui.messages.ColourManager;
25
 import com.dmdirc.ui.messages.ColourManager;
26
+import com.dmdirc.util.validators.ColourValidator;
27
+import com.dmdirc.util.validators.DisabledOptionValidator;
28
+import com.dmdirc.util.validators.NumericalValidator;
29
+import com.dmdirc.util.validators.OptionalValidator;
30
+import com.dmdirc.util.validators.PermissiveValidator;
31
+import com.dmdirc.util.validators.Validator;
32
+import com.dmdirc.util.validators.ValidatorChain;
26
 
33
 
27
 import java.awt.Color;
34
 import java.awt.Color;
28
 import java.util.ArrayList;
35
 import java.util.ArrayList;
31
 
38
 
32
 /**
39
 /**
33
  * Defines methods to get options from a config source in various forms.
40
  * Defines methods to get options from a config source in various forms.
41
+ * <p>
42
+ * This implementation supports the idea of optional/disabled settings.
43
+ * This is where values may be prefixed with the strings <code>true:</code>
44
+ * or <code>false:</code>, where the former has no effect on the value of
45
+ * the setting, and the latter indicates that the user wishes to disable
46
+ * the setting.
47
+ * <p>
48
+ * Disabled settings allow for optional settings to have default values; a
49
+ * value can be added with the <code>false:</code> prefix which effectively
50
+ * disables the default value and makes the setting act as though it does not
51
+ * have a value. Note that for this sort of behaviour to make sense, it requires
52
+ * an implementation that takes values from multiple sources, such as a
53
+ * {@link ConfigManager}.
34
  *
54
  *
35
  * @author chris
55
  * @author chris
36
  */
56
  */
37
 public abstract class ConfigSource {
57
 public abstract class ConfigSource {
58
+    
59
+    /** A permissive validator to use when callers don't specify one. */
60
+    private static final Validator<String> PERMISSIVE_VALIDATOR
61
+            = new PermissiveValidator<String>();
62
+    
63
+    /** A validator for integer settings. */
64
+    private static final Validator<String> INT_VALIDATOR
65
+            = new OptionalValidator(new NumericalValidator(-1, -1));
66
+    
67
+    /** A validator for colour settings. */
68
+    private static final Validator<String> COLOUR_VALIDATOR
69
+            = new OptionalValidator(new ColourValidator());
38
 
70
 
39
     /**
71
     /**
40
-     * Retrieves the specified option.
72
+     * Retrieves the specified option from this config source.
41
      *
73
      *
42
      * @param domain The domain of the option
74
      * @param domain The domain of the option
43
      * @param option The name of the option
75
      * @param option The name of the option
44
-     * @return The value of the option
76
+     * @return The value of the option, or null if it doesn't exist
45
      */
77
      */
46
-    public abstract String getOption(final String domain, final String option);
78
+    public String getOption(final String domain, final String option) {
79
+        return getOption(domain, option, PERMISSIVE_VALIDATOR);
80
+    }
81
+    
82
+    /**
83
+     * Retrieves the first value for the specified option that matches the
84
+     * specified validator.
85
+     *
86
+     * @since 0.6.5
87
+     * @param domain The domain of the option
88
+     * @param option The name of the option
89
+     * @param validator The validator to use to check legal values
90
+     * @return The value of the option, or null if no matching values exist
91
+     */
92
+    protected abstract String getOption(final String domain,
93
+            final String option, final Validator<String> validator);
47
 
94
 
48
     /**
95
     /**
49
-     * Determines if this manager has the specified option.
96
+     * Determines if this source has a value for the specified option which
97
+     * matches the specified validator.
50
      *
98
      *
99
+     * @since 0.6.5
51
      * @param domain The domain of the option
100
      * @param domain The domain of the option
52
      * @param option The name of the option
101
      * @param option The name of the option
53
-     * @return True iff the option exists, false otherwise.
102
+     * @param validator The validator to use to check legal values
103
+     * @return True iff a matching option exists, false otherwise.
54
      */
104
      */
55
-    protected abstract boolean hasOption(final String domain, final String option);
105
+    protected abstract boolean hasOption(final String domain,
106
+            final String option, final Validator<String> validator);
56
 
107
 
57
     /**
108
     /**
58
-     * Determines if this manager has the specified String option.
109
+     * Determines if this source has the specified String option.
110
+     * <p>
111
+     * A String option is considered to exist if:
112
+     * <ul>
113
+     *  <li>there is a value for the specified option,
114
+     *  <li>that value is not empty, and
115
+     *  <li>that value is not disabled (i.e., it doesn't begin with "false:")
116
+     * </ul>
59
      *
117
      *
60
      * @param domain The domain of the option
118
      * @param domain The domain of the option
61
      * @param option The name of the option
119
      * @param option The name of the option
63
      * @return True iff the option exists and is not empty, false otherwise
121
      * @return True iff the option exists and is not empty, false otherwise
64
      */
122
      */
65
     public boolean hasOptionString(final String domain, final String option) {
123
     public boolean hasOptionString(final String domain, final String option) {
124
+        return hasOptionString(domain, option, PERMISSIVE_VALIDATOR);
125
+    }
126
+    
127
+    /**
128
+     * Determines if this source has the specified String option.
129
+     * <p>
130
+     * A String option is considered to exist if:
131
+     * <ul>
132
+     *  <li>there is a value for the specified option that
133
+     *      satisfies the specified validator,
134
+     *  <li>that value is not empty, and
135
+     *  <li>that value is not disabled (i.e., it doesn't begin with "false:")
136
+     * </ul>
137
+     *
138
+     * @param domain The domain of the option
139
+     * @param option The name of the option
140
+     * @param validator The validator to use to check legal values
141
+     * @since 0.6.5
142
+     * @return True iff the option exists and is not empty, false otherwise
143
+     */
144
+    public boolean hasOptionString(final String domain, final String option,
145
+            final Validator<String> validator) {
66
         String value;
146
         String value;
67
 
147
 
68
-        return hasOption(domain, option) && !(value = getOption(domain, option)).isEmpty()
148
+        return hasOption(domain, option, validator)
149
+                && !(value = getOption(domain, option, validator)).isEmpty()
69
                 && !value.startsWith("false:");
150
                 && !value.startsWith("false:");
70
     }
151
     }
71
 
152
 
72
     /**
153
     /**
73
-     * Determines if this manager has the specified integer option.
154
+     * Determines if this source has the specified integer option.
74
      *
155
      *
75
      * @param domain The domain of the option
156
      * @param domain The domain of the option
76
      * @param option The name of the option
157
      * @param option The name of the option
79
      * false otherwise.
160
      * false otherwise.
80
      */
161
      */
81
     public boolean hasOptionInt(final String domain, final String option) {
162
     public boolean hasOptionInt(final String domain, final String option) {
82
-        if (hasOption(domain, option)) {
83
-            try {
84
-                return getOptionInt(domain, option) != null;
85
-            } catch (NumberFormatException ex) {
86
-                // Do nothing
87
-            }
88
-        }
89
-
90
-        return false;
163
+        return hasOptionString(domain, option, INT_VALIDATOR);
91
     }
164
     }
92
 
165
 
93
     /**
166
     /**
94
-     * Determines if this manager has the specified character option.
167
+     * Determines if this source has the specified character option.
95
      *
168
      *
96
      * @param domain The domain of the option
169
      * @param domain The domain of the option
97
      * @param option The name of the option
170
      * @param option The name of the option
100
      * false otherwise.
173
      * false otherwise.
101
      */
174
      */
102
     public boolean hasOptionChar(final String domain, final String option) {
175
     public boolean hasOptionChar(final String domain, final String option) {
103
-        return hasOption(domain, option) && !getOption(domain, option).isEmpty();
176
+        return hasOptionString(domain, option);
104
     }
177
     }
105
 
178
 
106
     /**
179
     /**
107
-     * Determines if this manager has the specified colour option.
180
+     * Determines if this source has the specified colour option.
108
      *
181
      *
109
      * @param domain The domain of the option
182
      * @param domain The domain of the option
110
      * @param option The name of the option
183
      * @param option The name of the option
113
      * false otherwise.
186
      * false otherwise.
114
      */
187
      */
115
     public boolean hasOptionColour(final String domain, final String option) {
188
     public boolean hasOptionColour(final String domain, final String option) {
116
-        if (hasOption(domain, option)) {
117
-            String value = getOption(domain, option);
118
-            String colour;
119
-
120
-            if (value.startsWith("true:")) {
121
-                colour = value.substring(5);
122
-            } else {
123
-                colour = value;
124
-            }
125
-
126
-            return ColourManager.parseColour(colour, null) != null;
127
-        } else {
128
-            return false;
129
-        }
189
+        return hasOptionString(domain, option, COLOUR_VALIDATOR);
130
     }
190
     }
131
 
191
 
132
     /**
192
     /**
137
      * @return The boolean representation of the option
197
      * @return The boolean representation of the option
138
      */
198
      */
139
     public boolean hasOptionBool(final String domain, final String option) {
199
     public boolean hasOptionBool(final String domain, final String option) {
140
-        return hasOption(domain, option);
200
+        return hasOption(domain, option, PERMISSIVE_VALIDATOR);
141
     }
201
     }
142
-
202
+    
143
     /**
203
     /**
144
-     * Retrieves the specified option as a String, if it exists
204
+     * Retrieves the specified option as a String, if it exists and satisfies
205
+     * the specified validator.
206
+     * <p>
207
+     * If no fallback settings are supplied (or if fallback settings are
208
+     * supplied and execution reaches the last fallback setting) AND if the
209
+     * 'required' parameter is true, then all disabled values (i.e., those
210
+     * starting with <code>false:</code>) will be ignored. To check if a valid
211
+     * non-disabled value exists, call
212
+     * {@link #hasOptionString(java.lang.String, java.lang.String, com.dmdirc.util.validators.Validator)}.
145
      *
213
      *
146
      * @param domain The domain of the option
214
      * @param domain The domain of the option
147
      * @param option The name of the option
215
      * @param option The name of the option
216
+     * @param required Whether the specified option is required or not
217
+     * @param validator The validator to use to check the value
148
      * @param fallbacks An ordered array of further domains and options
218
      * @param fallbacks An ordered array of further domains and options
149
      * (in pairs) to try if the specified domain/option isn't found
219
      * (in pairs) to try if the specified domain/option isn't found
150
      * @return The string representation of the option or null if optional
220
      * @return The string representation of the option or null if optional
151
      * setting is not specified
221
      * setting is not specified
152
-     * @since 0.6.3
222
+     * @since 0.6.5
153
      */
223
      */
154
     public String getOptionString(final String domain, final String option,
224
     public String getOptionString(final String domain, final String option,
225
+            final boolean required, final Validator<String> validator,
155
             final String ... fallbacks) {
226
             final String ... fallbacks) {
156
         String value;
227
         String value;
228
+        
229
+        @SuppressWarnings("unchecked")
230
+        final Validator<String> newValidator = required && fallbacks.length == 0
231
+                ? new ValidatorChain<String>(new DisabledOptionValidator(), validator)
232
+                : validator;
157
 
233
 
158
-        if (!hasOption(domain, option) || (value = getOption(domain, option))
159
-                .startsWith("false:")) {
160
-            return fallbacks.length >= 2 ? getOptionString(fallbacks[0], fallbacks[1],
234
+        if (!hasOption(domain, option, newValidator)
235
+                || (value = getOption(domain, option, newValidator)).startsWith("false:")) {            
236
+            return fallbacks.length >= 2 ? getOptionString(fallbacks[0],
237
+                    fallbacks[1], required, validator,
161
                     Arrays.copyOfRange(fallbacks, 2, fallbacks.length)) : null;
238
                     Arrays.copyOfRange(fallbacks, 2, fallbacks.length)) : null;
162
         } else if (value.startsWith("true:")) {
239
         } else if (value.startsWith("true:")) {
163
             return value.substring(5);
240
             return value.substring(5);
166
         }
243
         }
167
     }
244
     }
168
 
245
 
246
+    /**
247
+     * Retrieves the specified option as a String, if it exists.
248
+     *
249
+     * @param domain The domain of the option
250
+     * @param option The name of the option
251
+     * @param fallbacks An ordered array of further domains and options
252
+     * (in pairs) to try if the specified domain/option isn't found
253
+     * @return The string representation of the option or null if optional
254
+     * setting is not specified
255
+     * @since 0.6.3
256
+     */
257
+    public String getOptionString(final String domain, final String option,
258
+            final String ... fallbacks) {
259
+        return getOptionString(domain, option, true, PERMISSIVE_VALIDATOR, fallbacks);
260
+    }
261
+
169
     /**
262
     /**
170
      * Retrieves the specified option as a character.
263
      * Retrieves the specified option as a character.
171
      *
264
      *
189
      */
282
      */
190
     public Color getOptionColour(final String domain, final String option,
283
     public Color getOptionColour(final String domain, final String option,
191
             final String ... fallbacks) {
284
             final String ... fallbacks) {
192
-        final String value = getOptionString(domain, option, fallbacks);
285
+        final String value = getOptionString(domain, option, true, COLOUR_VALIDATOR, fallbacks);
193
 
286
 
194
         return value == null ? null : ColourManager.parseColour(value, null);
287
         return value == null ? null : ColourManager.parseColour(value, null);
195
     }
288
     }
217
             final boolean trimEmpty) {
310
             final boolean trimEmpty) {
218
         final List<String> res = new ArrayList<String>();
311
         final List<String> res = new ArrayList<String>();
219
 
312
 
220
-        if (hasOption(domain, option)) {
313
+        if (hasOption(domain, option, PERMISSIVE_VALIDATOR)) {
221
             for (String line : getOption(domain, option).split("\n")) {
314
             for (String line : getOption(domain, option).split("\n")) {
222
                 if (!line.isEmpty() || !trimEmpty) {
315
                 if (!line.isEmpty() || !trimEmpty) {
223
                     res.add(line);
316
                     res.add(line);
239
     public List<String> getOptionList(final String domain, final String option) {
332
     public List<String> getOptionList(final String domain, final String option) {
240
         return getOptionList(domain, option, true);
333
         return getOptionList(domain, option, true);
241
     }
334
     }
242
-
335
+    
243
     /**
336
     /**
244
      * Retrieves an integral representation of the specified option.
337
      * Retrieves an integral representation of the specified option.
245
      *
338
      *
247
      * @param option The name of the option
340
      * @param option The name of the option
248
      * @param fallbacks An ordered array of further domains and options
341
      * @param fallbacks An ordered array of further domains and options
249
      * (in pairs) to try if the specified domain/option isn't found
342
      * (in pairs) to try if the specified domain/option isn't found
250
-     * @throws NumberFormatException If the setting can't be parsed
251
-     * @return The integer representation of the option or null if optional
252
-     * setting is false
343
+     * @return The integer representation of the option
253
      */
344
      */
254
     public Integer getOptionInt(final String domain, final String option,
345
     public Integer getOptionInt(final String domain, final String option,
255
             final String ... fallbacks) {
346
             final String ... fallbacks) {
256
-        final String value = getOptionString(domain, option, fallbacks);
347
+        return getOptionInt(domain, option, true, fallbacks);
348
+    }
349
+
350
+    /**
351
+     * Retrieves an integral representation of the specified option.
352
+     *
353
+     * @since 0.6.5
354
+     * @param domain The domain of the option
355
+     * @param option The name of the option
356
+     * @param required Whether this option is required or optional
357
+     * @param fallbacks An ordered array of further domains and options
358
+     * (in pairs) to try if the specified domain/option isn't found
359
+     * @return The integer representation of the option
360
+     */
361
+    public Integer getOptionInt(final String domain, final String option,
362
+            final boolean required, final String ... fallbacks) {
363
+        final String value = getOptionString(domain, option, required, INT_VALIDATOR, fallbacks);
257
 
364
 
258
         return value == null ? null : Integer.parseInt(value.trim());
365
         return value == null ? null : Integer.parseInt(value.trim());
259
     }
366
     }

+ 33
- 22
src/com/dmdirc/config/Identity.java View File

29
 import com.dmdirc.util.ConfigFile;
29
 import com.dmdirc.util.ConfigFile;
30
 import com.dmdirc.util.InvalidConfigFileException;
30
 import com.dmdirc.util.InvalidConfigFileException;
31
 import com.dmdirc.util.WeakList;
31
 import com.dmdirc.util.WeakList;
32
+import com.dmdirc.util.validators.Validator;
32
 
33
 
33
 import java.io.File;
34
 import java.io.File;
34
 import java.io.IOException;
35
 import java.io.IOException;
157
             throws InvalidIdentityFileException {
158
             throws InvalidIdentityFileException {
158
         final ConfigTarget target = new ConfigTarget();
159
         final ConfigTarget target = new ConfigTarget();
159
 
160
 
160
-        if (hasOption(DOMAIN, "ircd")) {
161
+        if (hasOptionString(DOMAIN, "ircd")) {
161
             target.setIrcd(getOption(DOMAIN, "ircd"));
162
             target.setIrcd(getOption(DOMAIN, "ircd"));
162
-        } else if (hasOption(DOMAIN, "protocol")) {
163
+        } else if (hasOptionString(DOMAIN, "protocol")) {
163
             target.setProtocol(getOption(DOMAIN, "protocol"));
164
             target.setProtocol(getOption(DOMAIN, "protocol"));
164
-        } else if (hasOption(DOMAIN, "network")) {
165
+        } else if (hasOptionString(DOMAIN, "network")) {
165
             target.setNetwork(getOption(DOMAIN, "network"));
166
             target.setNetwork(getOption(DOMAIN, "network"));
166
-        } else if (hasOption(DOMAIN, "server")) {
167
+        } else if (hasOptionString(DOMAIN, "server")) {
167
             target.setServer(getOption(DOMAIN, "server"));
168
             target.setServer(getOption(DOMAIN, "server"));
168
-        } else if (hasOption(DOMAIN, "channel")) {
169
+        } else if (hasOptionString(DOMAIN, "channel")) {
169
             target.setChannel(getOption(DOMAIN, "channel"));
170
             target.setChannel(getOption(DOMAIN, "channel"));
170
-        } else if (hasOption(DOMAIN, "globaldefault")) {
171
+        } else if (hasOptionString(DOMAIN, "globaldefault")) {
171
             target.setGlobalDefault();
172
             target.setGlobalDefault();
172
-        } else if (hasOption(DOMAIN, "global") || (forceDefault && !isProfile())) {
173
+        } else if (hasOptionString(DOMAIN, "global") || (forceDefault && !isProfile())) {
173
             target.setGlobal();
174
             target.setGlobal();
174
         } else if (isProfile()) {
175
         } else if (isProfile()) {
175
             target.setCustom(PROFILE_DOMAIN);
176
             target.setCustom(PROFILE_DOMAIN);
176
-        } else if (hasOption(DOMAIN, "type")) {
177
+        } else if (hasOptionString(DOMAIN, "type")) {
177
             target.setCustom(getOption(DOMAIN, "type"));
178
             target.setCustom(getOption(DOMAIN, "type"));
178
         } else {
179
         } else {
179
             throw new InvalidIdentityFileException("No target and no profile");
180
             throw new InvalidIdentityFileException("No target and no profile");
180
         }
181
         }
181
 
182
 
182
-        if (hasOption(DOMAIN, "order")) {
183
+        if (hasOptionString(DOMAIN, "order")) {
183
             target.setOrder(getOptionInt(DOMAIN, "order"));
184
             target.setOrder(getOptionInt(DOMAIN, "order"));
184
         }
185
         }
185
 
186
 
203
             throw new InvalidIdentityFileException(ex);
204
             throw new InvalidIdentityFileException(ex);
204
         }
205
         }
205
 
206
 
206
-        if (!hasOption(DOMAIN, "name") && !forceDefault) {
207
+        if (!hasOptionString(DOMAIN, "name") && !forceDefault) {
207
             throw new InvalidIdentityFileException("No name specified");
208
             throw new InvalidIdentityFileException("No name specified");
208
         }
209
         }
209
     }
210
     }
279
      * @return The name of this identity
280
      * @return The name of this identity
280
      */
281
      */
281
     public String getName() {
282
     public String getName() {
282
-        if (hasOption(DOMAIN, "name")) {
283
+        if (hasOptionString(DOMAIN, "name")) {
283
             return getOption(DOMAIN, "name");
284
             return getOption(DOMAIN, "name");
284
         } else {
285
         } else {
285
             return "Unnamed";
286
             return "Unnamed";
294
      * @since 0.6.3m1
295
      * @since 0.6.3m1
295
      */
296
      */
296
     protected void migrateProfile() {
297
     protected void migrateProfile() {
297
-        if (hasOption(PROFILE_DOMAIN, "nickname")) {
298
+        if (hasOptionString(PROFILE_DOMAIN, "nickname")) {
298
             // Migrate
299
             // Migrate
299
 
300
 
300
             setOption(PROFILE_DOMAIN, "nicknames", getOption(PROFILE_DOMAIN, "nickname")
301
             setOption(PROFILE_DOMAIN, "nicknames", getOption(PROFILE_DOMAIN, "nickname")
301
-                    + (hasOption(PROFILE_DOMAIN, "altnicks") ? "\n"
302
+                    + (hasOptionString(PROFILE_DOMAIN, "altnicks") ? "\n"
302
                     + getOption(PROFILE_DOMAIN, "altnicks") : ""));
303
                     + getOption(PROFILE_DOMAIN, "altnicks") : ""));
303
             unsetOption(PROFILE_DOMAIN, "nickname");
304
             unsetOption(PROFILE_DOMAIN, "nickname");
304
             unsetOption(PROFILE_DOMAIN, "altnicks");
305
             unsetOption(PROFILE_DOMAIN, "altnicks");
313
      * @return True iff this identity can be used as a profile
314
      * @return True iff this identity can be used as a profile
314
      */
315
      */
315
     public boolean isProfile() {
316
     public boolean isProfile() {
316
-        return (hasOption(PROFILE_DOMAIN, "nicknames")
317
-                || hasOption(PROFILE_DOMAIN, "nickname"))
318
-                && hasOption(PROFILE_DOMAIN, "realname");
317
+        return (hasOptionString(PROFILE_DOMAIN, "nicknames")
318
+                || hasOptionString(PROFILE_DOMAIN, "nickname"))
319
+                && hasOptionString(PROFILE_DOMAIN, "realname");
319
     }
320
     }
320
 
321
 
321
     /** {@inheritDoc} */
322
     /** {@inheritDoc} */
322
     @Override
323
     @Override
323
-    protected boolean hasOption(final String domain, final String option) {
324
-        return file.isKeyDomain(domain) && file.getKeyDomain(domain).containsKey(option);
324
+    protected boolean hasOption(final String domain, final String option,
325
+            final Validator<String> validator) {
326
+        return file.isKeyDomain(domain)
327
+                && file.getKeyDomain(domain).containsKey(option)
328
+                && !validator.validate(file.getKeyDomain(domain).get(option)).isFailure();
325
     }
329
     }
326
 
330
 
327
     /** {@inheritDoc} */
331
     /** {@inheritDoc} */
328
     @Override
332
     @Override
329
-    public synchronized String getOption(final String domain, final String option) {
330
-        return file.getKeyDomain(domain).get(option);
333
+    public synchronized String getOption(final String domain,
334
+            final String option, final Validator<String> validator) {
335
+        final String value = file.getKeyDomain(domain).get(option);
336
+        
337
+        if (validator.validate(value).isFailure()) {
338
+            return null;
339
+        }
340
+        
341
+        return value;
331
     }
342
     }
332
 
343
 
333
     /**
344
     /**
356
 
367
 
357
                 globalConfig.removeIdentity(this);
368
                 globalConfig.removeIdentity(this);
358
 
369
 
359
-                if (globalConfig.hasOption(domain, option)
370
+                if (globalConfig.hasOptionString(domain, option)
360
                         && globalConfig.getOption(domain, option).equals(value)) {
371
                         && globalConfig.getOption(domain, option).equals(value)) {
361
                     // The new value is covered by a default setting
372
                     // The new value is covered by a default setting
362
                     if (oldValue == null) {
373
                     if (oldValue == null) {
512
                         final String key = subentry.getKey();
523
                         final String key = subentry.getKey();
513
                         final String value = subentry.getValue();
524
                         final String value = subentry.getValue();
514
 
525
 
515
-                        if (globalConfig.hasOption(domain, key) &&
526
+                        if (globalConfig.hasOptionString(domain, key) &&
516
                                 globalConfig.getOption(domain, key).equals(value)) {
527
                                 globalConfig.getOption(domain, key).equals(value)) {
517
                             LOGGER.log(Level.FINEST,
528
                             LOGGER.log(Level.FINEST,
518
                                     "{0}: found superfluous setting: {1}.{2} (= {3})",
529
                                     "{0}: found superfluous setting: {1}.{2} (= {3})",

+ 2
- 2
src/com/dmdirc/ui/messages/ColourManager.java View File

62
     private static void initColours() {
62
     private static void initColours() {
63
         for (int i = 0; i < 16; i++) {
63
         for (int i = 0; i < 16; i++) {
64
             if (IdentityManager.getGlobalConfig().hasOptionColour("colour", String.valueOf(i))) {
64
             if (IdentityManager.getGlobalConfig().hasOptionColour("colour", String.valueOf(i))) {
65
-                ircColours[i] = getColour(IdentityManager.getGlobalConfig()
66
-                        .getOption("colour", String.valueOf(i)));
65
+                ircColours[i] = IdentityManager.getGlobalConfig()
66
+                        .getOptionColour("colour", String.valueOf(i));
67
                 COLOUR_CACHE.remove(String.valueOf(i));
67
                 COLOUR_CACHE.remove(String.valueOf(i));
68
             } else if (!ircColours[i].equals(DEFAULT_COLOURS[i])) {
68
             } else if (!ircColours[i].equals(DEFAULT_COLOURS[i])) {
69
                 ircColours[i] = DEFAULT_COLOURS[i];
69
                 ircColours[i] = DEFAULT_COLOURS[i];

+ 2
- 2
src/com/dmdirc/ui/messages/IRCDocument.java View File

83
 
83
 
84
         cachedLines = new RollingList<Line>(50);
84
         cachedLines = new RollingList<Line>(50);
85
         cachedStrings = new RollingList<AttributedString>(50);
85
         cachedStrings = new RollingList<AttributedString>(50);
86
-        frameBufferSize = configManager.getOptionInt("ui", "frameBufferSize");
86
+        frameBufferSize = configManager.getOptionInt("ui", "frameBufferSize", false);
87
 
87
 
88
         configManager.addChangeListener("ui", "textPaneFontSize", this);
88
         configManager.addChangeListener("ui", "textPaneFontSize", this);
89
         configManager.addChangeListener("ui", "textPaneFontName", this);
89
         configManager.addChangeListener("ui", "textPaneFontName", this);
368
         } else {
368
         } else {
369
             fontSize = defaultFont.getSize();
369
             fontSize = defaultFont.getSize();
370
         }
370
         }
371
-        frameBufferSize = configManager.getOptionInt("ui", "frameBufferSize");
371
+        frameBufferSize = configManager.getOptionInt("ui", "frameBufferSize", false);
372
         trim(frameBufferSize);
372
         trim(frameBufferSize);
373
     }
373
     }
374
 
374
 

+ 7
- 4
src/com/dmdirc/ui/themes/ThemeIdentity.java View File

24
 
24
 
25
 import com.dmdirc.config.Identity;
25
 import com.dmdirc.config.Identity;
26
 import com.dmdirc.config.InvalidIdentityFileException;
26
 import com.dmdirc.config.InvalidIdentityFileException;
27
+import com.dmdirc.util.validators.Validator;
27
 
28
 
28
 import java.io.IOException;
29
 import java.io.IOException;
29
 import java.io.InputStream;
30
 import java.io.InputStream;
64
 
65
 
65
     /** {@inheritDoc} */
66
     /** {@inheritDoc} */
66
     @Override @Deprecated
67
     @Override @Deprecated
67
-    public boolean hasOption(final String domain, final String option) {
68
+    public boolean hasOption(final String domain, final String option,
69
+            final Validator<String> validator) {
68
         if (domain.equalsIgnoreCase("ui") || domain.equalsIgnoreCase("identity")
70
         if (domain.equalsIgnoreCase("ui") || domain.equalsIgnoreCase("identity")
69
                 || domain.equalsIgnoreCase("icon")  || domain.equalsIgnoreCase("theme")
71
                 || domain.equalsIgnoreCase("icon")  || domain.equalsIgnoreCase("theme")
70
                 || domain.equalsIgnoreCase("formatter") || domain.equalsIgnoreCase("colour")) {
72
                 || domain.equalsIgnoreCase("formatter") || domain.equalsIgnoreCase("colour")) {
71
-            return super.hasOption(domain, option);
73
+            return super.hasOption(domain, option, validator);
72
         } else {
74
         } else {
73
             return false;
75
             return false;
74
         }
76
         }
76
 
78
 
77
     /** {@inheritDoc} */
79
     /** {@inheritDoc} */
78
     @Override
80
     @Override
79
-    public String getOption(final String domain, final String option) {
80
-        final String result = super.getOption(domain, option);
81
+    public String getOption(final String domain,
82
+            final String option, final Validator<String> validator) {
83
+        final String result = super.getOption(domain, option, validator);
81
 
84
 
82
         if (result == null) {
85
         if (result == null) {
83
             return result;
86
             return result;

+ 4
- 3
test/com/dmdirc/config/ConfigManagerTest.java View File

22
 package com.dmdirc.config;
22
 package com.dmdirc.config;
23
 
23
 
24
 import com.dmdirc.interfaces.ConfigChangeListener;
24
 import com.dmdirc.interfaces.ConfigChangeListener;
25
+import com.dmdirc.util.validators.PermissiveValidator;
25
 
26
 
26
 import org.junit.Test;
27
 import org.junit.Test;
27
 import static org.junit.Assert.*;
28
 import static org.junit.Assert.*;
29
 
30
 
30
 public class ConfigManagerTest {
31
 public class ConfigManagerTest {
31
 
32
 
32
-    @Test(expected=IllegalArgumentException.class)
33
+    @Test
33
     public void testNonExistantOption() {
34
     public void testNonExistantOption() {
34
-        new ConfigManager("", "", "", "").getOption("unit-test123", "foobar");
35
+        assertNull(new ConfigManager("", "", "", "").getOption("unit-test123", "foobar"));
35
     }
36
     }
36
 
37
 
37
     @Test
38
     @Test
38
     public void testStats() {
39
     public void testStats() {
39
         final ConfigManager cm = new ConfigManager("", "", "", "");
40
         final ConfigManager cm = new ConfigManager("", "", "", "");
40
         assertNull(ConfigManager.getStats().get("unit-test123.baz"));
41
         assertNull(ConfigManager.getStats().get("unit-test123.baz"));
41
-        cm.hasOption("unit-test123", "baz");
42
+        cm.hasOption("unit-test123", "baz", new PermissiveValidator<String>());
42
         assertNotNull(ConfigManager.getStats().get("unit-test123.baz"));
43
         assertNotNull(ConfigManager.getStats().get("unit-test123.baz"));
43
         assertEquals(1, (int) ConfigManager.getStats().get("unit-test123.baz"));
44
         assertEquals(1, (int) ConfigManager.getStats().get("unit-test123.baz"));
44
     }
45
     }

+ 3
- 2
test/com/dmdirc/config/IdentityTest.java View File

23
 package com.dmdirc.config;
23
 package com.dmdirc.config;
24
 
24
 
25
 import com.dmdirc.interfaces.ConfigChangeListener;
25
 import com.dmdirc.interfaces.ConfigChangeListener;
26
+import com.dmdirc.util.validators.PermissiveValidator;
26
 
27
 
27
 import java.io.IOException;
28
 import java.io.IOException;
28
 import java.util.Map;
29
 import java.util.Map;
79
 
80
 
80
     @Test
81
     @Test
81
     public void testHasOption() {
82
     public void testHasOption() {
82
-        assertFalse(myIdent.hasOption("has", "option"));
83
+        assertFalse(myIdent.hasOption("has", "option", new PermissiveValidator<String>()));
83
 
84
 
84
         myIdent.setOption("has", "option", "");
85
         myIdent.setOption("has", "option", "");
85
 
86
 
86
-        assertTrue(myIdent.hasOption("has", "option"));
87
+        assertTrue(myIdent.hasOption("has", "option", new PermissiveValidator<String>()));
87
 
88
 
88
         myIdent.unsetOption("has", "option");
89
         myIdent.unsetOption("has", "option");
89
     }
90
     }

+ 3
- 2
test/com/dmdirc/harness/TestConfigManagerMap.java View File

23
 package com.dmdirc.harness;
23
 package com.dmdirc.harness;
24
 
24
 
25
 import com.dmdirc.config.ConfigManager;
25
 import com.dmdirc.config.ConfigManager;
26
+import com.dmdirc.util.validators.Validator;
26
 import java.util.HashMap;
27
 import java.util.HashMap;
27
 import java.util.Map;
28
 import java.util.Map;
28
 
29
 
46
     }
47
     }
47
 
48
 
48
     @Override @Deprecated
49
     @Override @Deprecated
49
-    public boolean hasOption(String domain, String option) {
50
+    public boolean hasOption(String domain, String option, Validator<String> validator) {
50
         if (settings.containsKey(domain + "." + option)) {
51
         if (settings.containsKey(domain + "." + option)) {
51
             return true;
52
             return true;
52
         } else {
53
         } else {
53
-            return super.hasOption(domain, option);
54
+            return super.hasOption(domain, option, validator);
54
         }
55
         }
55
     }
56
     }
56
 }
57
 }

+ 3
- 2
test/com/dmdirc/harness/TestConfigManagerOptionToggle.java View File

23
 package com.dmdirc.harness;
23
 package com.dmdirc.harness;
24
 
24
 
25
 import com.dmdirc.config.ConfigManager;
25
 import com.dmdirc.config.ConfigManager;
26
+import com.dmdirc.util.validators.Validator;
26
 
27
 
27
 public class TestConfigManagerOptionToggle extends ConfigManager {
28
 public class TestConfigManagerOptionToggle extends ConfigManager {
28
     private static final long serialVersionUID = 8078917248288638755L;
29
     private static final long serialVersionUID = 8078917248288638755L;
32
     }
33
     }
33
 
34
 
34
     @Override
35
     @Override
35
-    public String getOption(String domain, String option) {
36
+    public String getOption(String domain, String option, Validator<String> validator) {
36
         return option.substring(1);
37
         return option.substring(1);
37
     }
38
     }
38
 
39
 
39
     @Override @Deprecated
40
     @Override @Deprecated
40
-    public boolean hasOption(String domain, String option) {
41
+    public boolean hasOption(String domain, String option, Validator<String> validator) {
41
         return option.charAt(0) == '1';
42
         return option.charAt(0) == '1';
42
     }
43
     }
43
 }
44
 }

+ 5
- 4
test/com/dmdirc/harness/TestConfigSource.java View File

23
 package com.dmdirc.harness;
23
 package com.dmdirc.harness;
24
 
24
 
25
 import com.dmdirc.config.*;
25
 import com.dmdirc.config.*;
26
+import com.dmdirc.util.validators.Validator;
26
 
27
 
27
 public class TestConfigSource extends ConfigSource {
28
 public class TestConfigSource extends ConfigSource {
28
 
29
 
29
     @Override
30
     @Override
30
-    public String getOption(String domain, String option) {
31
-        return option;
31
+    protected boolean hasOption(String domain, String option, Validator<String> validator) {
32
+        return Boolean.parseBoolean(domain);
32
     }
33
     }
33
 
34
 
34
     @Override
35
     @Override
35
-    protected boolean hasOption(String domain, String option) {
36
-        return Boolean.parseBoolean(domain);
36
+    protected String getOption(String domain, String option, Validator<String> validator) {
37
+        return option;
37
     }
38
     }
38
 }
39
 }

Loading…
Cancel
Save