Skip to content

Commit a23178f

Browse files
committed
Improve file/folder access and creation for a better reliabillity
1 parent 5b5293f commit a23178f

File tree

17 files changed

+204
-281
lines changed

17 files changed

+204
-281
lines changed

BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/BlueMapService.java

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,11 @@
2424
*/
2525
package de.bluecolored.bluemap.common;
2626

27-
import java.io.File;
28-
import java.io.IOException;
29-
import java.net.URL;
30-
import java.util.ArrayList;
31-
import java.util.Arrays;
32-
import java.util.Collections;
33-
import java.util.HashMap;
34-
import java.util.List;
35-
import java.util.Map;
36-
import java.util.UUID;
37-
38-
import org.apache.commons.io.FileUtils;
39-
4027
import com.flowpowered.math.vector.Vector2i;
41-
4228
import de.bluecolored.bluemap.common.plugin.Plugin;
4329
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
4430
import de.bluecolored.bluemap.core.MinecraftVersion;
45-
import de.bluecolored.bluemap.core.config.ConfigManager;
46-
import de.bluecolored.bluemap.core.config.CoreConfig;
47-
import de.bluecolored.bluemap.core.config.MapConfig;
48-
import de.bluecolored.bluemap.core.config.RenderConfig;
49-
import de.bluecolored.bluemap.core.config.WebServerConfig;
31+
import de.bluecolored.bluemap.core.config.*;
5032
import de.bluecolored.bluemap.core.logger.Logger;
5133
import de.bluecolored.bluemap.core.mca.MCAWorld;
5234
import de.bluecolored.bluemap.core.render.RenderSettings;
@@ -58,6 +40,12 @@
5840
import de.bluecolored.bluemap.core.web.WebSettings;
5941
import de.bluecolored.bluemap.core.world.SlicedWorld;
6042
import de.bluecolored.bluemap.core.world.World;
43+
import org.apache.commons.io.FileUtils;
44+
45+
import java.io.File;
46+
import java.io.IOException;
47+
import java.net.URL;
48+
import java.util.*;
6149

6250
/**
6351
* This is the attempt to generalize as many actions as possible to have CLI and Plugins run on the same general setup-code.
@@ -219,19 +207,23 @@ private synchronized void loadWorldsAndMaps() throws IOException, InterruptedExc
219207
maps = Collections.unmodifiableMap(maps);
220208
}
221209

222-
public synchronized ResourcePack getResourcePack() throws IOException, MissingResourcesException, InterruptedException {
210+
public synchronized ResourcePack getResourcePack() throws IOException, InterruptedException {
223211
if (resourcePack == null) {
224212
File defaultResourceFile = new File(getCoreConfig().getDataFolder(), "minecraft-client-" + minecraftVersion.getVersionString() + ".jar");
225213
File resourceExtensionsFile = new File(getCoreConfig().getDataFolder(), "resourceExtensions.zip");
226214

227215
File textureExportFile = new File(getRenderConfig().getWebRoot(), "data" + File.separator + "textures.json");
216+
217+
File resourcePackFolder = new File(configFolder, "resourcepacks");
218+
FileUtils.forceMkdir(resourcePackFolder);
228219

229220
if (!defaultResourceFile.exists()) {
230221
if (getCoreConfig().isDownloadAccepted()) {
231222

232223
//download file
233224
try {
234225
Logger.global.logInfo("Downloading " + minecraftVersion.getClientDownloadUrl() + " to " + defaultResourceFile + " ...");
226+
FileUtils.forceMkdirParent(defaultResourceFile);
235227
FileUtils.copyURLToFile(new URL(minecraftVersion.getClientDownloadUrl()), defaultResourceFile, 10000, 10000);
236228
} catch (IOException e) {
237229
throw new IOException("Failed to download resources!", e);
@@ -244,18 +236,18 @@ public synchronized ResourcePack getResourcePack() throws IOException, MissingRe
244236

245237
Logger.global.logInfo("Loading resources...");
246238

247-
resourceExtensionsFile.delete();
239+
if (resourceExtensionsFile.exists()) FileUtils.forceDelete(resourceExtensionsFile);
240+
FileUtils.forceMkdirParent(resourceExtensionsFile);
248241
FileUtils.copyURLToFile(Plugin.class.getResource("/de/bluecolored/bluemap/" + minecraftVersion.getResourcePrefix() + "/resourceExtensions.zip"), resourceExtensionsFile, 10000, 10000);
249242

250243
//find more resource packs
251-
File resourcePackFolder = new File(configFolder, "resourcepacks");
252-
resourcePackFolder.mkdirs();
253244
File[] resourcePacks = resourcePackFolder.listFiles();
245+
if (resourcePacks == null) resourcePacks = new File[0];
254246
Arrays.sort(resourcePacks); //load resource packs in alphabetical order so you can reorder them by renaming
255247

256248
List<File> resources = new ArrayList<>(resourcePacks.length + 1);
257249
resources.add(defaultResourceFile);
258-
for (File file : resourcePacks) resources.add(file);
250+
resources.addAll(Arrays.asList(resourcePacks));
259251
resources.add(resourceExtensionsFile);
260252

261253
try {
@@ -272,7 +264,7 @@ public synchronized ResourcePack getResourcePack() throws IOException, MissingRe
272264
return resourcePack;
273265
}
274266

275-
public synchronized ConfigManager getConfigManager() throws IOException {
267+
public synchronized ConfigManager getConfigManager() {
276268
return configManager;
277269
}
278270

BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/WebFilesManager.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,10 @@ public void updateFiles() throws IOException {
5858
ZipEntry zipEntry = entries.nextElement();
5959
if (zipEntry.isDirectory()) {
6060
File dir = new File(webRoot, zipEntry.getName());
61-
if (!dir.mkdirs()) {
62-
Logger.global.logWarning("Failed to create directory: " + dir);
63-
}
61+
FileUtils.forceMkdir(dir);
6462
} else {
6563
File target = new File(webRoot, zipEntry.getName());
64+
FileUtils.forceMkdirParent(target);
6665
FileUtils.copyInputStreamToFile(zipFile.getInputStream(zipEntry), target);
6766
}
6867
}

BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/api/BlueMapAPIImpl.java

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,6 @@
2424
*/
2525
package de.bluecolored.bluemap.common.api;
2626

27-
import java.awt.image.BufferedImage;
28-
import java.io.File;
29-
import java.io.IOException;
30-
import java.nio.file.FileSystems;
31-
import java.nio.file.Path;
32-
import java.nio.file.Paths;
33-
import java.util.Collection;
34-
import java.util.Collections;
35-
import java.util.HashMap;
36-
import java.util.Map;
37-
import java.util.Optional;
38-
import java.util.UUID;
39-
import java.util.concurrent.ExecutionException;
40-
41-
import javax.imageio.ImageIO;
42-
4327
import de.bluecolored.bluemap.api.BlueMapAPI;
4428
import de.bluecolored.bluemap.api.BlueMapMap;
4529
import de.bluecolored.bluemap.api.BlueMapWorld;
@@ -50,6 +34,17 @@
5034
import de.bluecolored.bluemap.core.BlueMap;
5135
import de.bluecolored.bluemap.core.logger.Logger;
5236
import de.bluecolored.bluemap.core.world.World;
37+
import org.apache.commons.io.FileUtils;
38+
39+
import javax.imageio.ImageIO;
40+
import java.awt.image.BufferedImage;
41+
import java.io.File;
42+
import java.io.IOException;
43+
import java.nio.file.FileSystems;
44+
import java.nio.file.Path;
45+
import java.nio.file.Paths;
46+
import java.util.*;
47+
import java.util.concurrent.ExecutionException;
5348

5449
public class BlueMapAPIImpl extends BlueMapAPI {
5550

@@ -109,9 +104,8 @@ public String createImage(BufferedImage image, String path) throws IOException {
109104
Path imagePath = webDataRoot.resolve(Paths.get(IMAGE_ROOT_PATH, path.replace("/", separator) + ".png")).toAbsolutePath();
110105

111106
File imageFile = imagePath.toFile();
112-
imageFile.getParentFile().mkdirs();
113-
imageFile.delete();
114-
imageFile.createNewFile();
107+
if (imageFile.exists()) FileUtils.forceDelete(imageFile);
108+
de.bluecolored.bluemap.core.util.FileUtils.createFile(imageFile);
115109

116110
if (!ImageIO.write(image, "png", imagePath.toFile()))
117111
throw new IOException("The format 'png' is not supported!");

BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/api/marker/MarkerAPIImpl.java

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,20 @@
2424
*/
2525
package de.bluecolored.bluemap.common.api.marker;
2626

27-
import java.io.File;
28-
import java.io.IOException;
29-
import java.util.Collection;
30-
import java.util.Collections;
31-
import java.util.HashSet;
32-
import java.util.Map;
33-
import java.util.Optional;
34-
import java.util.Set;
35-
import java.util.concurrent.ConcurrentHashMap;
36-
3727
import com.google.common.collect.Sets;
38-
3928
import de.bluecolored.bluemap.api.marker.MarkerAPI;
4029
import de.bluecolored.bluemap.api.marker.MarkerSet;
4130
import de.bluecolored.bluemap.common.api.BlueMapAPIImpl;
4231
import de.bluecolored.bluemap.core.logger.Logger;
32+
import de.bluecolored.bluemap.core.util.FileUtils;
4333
import ninja.leaping.configurate.ConfigurationNode;
4434
import ninja.leaping.configurate.gson.GsonConfigurationLoader;
4535

36+
import java.io.File;
37+
import java.io.IOException;
38+
import java.util.*;
39+
import java.util.concurrent.ConcurrentHashMap;
40+
4641
public class MarkerAPIImpl implements MarkerAPI {
4742

4843
private BlueMapAPIImpl api;
@@ -98,37 +93,35 @@ public synchronized void load() throws IOException {
9893
}
9994

10095
private synchronized void load(boolean overwriteChanges) throws IOException {
101-
if (!markerFile.exists()) {
102-
markerFile.getParentFile().mkdirs();
103-
markerFile.createNewFile();
104-
}
105-
106-
GsonConfigurationLoader loader = GsonConfigurationLoader.builder().setFile(markerFile).build();
107-
ConfigurationNode node = loader.load();
108-
10996
Set<String> externallyRemovedSets = new HashSet<>(markerSets.keySet());
110-
for (ConfigurationNode markerSetNode : node.getNode("markerSets").getChildrenList()) {
111-
String setId = markerSetNode.getNode("id").getString();
112-
if (setId == null) {
113-
Logger.global.logDebug("Marker-API: Failed to load a markerset: No id defined!");
114-
continue;
115-
}
116-
117-
externallyRemovedSets.remove(setId);
118-
if (!overwriteChanges && removedMarkerSets.contains(setId)) continue;
119-
120-
MarkerSetImpl set = markerSets.get(setId);
121-
122-
try {
123-
if (set == null) {
124-
set = new MarkerSetImpl(setId);
125-
set.load(api, markerSetNode, true);
126-
} else {
127-
set.load(api, markerSetNode, overwriteChanges);
97+
98+
if (markerFile.exists() && markerFile.isFile()) {
99+
GsonConfigurationLoader loader = GsonConfigurationLoader.builder().setFile(markerFile).build();
100+
ConfigurationNode node = loader.load();
101+
102+
for (ConfigurationNode markerSetNode : node.getNode("markerSets").getChildrenList()) {
103+
String setId = markerSetNode.getNode("id").getString();
104+
if (setId == null) {
105+
Logger.global.logDebug("Marker-API: Failed to load a markerset: No id defined!");
106+
continue;
107+
}
108+
109+
externallyRemovedSets.remove(setId);
110+
if (!overwriteChanges && removedMarkerSets.contains(setId)) continue;
111+
112+
MarkerSetImpl set = markerSets.get(setId);
113+
114+
try {
115+
if (set == null) {
116+
set = new MarkerSetImpl(setId);
117+
set.load(api, markerSetNode, true);
118+
} else {
119+
set.load(api, markerSetNode, overwriteChanges);
120+
}
121+
markerSets.put(setId, set);
122+
} catch (MarkerFileFormatException ex) {
123+
Logger.global.logDebug("Marker-API: Failed to load marker-set '" + setId + ": " + ex);
128124
}
129-
markerSets.put(setId, set);
130-
} catch (MarkerFileFormatException ex) {
131-
Logger.global.logDebug("Marker-API: Failed to load marker-set '" + setId + ": " + ex);
132125
}
133126
}
134127

@@ -144,7 +137,9 @@ private synchronized void load(boolean overwriteChanges) throws IOException {
144137
@Override
145138
public synchronized void save() throws IOException {
146139
load(false);
147-
140+
141+
FileUtils.createFile(markerFile);
142+
148143
GsonConfigurationLoader loader = GsonConfigurationLoader.builder().setFile(markerFile).build();
149144
ConfigurationNode node = loader.createEmptyNode();
150145

BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/Plugin.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import de.bluecolored.bluemap.core.logger.Logger;
3838
import de.bluecolored.bluemap.core.metrics.Metrics;
3939
import de.bluecolored.bluemap.core.resourcepack.ParseResourceException;
40+
import de.bluecolored.bluemap.core.util.FileUtils;
4041
import de.bluecolored.bluemap.core.web.FileRequestHandler;
4142
import de.bluecolored.bluemap.core.webserver.HttpRequestHandler;
4243
import de.bluecolored.bluemap.core.webserver.WebServer;
@@ -110,6 +111,7 @@ public void load() throws IOException, ParseResourceException {
110111

111112
//create and start webserver
112113
if (webServerConfig.isWebserverEnabled()) {
114+
FileUtils.mkDirs(webServerConfig.getWebRoot());
113115
HttpRequestHandler requestHandler = new FileRequestHandler(webServerConfig.getWebRoot().toPath(), "BlueMap v" + BlueMap.VERSION);
114116

115117
//inject live api if enabled
@@ -120,7 +122,7 @@ public void load() throws IOException, ParseResourceException {
120122
webServer = new WebServer(
121123
webServerConfig.getWebserverPort(),
122124
webServerConfig.getWebserverMaxConnections(),
123-
webServerConfig.getWebserverBindAdress(),
125+
webServerConfig.getWebserverBindAddress(),
124126
requestHandler,
125127
false
126128
);
@@ -305,8 +307,8 @@ public void unload() {
305307
public void saveRenderManagerState() throws IOException {
306308
File saveFile = getRenderManagerSaveFile();
307309

308-
if (saveFile.exists()) saveFile.delete();
309-
saveFile.createNewFile();
310+
if (saveFile.exists()) FileUtils.delete(saveFile);
311+
FileUtils.createFile(saveFile);
310312

311313
try (DataOutputStream out = new DataOutputStream(new GZIPOutputStream(new FileOutputStream(saveFile)))) {
312314
renderManager.writeState(out);
@@ -356,11 +358,7 @@ public RenderManager getRenderManager() {
356358

357359
public File getRenderManagerSaveFile() throws IOException {
358360
if (blueMap == null) return null;
359-
360-
File saveFile = new File(blueMap.getCoreConfig().getDataFolder(), "rmstate");
361-
saveFile.getParentFile().mkdirs();
362-
363-
return saveFile;
361+
return new File(blueMap.getCoreConfig().getDataFolder(), "rmstate");
364362
}
365363

366364
public MapUpdateHandler getUpdateHandler() {

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/ConfigManager.java

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,26 @@
2424
*/
2525
package de.bluecolored.bluemap.core.config;
2626

27-
import java.io.BufferedReader;
28-
import java.io.File;
29-
import java.io.IOException;
30-
import java.io.InputStream;
31-
import java.io.InputStreamReader;
32-
import java.net.URL;
33-
import java.nio.charset.StandardCharsets;
34-
import java.nio.file.Files;
35-
import java.time.LocalDateTime;
36-
import java.util.HashSet;
37-
import java.util.Set;
38-
import java.util.stream.Collectors;
39-
4027
import com.google.common.base.Preconditions;
41-
4228
import de.bluecolored.bluemap.core.BlueMap;
4329
import de.bluecolored.bluemap.core.logger.Logger;
4430
import de.bluecolored.bluemap.core.resourcepack.ResourcePack;
4531
import de.bluecolored.bluemap.core.resourcepack.ResourcePack.Resource;
32+
import de.bluecolored.bluemap.core.util.FileUtils;
4633
import ninja.leaping.configurate.ConfigurationNode;
4734
import ninja.leaping.configurate.gson.GsonConfigurationLoader;
4835
import ninja.leaping.configurate.hocon.HoconConfigurationLoader;
4936
import ninja.leaping.configurate.loader.ConfigurationLoader;
5037

38+
import java.io.*;
39+
import java.net.URL;
40+
import java.nio.charset.StandardCharsets;
41+
import java.nio.file.Files;
42+
import java.time.LocalDateTime;
43+
import java.util.HashSet;
44+
import java.util.Set;
45+
import java.util.stream.Collectors;
46+
5147
public class ConfigManager {
5248

5349
private static final Set<Placeholder> CONFIG_PLACEHOLDERS = new HashSet<>();
@@ -76,7 +72,7 @@ public ConfigurationNode loadOrCreate(File configFile, URL defaultConfig, URL de
7672

7773
ConfigurationNode configNode;
7874
if (!configFile.exists()) {
79-
configFile.getParentFile().mkdirs();
75+
FileUtils.mkDirsParent(configFile);
8076

8177
if (defaultConfig != null) {
8278
//load content of default config

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/CoreConfig.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424
*/
2525
package de.bluecolored.bluemap.core.config;
2626

27+
import ninja.leaping.configurate.ConfigurationNode;
28+
2729
import java.io.File;
2830
import java.io.IOException;
2931

30-
import ninja.leaping.configurate.ConfigurationNode;
31-
3232
public class CoreConfig {
3333

3434
private boolean downloadAccepted = false;
@@ -57,7 +57,6 @@ public CoreConfig(ConfigurationNode node) throws IOException {
5757
}
5858

5959
public File getDataFolder() {
60-
if (!dataFolder.exists()) dataFolder.mkdirs();
6160
return dataFolder;
6261
}
6362

0 commit comments

Comments
 (0)