Bläddra i källkod

Path-ify the IdentityManager.

Change-Id: Iaf2b64f2bd6dcf834e3621e26ae3ff6b81cdb2b4
Reviewed-on: http://gerrit.dmdirc.com/4007
Automatic-Compile: DMDirc Build Manager
Reviewed-by: Greg Holmes <greg@dmdirc.com>
pull/1/head
Chris Smith 9 år sedan
förälder
incheckning
aefb110fff

+ 4
- 2
src/com/dmdirc/config/ConfigFileBackedConfigProvider.java Visa fil

@@ -34,6 +34,7 @@ import com.dmdirc.util.validators.Validator;
34 34
 import java.io.File;
35 35
 import java.io.IOException;
36 36
 import java.io.InputStream;
37
+import java.nio.file.Path;
37 38
 import java.util.ArrayList;
38 39
 import java.util.Collection;
39 40
 import java.util.HashMap;
@@ -82,8 +83,9 @@ public class ConfigFileBackedConfigProvider extends BaseConfigProvider implement
82 83
      * @throws InvalidIdentityFileException Missing required properties
83 84
      * @throws IOException                  Input/output exception
84 85
      */
85
-    public ConfigFileBackedConfigProvider(@Nullable final IdentityManager identityManager, final File file,
86
-            final boolean forceDefault) throws IOException, InvalidIdentityFileException {
86
+    public ConfigFileBackedConfigProvider(@Nullable final IdentityManager identityManager,
87
+            final Path file, final boolean forceDefault) throws IOException,
88
+            InvalidIdentityFileException {
87 89
         this.identityManager = identityManager;
88 90
         this.file = new ConfigFile(file);
89 91
         this.file.setAutomake(true);

+ 13
- 10
src/com/dmdirc/config/ConfigModule.java Visa fil

@@ -34,7 +34,9 @@ import com.dmdirc.logger.Logger;
34 34
 import com.dmdirc.ui.WarningDialog;
35 35
 
36 36
 import java.awt.GraphicsEnvironment;
37
-import java.io.File;
37
+import java.io.IOException;
38
+import java.nio.file.Files;
39
+import java.nio.file.Path;
38 40
 import java.text.SimpleDateFormat;
39 41
 import java.util.Date;
40 42
 
@@ -59,8 +61,8 @@ public class ConfigModule {
59 61
     @Provides
60 62
     @Singleton
61 63
     public IdentityManager getIdentityManager(
62
-            @Directory(DirectoryType.BASE) final String baseDirectory,
63
-            @Directory(DirectoryType.IDENTITIES) final String identitiesDirectory,
64
+            @Directory(DirectoryType.BASE) final Path baseDirectory,
65
+            @Directory(DirectoryType.IDENTITIES) final Path identitiesDirectory,
64 66
             @Directory(DirectoryType.ERRORS) final String errorsDirectory,
65 67
             final CommandLineParser commandLineParser,
66 68
             final DMDircMBassador eventBus) {
@@ -114,12 +116,11 @@ public class ConfigModule {
114 116
     /**
115 117
      * Called when the global config cannot be loaded due to an error. This method informs the user
116 118
      * of the problem and installs a new default config file, backing up the old one.
117
-     *
118
-     * @param identityManager The identity manager to re-initialise after installing defaults.
119
+     *  @param identityManager The identity manager to re-initialise after installing defaults.
119 120
      * @param configdir       The directory to extract default settings into.
120 121
      */
121 122
     private void handleInvalidConfigFile(final IdentityManager identityManager,
122
-            final String configdir) {
123
+            final Path configdir) {
123 124
         final String date = new SimpleDateFormat("yyyyMMddkkmmss").format(new Date());
124 125
 
125 126
         final String message = "DMDirc has detected that your config file "
@@ -135,17 +136,19 @@ public class ConfigModule {
135 136
         // Let command-line users know what is happening.
136 137
         System.out.println(message.replace("<br>", "\n"));
137 138
 
138
-        final File configFile = new File(configdir + "dmdirc.config");
139
-        final File newConfigFile = new File(configdir + "dmdirc.config." + date);
139
+        final Path configFile = configdir.resolve("dmdirc.config");
140
+        final Path newConfigFile = configdir.resolve("dmdirc.config." + date);
141
+
142
+        try {
143
+            Files.move(configFile, newConfigFile);
140 144
 
141
-        if (configFile.renameTo(newConfigFile)) {
142 145
             try {
143 146
                 identityManager.initialise();
144 147
             } catch (InvalidIdentityFileException iife) {
145 148
                 // This shouldn't happen!
146 149
                 Logger.appError(ErrorLevel.FATAL, "Unable to load global config", iife);
147 150
             }
148
-        } else {
151
+        } catch (IOException ex) {
149 152
             final String newMessage = "DMDirc was unable to rename the "
150 153
                     + "global config file and is unable to fix this issue.";
151 154
             if (!GraphicsEnvironment.isHeadless()) {

+ 87
- 64
src/com/dmdirc/config/IdentityManager.java Visa fil

@@ -39,8 +39,10 @@ import com.dmdirc.util.io.ConfigFile;
39 39
 import com.dmdirc.util.io.InvalidConfigFileException;
40 40
 import com.dmdirc.util.resourcemanager.ResourceManager;
41 41
 
42
-import java.io.File;
43 42
 import java.io.IOException;
43
+import java.nio.file.DirectoryStream;
44
+import java.nio.file.Files;
45
+import java.nio.file.Path;
44 46
 import java.util.ArrayList;
45 47
 import java.util.Collection;
46 48
 import java.util.Collections;
@@ -48,6 +50,7 @@ import java.util.HashMap;
48 50
 import java.util.LinkedHashSet;
49 51
 import java.util.List;
50 52
 import java.util.Map;
53
+import java.util.concurrent.ConcurrentHashMap;
51 54
 
52 55
 import org.slf4j.Logger;
53 56
 import org.slf4j.LoggerFactory;
@@ -65,9 +68,9 @@ public class IdentityManager implements IdentityFactory, IdentityController {
65 68
     /** The domain used for profile settings. */
66 69
     private static final String PROFILE_DOMAIN = "profile";
67 70
     /** Base configuration directory where the main configuration file will be located. */
68
-    private final String configDirectory;
71
+    private final Path configDirectory;
69 72
     /** Directory to save and load identities in. */
70
-    private final String identitiesDirectory;
73
+    private final Path identitiesDirectory;
71 74
     /**
72 75
      * The identities that have been loaded into this manager.
73 76
      *
@@ -75,6 +78,8 @@ public class IdentityManager implements IdentityFactory, IdentityController {
75 78
      * custom type as the key.
76 79
      */
77 80
     private final MapList<String, ConfigProvider> identities = new MapList<>();
81
+    /** Map of paths to corresponding config providers, to facilitate reloading. */
82
+    private final Map<Path, ConfigProvider> configProvidersByPath = new ConcurrentHashMap<>();
78 83
     /** The event bus to post events to. */
79 84
     private final DMDircMBassador eventBus;
80 85
     /**
@@ -100,7 +105,7 @@ public class IdentityManager implements IdentityFactory, IdentityController {
100 105
      * @param identitiesDirectory The directory to store identities in.
101 106
      * @param eventBus            The event bus to post events to
102 107
      */
103
-    public IdentityManager(final String baseDirectory, final String identitiesDirectory,
108
+    public IdentityManager(final Path baseDirectory, final Path identitiesDirectory,
104 109
             final DMDircMBassador eventBus) {
105 110
         this.configDirectory = baseDirectory;
106 111
         this.identitiesDirectory = identitiesDirectory;
@@ -129,7 +134,7 @@ public class IdentityManager implements IdentityFactory, IdentityController {
129 134
         target.setGlobalDefault();
130 135
         target.setOrder(500000);
131 136
 
132
-        final ConfigFile addonConfigFile = new ConfigFile((File) null);
137
+        final ConfigFile addonConfigFile = new ConfigFile((Path) null);
133 138
         final Map<String, String> addonSettings = new HashMap<>();
134 139
         addonSettings.put("name", "Addon defaults");
135 140
         addonConfigFile.addDomain("identity", addonSettings);
@@ -148,13 +153,18 @@ public class IdentityManager implements IdentityFactory, IdentityController {
148 153
         final String[] targets = {"default", "modealiases"};
149 154
 
150 155
         for (String target : targets) {
151
-            final File file = new File(identitiesDirectory + target);
156
+            final Path file = identitiesDirectory.resolve(target);
152 157
 
153
-            if (file.exists() && !file.isDirectory()) {
158
+            if (Files.exists(file) && !Files.isDirectory(file)) {
154 159
                 boolean success = false;
155 160
                 for (int i = 0; i < 10 && !success; i++) {
156
-                    final String suffix = ".old" + (i > 0 ? "-" + i : "");
157
-                    success = file.renameTo(new File(file.getParentFile(), target + suffix));
161
+                    try {
162
+                        final String suffix = ".old" + (i > 0 ? "-" + i : "");
163
+                        Files.move(file, identitiesDirectory.resolve(target + suffix));
164
+                        success = true;
165
+                    } catch (IOException ex) {
166
+                        success = false;
167
+                    }
158 168
                 }
159 169
 
160 170
                 if (!success) {
@@ -162,22 +172,33 @@ public class IdentityManager implements IdentityFactory, IdentityController {
162 172
                             "Unable to create directory for default settings folder ("
163 173
                             + target + ')',
164 174
                             "A file with that name already exists, and couldn't be renamed."
165
-                            + " Rename or delete " + file.getAbsolutePath()));
175
+                            + " Rename or delete " + file));
166 176
                     continue;
167 177
                 }
168 178
             }
169 179
 
170
-            if (!file.exists() && !file.mkdirs()) {
171
-                eventBus.publishAsync(new UserErrorEvent(ErrorLevel.FATAL, null,
172
-                        "Unable to create required directory '" + file.getAbsolutePath()
173
-                        + "'. Please check file permissions or specify "
174
-                        + "a different configuration directory.", ""));
175
-                return;
180
+            if (!Files.exists(file)) {
181
+                try {
182
+                    Files.createDirectories(file);
183
+                } catch (IOException ex) {
184
+                    eventBus.publishAsync(new UserErrorEvent(ErrorLevel.FATAL, null,
185
+                            "Unable to create required directory '" + file + "'. Please check " +
186
+                                    "file permissions or specify a different configuration " +
187
+                                    "directory.", ""));
188
+                    return;
189
+                }
176 190
             }
177 191
 
178
-            final File[] files = file.listFiles();
179
-            if (files == null || files.length == 0) {
180
-                extractIdentities(target);
192
+            try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(file)) {
193
+                if (!directoryStream.iterator().hasNext()) {
194
+                    extractIdentities(target);
195
+                }
196
+            } catch (IOException ex) {
197
+                eventBus.publishAsync(new UserErrorEvent(ErrorLevel.FATAL, null,
198
+                        "Unable to iterate required directory '" + file + "'. Please check " +
199
+                                "file permissions or specify a different configuration " +
200
+                                "directory.", ""));
201
+                return;
181 202
             }
182 203
 
183 204
             loadUser(file);
@@ -196,7 +217,7 @@ public class IdentityManager implements IdentityFactory, IdentityController {
196 217
 
197 218
             if (bundledVersion.compareTo(installedVersion) > 0) {
198 219
                 extractIdentities("default");
199
-                loadUser(new File(identitiesDirectory, "default"));
220
+                loadUser(identitiesDirectory.resolve("default"));
200 221
             }
201 222
         }
202 223
     }
@@ -233,19 +254,16 @@ public class IdentityManager implements IdentityFactory, IdentityController {
233 254
 
234 255
     @Override
235 256
     public void loadUserIdentities() {
236
-        final File dir = new File(identitiesDirectory);
237
-
238
-        if (!dir.exists()) {
257
+        if (!Files.exists(identitiesDirectory)) {
239 258
             try {
240
-                dir.mkdirs();
241
-                dir.createNewFile();
259
+                Files.createDirectories(identitiesDirectory);
242 260
             } catch (IOException ex) {
243 261
                 eventBus.publishAsync(new UserErrorEvent(ErrorLevel.MEDIUM, ex,
244 262
                         "Unable to create identity dir", ""));
245 263
             }
246 264
         }
247 265
 
248
-        loadUser(dir);
266
+        loadUser(identitiesDirectory);
249 267
     }
250 268
 
251 269
     /**
@@ -257,22 +275,21 @@ public class IdentityManager implements IdentityFactory, IdentityController {
257 275
         "The specified File is not null",
258 276
         "The specified File is a directory"
259 277
     })
260
-    private void loadUser(final File dir) {
278
+    private void loadUser(final Path dir) {
261 279
         checkNotNull(dir);
262
-        checkArgument(dir.isDirectory());
280
+        checkArgument(Files.isDirectory(dir));
263 281
 
264
-        final File[] files = dir.listFiles();
265
-        if (files == null) {
266
-            eventBus.publishAsync(new UserErrorEvent(ErrorLevel.MEDIUM, null,
267
-                    "Unable to load user identity files from " + dir.getAbsolutePath(), ""));
268
-        } else {
269
-            for (File file : files) {
270
-                if (file.isDirectory()) {
271
-                    loadUser(file);
282
+        try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(dir)) {
283
+            for (Path child : directoryStream) {
284
+                if (Files.isDirectory(child)) {
285
+                    loadUser(child);
272 286
                 } else {
273
-                    loadIdentity(file);
287
+                    loadIdentity(child);
274 288
                 }
275 289
             }
290
+        } catch (IOException ex) {
291
+            eventBus.publishAsync(new UserErrorEvent(ErrorLevel.MEDIUM, ex,
292
+                    "Unable to load user identity files from " + dir, ""));
276 293
         }
277 294
     }
278 295
 
@@ -282,37 +299,31 @@ public class IdentityManager implements IdentityFactory, IdentityController {
282 299
      *
283 300
      * @param file The file to load the identity from.
284 301
      */
285
-    private void loadIdentity(final File file) {
302
+    private void loadIdentity(final Path file) {
286 303
         synchronized (identities) {
287
-            for (ConfigProvider identity : getAllIdentities()) {
288
-                if (identity instanceof ConfigFileBackedConfigProvider
289
-                        && ((ConfigFileBackedConfigProvider) identity).isFile(file)) {
290
-                    // TODO: This manager should keep a list of files->identities instead of
291
-                    //       relying on the identities remembering.
292
-                    try {
293
-                        identity.reload();
294
-                    } catch (IOException ex) {
295
-                        eventBus.publishAsync(new UserErrorEvent(ErrorLevel.MEDIUM, null,
296
-                                "I/O error when reloading identity file: "
297
-                                + file.getAbsolutePath() + " (" + ex.getMessage() + ')', ""));
298
-                    } catch (InvalidConfigFileException ex) {
299
-                        // Do nothing
300
-                    }
301
-
302
-                    return;
304
+            if (configProvidersByPath.containsKey(file)) {
305
+                try {
306
+                    configProvidersByPath.get(file).reload();
307
+                } catch (IOException ex) {
308
+                    eventBus.publishAsync(new UserErrorEvent(ErrorLevel.MEDIUM, null,
309
+                            "I/O error when reloading identity file: "
310
+                                    + file + " (" + ex.getMessage() + ')', ""));
311
+                } catch (InvalidConfigFileException ex) {
312
+                    // Do nothing
303 313
                 }
304 314
             }
305 315
         }
306 316
 
307 317
         try {
308
-            addConfigProvider(new ConfigFileBackedConfigProvider(this, file, false));
318
+            final ConfigProvider provider = new ConfigFileBackedConfigProvider(this, file, false);
319
+            addConfigProvider(provider);
320
+            configProvidersByPath.put(file, provider);
309 321
         } catch (InvalidIdentityFileException ex) {
310 322
             eventBus.publishAsync(new UserErrorEvent(ErrorLevel.MEDIUM, null,
311
-                    "Invalid identity file: " + file.getAbsolutePath() + " ("
312
-                    + ex.getMessage() + ')', ""));
323
+                    "Invalid identity file: " + file + " (" + ex.getMessage() + ')', ""));
313 324
         } catch (IOException ex) {
314 325
             eventBus.publishAsync(new UserErrorEvent(ErrorLevel.MEDIUM, null,
315
-                    "I/O error when reading identity file: " + file.getAbsolutePath(), ""));
326
+                    "I/O error when reading identity file: " + file, ""));
316 327
         }
317 328
     }
318 329
 
@@ -367,14 +378,15 @@ public class IdentityManager implements IdentityFactory, IdentityController {
367 378
      */
368 379
     private void loadConfig() throws InvalidIdentityFileException {
369 380
         try {
370
-            final File file = new File(configDirectory + "dmdirc.config");
381
+            final Path file = configDirectory.resolve("dmdirc.config");
371 382
 
372
-            if (!file.exists()) {
373
-                file.createNewFile();
383
+            if (!Files.exists(file)) {
384
+                Files.createFile(file);
374 385
             }
375 386
 
376 387
             config = new ConfigFileBackedConfigProvider(this, file, true);
377 388
             config.setOption("identity", "name", "Global config");
389
+            configProvidersByPath.put(file, config);
378 390
             addConfigProvider(config);
379 391
         } catch (IOException ex) {
380 392
             eventBus.publishAsync(new UserErrorEvent(ErrorLevel.MEDIUM, ex,
@@ -437,6 +449,17 @@ public class IdentityManager implements IdentityFactory, IdentityController {
437 449
 
438 450
         checkArgument(identities.containsValue(group, identity));
439 451
 
452
+        Path path = null;
453
+        for (Map.Entry<Path, ConfigProvider> entry : configProvidersByPath.entrySet()) {
454
+            if (entry.getValue() == identity) {
455
+                path = entry.getKey();
456
+            }
457
+        }
458
+
459
+        if (path != null) {
460
+            configProvidersByPath.remove(path);
461
+        }
462
+
440 463
         synchronized (identities) {
441 464
             identities.remove(group, identity);
442 465
         }
@@ -663,11 +686,11 @@ public class IdentityManager implements IdentityFactory, IdentityController {
663 686
 
664 687
         final String name = settings.get(IDENTITY_DOMAIN).get("name").replaceAll(ILLEGAL_CHARS, "_");
665 688
 
666
-        File file = new File(identitiesDirectory + name);
689
+        Path file = identitiesDirectory.resolve(name);
667 690
         int attempt = 1;
668 691
 
669
-        while (file.exists()) {
670
-            file = new File(identitiesDirectory + name + '-' + attempt);
692
+        while (Files.exists(file)) {
693
+            file = identitiesDirectory.resolve(name + '-' + attempt);
671 694
             attempt++;
672 695
         }
673 696
 

+ 1
- 1
test/com/dmdirc/config/IdentityTest.java Visa fil

@@ -141,7 +141,7 @@ public class IdentityTest {
141 141
         myIdent.save();
142 142
 
143 143
         myIdent = new ConfigFileBackedConfigProvider(identityManager,
144
-                myIdent.file.getFile(), false);
144
+                myIdent.file.getFile().toPath(), false);
145 145
 
146 146
         assertEquals("baz!", myIdent.getOption("foo", "bar"));
147 147
     }

Laddar…
Avbryt
Spara