2019-11-02 17:23:48 +01:00
|
|
|
/*
|
|
|
|
* This file is part of BlueMap, licensed under the MIT License (MIT).
|
|
|
|
*
|
|
|
|
* Copyright (c) Blue (Lukas Rieger) <https://bluecolored.de>
|
|
|
|
* Copyright (c) contributors
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
|
|
* in the Software without restriction, including without limitation the rights
|
|
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
* THE SOFTWARE.
|
|
|
|
*/
|
2021-03-18 22:55:07 +01:00
|
|
|
package de.bluecolored.bluemap.common;
|
|
|
|
|
2023-11-08 13:27:51 +01:00
|
|
|
import com.google.gson.FieldNamingPolicy;
|
|
|
|
import com.google.gson.Gson;
|
2022-07-31 18:58:59 +02:00
|
|
|
import com.google.gson.GsonBuilder;
|
2022-06-06 22:51:26 +02:00
|
|
|
import de.bluecolored.bluemap.common.config.WebappConfig;
|
2022-09-12 12:02:36 +02:00
|
|
|
import de.bluecolored.bluemap.core.BlueMap;
|
2021-03-18 22:55:07 +01:00
|
|
|
import de.bluecolored.bluemap.core.logger.Logger;
|
2022-06-06 22:51:26 +02:00
|
|
|
import de.bluecolored.bluemap.core.resources.adapter.ResourcesGson;
|
2022-10-14 10:24:19 +02:00
|
|
|
import de.bluecolored.bluemap.core.util.FileHelper;
|
2021-03-18 22:55:07 +01:00
|
|
|
import org.apache.commons.io.FileUtils;
|
2019-11-02 17:23:48 +01:00
|
|
|
|
2022-06-06 22:51:26 +02:00
|
|
|
import java.io.BufferedReader;
|
|
|
|
import java.io.BufferedWriter;
|
2019-11-02 17:23:48 +01:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.net.URL;
|
2022-04-20 22:54:27 +02:00
|
|
|
import java.nio.file.Files;
|
|
|
|
import java.nio.file.Path;
|
2022-06-06 22:51:26 +02:00
|
|
|
import java.nio.file.StandardOpenOption;
|
2024-01-17 18:27:44 +01:00
|
|
|
import java.util.Enumeration;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.Set;
|
2019-11-02 17:23:48 +01:00
|
|
|
import java.util.zip.ZipEntry;
|
|
|
|
import java.util.zip.ZipFile;
|
|
|
|
|
|
|
|
public class WebFilesManager {
|
|
|
|
|
2023-11-08 13:27:51 +01:00
|
|
|
private static final Gson GSON = ResourcesGson.addAdapter(new GsonBuilder())
|
|
|
|
.setFieldNamingPolicy(FieldNamingPolicy.IDENTITY)
|
2024-01-25 15:11:11 +01:00
|
|
|
//.setPrettyPrinting() // enable pretty printing for easy editing
|
2023-11-08 13:27:51 +01:00
|
|
|
.create();
|
|
|
|
|
2022-04-20 22:54:27 +02:00
|
|
|
private final Path webRoot;
|
2022-06-06 22:51:26 +02:00
|
|
|
private Settings settings;
|
2021-09-19 22:15:50 +02:00
|
|
|
|
2022-04-20 22:54:27 +02:00
|
|
|
public WebFilesManager(Path webRoot) {
|
2021-09-19 22:15:50 +02:00
|
|
|
this.webRoot = webRoot;
|
2022-06-06 22:51:26 +02:00
|
|
|
this.settings = new Settings();
|
2021-09-19 22:15:50 +02:00
|
|
|
}
|
|
|
|
|
2022-06-06 22:51:26 +02:00
|
|
|
public Path getSettingsFile() {
|
2022-06-27 01:13:48 +02:00
|
|
|
return webRoot.resolve("settings.json");
|
2022-06-06 22:51:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void loadSettings() throws IOException {
|
|
|
|
try (BufferedReader reader = Files.newBufferedReader(getSettingsFile())) {
|
2023-11-08 13:27:51 +01:00
|
|
|
this.settings = GSON.fromJson(reader, Settings.class);
|
2022-06-06 22:51:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void saveSettings() throws IOException {
|
2022-10-14 10:24:19 +02:00
|
|
|
FileHelper.createDirectories(getSettingsFile().getParent());
|
2022-06-06 22:51:26 +02:00
|
|
|
try (BufferedWriter writer = Files.newBufferedWriter(getSettingsFile(),
|
|
|
|
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
|
2023-11-08 13:27:51 +01:00
|
|
|
GSON.toJson(this.settings, writer);
|
2022-06-06 22:51:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void resetSettings() {
|
|
|
|
this.settings = new Settings();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addMap(String mapId) {
|
|
|
|
this.settings.maps.add(mapId);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void removeMap(String mapId) {
|
|
|
|
this.settings.maps.remove(mapId);
|
|
|
|
}
|
|
|
|
|
2022-12-13 16:54:31 +01:00
|
|
|
public Set<String> getScripts() {
|
|
|
|
return this.settings.scripts;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Set<String> getStyles() {
|
|
|
|
return this.settings.styles;
|
|
|
|
}
|
|
|
|
|
2022-06-06 22:51:26 +02:00
|
|
|
public void setFrom(WebappConfig webappConfig) {
|
|
|
|
this.settings.setFrom(webappConfig);
|
|
|
|
}
|
|
|
|
|
2022-12-13 16:54:31 +01:00
|
|
|
public void addFrom(WebappConfig webappConfig) {
|
|
|
|
this.settings.addFrom(webappConfig);
|
|
|
|
}
|
|
|
|
|
2022-06-06 22:51:26 +02:00
|
|
|
public boolean filesNeedUpdate() {
|
2022-04-20 22:54:27 +02:00
|
|
|
return !Files.exists(webRoot.resolve("index.html"));
|
2021-09-19 22:15:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void updateFiles() throws IOException {
|
|
|
|
URL fileResource = getClass().getResource("/de/bluecolored/bluemap/webapp.zip");
|
|
|
|
File tempFile = File.createTempFile("bluemap_webroot_extraction", null);
|
|
|
|
|
2022-04-20 22:54:27 +02:00
|
|
|
if (fileResource == null) throw new IOException("Failed to open bundled webapp.");
|
|
|
|
|
2021-09-19 22:15:50 +02:00
|
|
|
try {
|
|
|
|
FileUtils.copyURLToFile(fileResource, tempFile, 10000, 10000);
|
|
|
|
try (ZipFile zipFile = new ZipFile(tempFile)){
|
|
|
|
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
|
|
|
while(entries.hasMoreElements()) {
|
|
|
|
ZipEntry zipEntry = entries.nextElement();
|
|
|
|
if (zipEntry.isDirectory()) {
|
2022-04-20 22:54:27 +02:00
|
|
|
File dir = webRoot.resolve(zipEntry.getName()).toFile();
|
2021-09-19 22:15:50 +02:00
|
|
|
FileUtils.forceMkdir(dir);
|
|
|
|
} else {
|
2022-04-20 22:54:27 +02:00
|
|
|
File target = webRoot.resolve(zipEntry.getName()).toFile();
|
2021-09-19 22:15:50 +02:00
|
|
|
FileUtils.forceMkdirParent(target);
|
|
|
|
FileUtils.copyInputStreamToFile(zipFile.getInputStream(zipEntry), target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-09-12 12:02:36 +02:00
|
|
|
|
|
|
|
// set version in index.html
|
|
|
|
Path indexFile = webRoot.resolve("index.html");
|
|
|
|
String indexContent = Files.readString(indexFile);
|
|
|
|
indexContent = indexContent.replace("%version%", BlueMap.VERSION);
|
|
|
|
Files.writeString(indexFile, indexContent);
|
|
|
|
|
2021-09-19 22:15:50 +02:00
|
|
|
} finally {
|
|
|
|
if (!tempFile.delete()) {
|
|
|
|
Logger.global.logWarning("Failed to delete file: " + tempFile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-04 14:42:12 +02:00
|
|
|
@SuppressWarnings({"FieldMayBeFinal", "FieldCanBeLocal", "unused", "MismatchedQueryAndUpdateOfCollection"})
|
2022-06-06 22:51:26 +02:00
|
|
|
private static class Settings {
|
|
|
|
|
2022-09-12 12:02:36 +02:00
|
|
|
private String version = BlueMap.VERSION;
|
|
|
|
|
2022-06-06 22:51:26 +02:00
|
|
|
private boolean useCookies = true;
|
|
|
|
|
|
|
|
private boolean enableFreeFlight = true;
|
2023-07-04 14:42:12 +02:00
|
|
|
private boolean defaultToFlatView = false;
|
2022-06-06 22:51:26 +02:00
|
|
|
|
|
|
|
private String startLocation = null;
|
|
|
|
|
|
|
|
private float resolutionDefault = 1;
|
|
|
|
|
2022-08-12 18:11:11 +02:00
|
|
|
private int minZoomDistance = 5;
|
|
|
|
private int maxZoomDistance = 100000;
|
|
|
|
|
2022-06-06 22:51:26 +02:00
|
|
|
private int hiresSliderMax = 500;
|
|
|
|
private int hiresSliderDefault = 200;
|
|
|
|
private int hiresSliderMin = 50;
|
|
|
|
|
|
|
|
private int lowresSliderMax = 10000;
|
|
|
|
private int lowresSliderDefault = 2000;
|
|
|
|
private int lowresSliderMin = 500;
|
|
|
|
|
|
|
|
private Set<String> maps = new HashSet<>();
|
2022-12-13 16:54:31 +01:00
|
|
|
private Set<String> scripts = new HashSet<>();
|
|
|
|
private Set<String> styles = new HashSet<>();
|
2022-06-06 22:51:26 +02:00
|
|
|
|
|
|
|
public void setFrom(WebappConfig config) {
|
|
|
|
this.useCookies = config.isUseCookies();
|
|
|
|
this.enableFreeFlight = config.isEnableFreeFlight();
|
2023-07-04 14:42:12 +02:00
|
|
|
this.defaultToFlatView = config.isDefaultToFlatView();
|
2022-06-06 22:51:26 +02:00
|
|
|
this.startLocation = config.getStartLocation().orElse(null);
|
|
|
|
this.resolutionDefault = config.getResolutionDefault();
|
2022-08-12 18:11:11 +02:00
|
|
|
|
|
|
|
this.minZoomDistance = config.getMinZoomDistance();
|
|
|
|
this.maxZoomDistance = config.getMaxZoomDistance();
|
2022-12-13 16:54:31 +01:00
|
|
|
|
2022-06-06 22:51:26 +02:00
|
|
|
this.hiresSliderMax = config.getHiresSliderMax();
|
2022-08-07 08:35:16 +02:00
|
|
|
this.hiresSliderDefault = config.getHiresSliderDefault();
|
2022-06-06 22:51:26 +02:00
|
|
|
this.hiresSliderMin = config.getHiresSliderMin();
|
2022-12-13 16:54:31 +01:00
|
|
|
|
2022-06-06 22:51:26 +02:00
|
|
|
this.lowresSliderMax = config.getLowresSliderMax();
|
|
|
|
this.lowresSliderDefault = config.getLowresSliderDefault();
|
|
|
|
this.lowresSliderMin = config.getLowresSliderMin();
|
2022-12-13 16:54:31 +01:00
|
|
|
|
|
|
|
this.styles.clear();
|
|
|
|
this.scripts.clear();
|
|
|
|
|
|
|
|
addFrom(config);
|
2022-06-06 22:51:26 +02:00
|
|
|
}
|
2022-12-13 16:54:31 +01:00
|
|
|
|
|
|
|
public void addFrom(WebappConfig config) {
|
|
|
|
this.scripts.addAll(config.getScripts());
|
|
|
|
this.styles.addAll(config.getStyles());
|
|
|
|
}
|
|
|
|
|
2022-06-06 22:51:26 +02:00
|
|
|
}
|
|
|
|
|
2019-11-02 17:23:48 +01:00
|
|
|
}
|