mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-09-28 14:37:40 +02:00
Implemented ResourceSvc
- Customizable resources - Snippets - Fixed issue with a web resource being fetched on enable (favicon in ResponseResolver) - Fixed some issues with Config#addNode used in an orElse block of Optional - Deprecated PlanFiles#getCustomizableResourceOrDefault
This commit is contained in:
parent
f2ba301880
commit
dae96ef53d
@ -16,8 +16,9 @@
|
||||
*/
|
||||
package com.djrapitops.plan.delivery.web;
|
||||
|
||||
import com.djrapitops.plan.delivery.web.resource.Resource;
|
||||
import com.djrapitops.plan.delivery.web.resource.WebResource;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
@ -27,15 +28,20 @@ import java.util.function.Supplier;
|
||||
*/
|
||||
public interface ResourceService {
|
||||
|
||||
static ResourceService getInstance() {
|
||||
return Optional.ofNullable(ResourceService.Holder.service)
|
||||
.orElseThrow(() -> new IllegalStateException("ResourceService has not been initialised yet."));
|
||||
}
|
||||
|
||||
/**
|
||||
* Make one of your web resources customizable by user or Plan API.
|
||||
*
|
||||
* @param pluginName Name of your plugin (for config purposes)
|
||||
* @param fileName Name of the file (for customization)
|
||||
* @param source Supplier to use to get the original resource.
|
||||
* @param source Supplier to use to get the original resource, it is assumed that any text based files are encoded in UTF-8.
|
||||
* @return Resource of the customized file.
|
||||
*/
|
||||
Resource getResource(String pluginName, String fileName, Supplier<Resource> source);
|
||||
WebResource getResource(String pluginName, String fileName, Supplier<WebResource> source);
|
||||
|
||||
/**
|
||||
* Add javascript to load in an existing html resource.
|
||||
@ -81,4 +87,16 @@ public interface ResourceService {
|
||||
*/
|
||||
BODY_END
|
||||
}
|
||||
|
||||
class Holder {
|
||||
static ResourceService service;
|
||||
|
||||
private Holder() {
|
||||
/* Static variable holder */
|
||||
}
|
||||
|
||||
static void set(ResourceService service) {
|
||||
ResourceService.Holder.service = service;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,18 +26,41 @@ import java.nio.charset.StandardCharsets;
|
||||
* Represents a customizable resource.
|
||||
* <p>
|
||||
* You can use the create methods for simple resources when using {@link com.djrapitops.plan.delivery.web.ResourceService}.
|
||||
* <p>
|
||||
* It is assumed that any text based files are encoded in UTF-8.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public interface Resource {
|
||||
public interface WebResource {
|
||||
|
||||
static Resource create(byte[] content) {
|
||||
/**
|
||||
* Create a new WebResource from byte array.
|
||||
*
|
||||
* @param content Bytes of the resource.
|
||||
* @return WebResource.
|
||||
*/
|
||||
static WebResource create(byte[] content) {
|
||||
return new ByteResource(content);
|
||||
}
|
||||
|
||||
static Resource create(String utf8String) {
|
||||
/**
|
||||
* Create a new WebResource from an UTF-8 String.
|
||||
*
|
||||
* @param utf8String String in UTF-8 encoding.
|
||||
* @return WebResource.
|
||||
*/
|
||||
static WebResource create(String utf8String) {
|
||||
return new ByteResource(utf8String.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
static Resource create(InputStream in) throws IOException {
|
||||
/**
|
||||
* Creates a new WebResource from an InputStream.
|
||||
*
|
||||
* @param in InputStream for the resource, closed after inside the method.
|
||||
* @return WebResource.
|
||||
* @throws IOException If the stream can not be read.
|
||||
*/
|
||||
static WebResource create(InputStream in) throws IOException {
|
||||
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
||||
int read;
|
||||
byte[] bytes = new byte[1024];
|
||||
@ -53,11 +76,16 @@ public interface Resource {
|
||||
|
||||
byte[] asBytes();
|
||||
|
||||
/**
|
||||
* Return the resource as a UTF-8 String.
|
||||
*
|
||||
* @return The resource in UTF-8.
|
||||
*/
|
||||
String asString();
|
||||
|
||||
InputStream asStream();
|
||||
|
||||
final class ByteResource implements Resource {
|
||||
final class ByteResource implements WebResource {
|
||||
private final byte[] content;
|
||||
|
||||
public ByteResource(byte[] content) {
|
@ -17,10 +17,10 @@
|
||||
package com.djrapitops.plan;
|
||||
|
||||
import com.djrapitops.plan.api.PlanAPI;
|
||||
import com.djrapitops.plan.capability.CapabilitySvc;
|
||||
import com.djrapitops.plan.delivery.DeliveryUtilities;
|
||||
import com.djrapitops.plan.delivery.export.ExportSystem;
|
||||
import com.djrapitops.plan.delivery.web.ResolverSvc;
|
||||
import com.djrapitops.plan.delivery.web.ResourceSvc;
|
||||
import com.djrapitops.plan.delivery.webserver.NonProxyWebserverDisableChecker;
|
||||
import com.djrapitops.plan.delivery.webserver.WebServer;
|
||||
import com.djrapitops.plan.delivery.webserver.WebServerSystem;
|
||||
@ -79,6 +79,7 @@ public class PlanSystem implements SubSystem {
|
||||
private final ExportSystem exportSystem;
|
||||
private final DeliveryUtilities deliveryUtilities;
|
||||
private final ResolverSvc resolverService;
|
||||
private final ResourceSvc resourceService;
|
||||
private final ExtensionSvc extensionService;
|
||||
private final QuerySvc queryService;
|
||||
private final SettingsSvc settingsService;
|
||||
@ -103,6 +104,7 @@ public class PlanSystem implements SubSystem {
|
||||
ExportSystem exportSystem,
|
||||
DeliveryUtilities deliveryUtilities,
|
||||
ResolverSvc resolverService,
|
||||
ResourceSvc resourceService,
|
||||
ExtensionSvc extensionService,
|
||||
QuerySvc queryService,
|
||||
SettingsSvc settingsService,
|
||||
@ -126,6 +128,7 @@ public class PlanSystem implements SubSystem {
|
||||
this.exportSystem = exportSystem;
|
||||
this.deliveryUtilities = deliveryUtilities;
|
||||
this.resolverService = resolverService;
|
||||
this.resourceService = resourceService;
|
||||
this.extensionService = extensionService;
|
||||
this.queryService = queryService;
|
||||
this.settingsService = settingsService;
|
||||
@ -155,10 +158,9 @@ public class PlanSystem implements SubSystem {
|
||||
|
||||
@Override
|
||||
public void enable() throws EnableException {
|
||||
CapabilitySvc.initialize();
|
||||
|
||||
extensionService.register();
|
||||
resolverService.register();
|
||||
resourceService.register();
|
||||
settingsService.register();
|
||||
queryService.register();
|
||||
|
||||
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.delivery.rendering.pages;
|
||||
import com.djrapitops.plan.delivery.domain.container.PlayerContainer;
|
||||
import com.djrapitops.plan.delivery.formatting.Formatters;
|
||||
import com.djrapitops.plan.delivery.rendering.html.icon.Icon;
|
||||
import com.djrapitops.plan.delivery.web.ResourceService;
|
||||
import com.djrapitops.plan.delivery.web.resolver.exception.NotFoundException;
|
||||
import com.djrapitops.plan.extension.implementation.results.ExtensionData;
|
||||
import com.djrapitops.plan.extension.implementation.storage.queries.ExtensionPlayerDataQuery;
|
||||
@ -41,6 +42,7 @@ import dagger.Lazy;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@ -92,14 +94,14 @@ public class PageFactory {
|
||||
|
||||
public DebugPage debugPage() throws IOException {
|
||||
return new DebugPage(
|
||||
getResource("web/error.html"),
|
||||
getResource("error.html"),
|
||||
dbSystem.get().getDatabase(), serverInfo.get(), formatters.get(), versionChecker.get(),
|
||||
debugLogger.get(), timings.get(), errorHandler.get()
|
||||
);
|
||||
}
|
||||
|
||||
public PlayersPage playersPage() throws IOException {
|
||||
return new PlayersPage(getResource("web/players.html"), versionChecker.get(),
|
||||
return new PlayersPage(getResource("players.html"), versionChecker.get(),
|
||||
config.get(), locale.get(), theme.get(), serverInfo.get());
|
||||
}
|
||||
|
||||
@ -115,7 +117,7 @@ public class PageFactory {
|
||||
Server server = dbSystem.get().getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverUUID))
|
||||
.orElseThrow(() -> new NotFoundException("Server not found in the database"));
|
||||
return new ServerPage(
|
||||
getResource("web/server.html"),
|
||||
getResource("server.html"),
|
||||
server,
|
||||
config.get(),
|
||||
theme.get(),
|
||||
@ -131,7 +133,7 @@ public class PageFactory {
|
||||
Database db = dbSystem.get().getDatabase();
|
||||
PlayerContainer player = db.query(ContainerFetchQueries.fetchPlayerContainer(playerUUID));
|
||||
return new PlayerPage(
|
||||
getResource("web/player.html"), player,
|
||||
getResource("player.html"), player,
|
||||
versionChecker.get(),
|
||||
config.get(), this, theme.get(), locale.get(),
|
||||
formatters.get(), serverInfo.get()
|
||||
@ -172,7 +174,7 @@ public class PageFactory {
|
||||
}
|
||||
|
||||
public NetworkPage networkPage() throws IOException {
|
||||
return new NetworkPage(getResource("web/network.html"),
|
||||
return new NetworkPage(getResource("network.html"),
|
||||
dbSystem.get(),
|
||||
versionChecker.get(),
|
||||
config.get(), theme.get(), locale.get(),
|
||||
@ -182,7 +184,7 @@ public class PageFactory {
|
||||
public Page internalErrorPage(String message, Throwable error) {
|
||||
try {
|
||||
return new InternalErrorPage(
|
||||
getResource("web/error.html"), message, error,
|
||||
getResource("error.html"), message, error,
|
||||
versionChecker.get());
|
||||
} catch (IOException noParse) {
|
||||
return () -> "Error occurred: " + error.toString() +
|
||||
@ -193,17 +195,23 @@ public class PageFactory {
|
||||
|
||||
public Page errorPage(String title, String error) throws IOException {
|
||||
return new ErrorMessagePage(
|
||||
getResource("web/error.html"), title, error,
|
||||
getResource("error.html"), title, error,
|
||||
versionChecker.get(), locale.get(), theme.get());
|
||||
}
|
||||
|
||||
public Page errorPage(Icon icon, String title, String error) throws IOException {
|
||||
return new ErrorMessagePage(
|
||||
getResource("web/error.html"), icon, title, error,
|
||||
getResource("error.html"), icon, title, error,
|
||||
locale.get(), theme.get(), versionChecker.get());
|
||||
}
|
||||
|
||||
public String getResource(String name) throws IOException {
|
||||
return files.get().getCustomizableResourceOrDefault(name).asString();
|
||||
try {
|
||||
return ResourceService.getInstance().getResource("Plan", name,
|
||||
() -> files.get().getResourceFromJar("web/" + name).asWebResource()
|
||||
).asString();
|
||||
} catch (UncheckedIOException readFail) {
|
||||
throw readFail.getCause();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.delivery.web;
|
||||
|
||||
import com.djrapitops.plan.delivery.web.resource.WebResource;
|
||||
import com.djrapitops.plan.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.settings.config.ResourceSettings;
|
||||
import com.djrapitops.plan.storage.file.PlanFiles;
|
||||
import com.djrapitops.plan.storage.file.Resource;
|
||||
import com.djrapitops.plugin.logging.L;
|
||||
import com.djrapitops.plugin.logging.error.ErrorHandler;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.text.TextStringBuilder;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.OpenOption;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* ResourceService implementation.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
@Singleton
|
||||
public class ResourceSvc implements ResourceService {
|
||||
|
||||
public final Set<Snippet> snippets;
|
||||
private final PlanFiles files;
|
||||
private final ResourceSettings resourceSettings;
|
||||
private final ErrorHandler errorHandler;
|
||||
|
||||
@Inject
|
||||
public ResourceSvc(
|
||||
PlanFiles files,
|
||||
PlanConfig config,
|
||||
ErrorHandler errorHandler
|
||||
) {
|
||||
this.files = files;
|
||||
this.resourceSettings = config.getResourceSettings();
|
||||
this.errorHandler = errorHandler;
|
||||
this.snippets = new HashSet<>();
|
||||
}
|
||||
|
||||
public void register() {
|
||||
Holder.set(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebResource getResource(String pluginName, String fileName, Supplier<WebResource> source) {
|
||||
return applySnippets(pluginName, fileName, getTheResource(pluginName, fileName, source));
|
||||
}
|
||||
|
||||
private WebResource applySnippets(String pluginName, String fileName, WebResource resource) {
|
||||
Map<Position, StringBuilder> byPosition = calculateSnippets(pluginName, fileName);
|
||||
if (byPosition.isEmpty()) return resource;
|
||||
|
||||
String html = applySnippets(resource, byPosition);
|
||||
return WebResource.create(html);
|
||||
}
|
||||
|
||||
private String applySnippets(WebResource resource, Map<Position, StringBuilder> byPosition) {
|
||||
String html = resource.asString();
|
||||
if (html == null) {
|
||||
return "Error: Given resource did not support WebResource#asString method properly and returned 'null'";
|
||||
}
|
||||
|
||||
StringBuilder toHead = byPosition.get(Position.HEAD);
|
||||
if (toHead != null) {
|
||||
html = StringUtils.replaceOnce(html, "</head>", toHead.append("</head>").toString());
|
||||
}
|
||||
|
||||
StringBuilder toBody = byPosition.get(Position.BODY);
|
||||
if (toBody != null) {
|
||||
if (StringUtils.contains(html, "<!-- End of Page Wrapper -->")) {
|
||||
html = StringUtils.replaceOnce(html, "<!-- End of Page Wrapper -->", toBody.toString());
|
||||
} else {
|
||||
html = StringUtils.replaceOnce(html, "<body>", toBody.append("<body>").toString());
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder toBodyEnd = byPosition.get(Position.BODY_END);
|
||||
if (toBodyEnd != null) {
|
||||
html = StringUtils.replaceOnce(html, "<\body>", toBodyEnd.append("<\body>").toString());
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
private Map<Position, StringBuilder> calculateSnippets(String pluginName, String fileName) {
|
||||
Map<Position, StringBuilder> byPosition = new EnumMap<>(Position.class);
|
||||
for (Snippet snippet : snippets) {
|
||||
if (snippet.matches(pluginName, fileName)) {
|
||||
byPosition.computeIfAbsent(snippet.position, k -> new StringBuilder()).append(snippet.content);
|
||||
}
|
||||
}
|
||||
return byPosition;
|
||||
}
|
||||
|
||||
public WebResource getTheResource(String pluginName, String fileName, Supplier<WebResource> source) {
|
||||
try {
|
||||
if (resourceSettings.shouldBeCustomized(pluginName, fileName)) {
|
||||
return getOrWriteCustomized(fileName, source);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
errorHandler.log(L.WARN, getClass(), e.getCause());
|
||||
}
|
||||
// Return original by default
|
||||
return source.get();
|
||||
}
|
||||
|
||||
public WebResource getOrWriteCustomized(String fileName, Supplier<WebResource> source) throws IOException {
|
||||
Optional<Resource> customizedResource = files.getCustomizableResource(fileName);
|
||||
if (customizedResource.isPresent()) {
|
||||
return readCustomized(customizedResource.get());
|
||||
} else {
|
||||
return writeCustomized(fileName, source);
|
||||
}
|
||||
}
|
||||
|
||||
public WebResource readCustomized(Resource customizedResource) throws IOException {
|
||||
try {
|
||||
return customizedResource.asWebResource();
|
||||
} catch (UncheckedIOException readFail) {
|
||||
throw readFail.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
public WebResource writeCustomized(String fileName, Supplier<WebResource> source) throws IOException {
|
||||
WebResource original = source.get();
|
||||
byte[] bytes = original.asBytes();
|
||||
OpenOption[] overwrite = {StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE};
|
||||
Files.write(files.getCustomizationDirectory().resolve(fileName), bytes, overwrite);
|
||||
return original;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addScriptsToResource(String pluginName, String fileName, Position position, String... jsSrcs) {
|
||||
if (!fileName.endsWith(".html")) {
|
||||
throw new IllegalArgumentException("'" + fileName + "' is not a .html file! Only html files can be added to.");
|
||||
}
|
||||
String snippet = new TextStringBuilder("<script src=\"")
|
||||
.appendWithSeparators(jsSrcs, "\"></script><script src=\"")
|
||||
.append("\"></script>").build();
|
||||
snippets.add(new Snippet(pluginName, fileName, position, snippet));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addStylesToResource(String pluginName, String fileName, Position position, String... cssSrcs) {
|
||||
if (!fileName.endsWith(".html")) {
|
||||
throw new IllegalArgumentException("'" + fileName + "' is not a .html file! Only html files can be added to.");
|
||||
}
|
||||
String snippet = new TextStringBuilder("<link href=\"")
|
||||
.appendWithSeparators(cssSrcs, "\" ref=\"stylesheet\"></link><link href=\"")
|
||||
.append("\" ref=\"stylesheet\"></link>").build();
|
||||
snippets.add(new Snippet(pluginName, fileName, position, snippet));
|
||||
}
|
||||
|
||||
private static class Snippet {
|
||||
private final String pluginName;
|
||||
private final String fileName;
|
||||
private final Position position;
|
||||
private final String content;
|
||||
|
||||
public Snippet(String pluginName, String fileName, Position position, String content) {
|
||||
this.pluginName = pluginName;
|
||||
this.fileName = fileName;
|
||||
this.position = position;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public boolean matches(String pluginName, String fileName) {
|
||||
return pluginName.equals(this.pluginName) && fileName.equals(this.fileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Snippet snippet = (Snippet) o;
|
||||
return Objects.equals(pluginName, snippet.pluginName) &&
|
||||
Objects.equals(fileName, snippet.fileName) &&
|
||||
position == snippet.position &&
|
||||
Objects.equals(content, snippet.content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(pluginName, fileName, position, content);
|
||||
}
|
||||
}
|
||||
}
|
@ -96,7 +96,7 @@ public class ResponseResolver {
|
||||
resolverService.registerResolver(plugin, "/debug", debugPageResolver);
|
||||
resolverService.registerResolver(plugin, "/players", playersPageResolver);
|
||||
resolverService.registerResolver(plugin, "/player", playerPageResolver);
|
||||
resolverService.registerResolver(plugin, "/favicon.ico", noAuthResolverFor(responseFactory.faviconResponse()));
|
||||
resolverService.registerResolver(plugin, "/favicon.ico", (NoAuthResolver) request -> Optional.of(responseFactory.faviconResponse()));
|
||||
resolverService.registerResolver(plugin, "/network", serverPageResolver);
|
||||
resolverService.registerResolver(plugin, "/server", serverPageResolver);
|
||||
resolverService.registerResolverForMatches(plugin, Pattern.compile("^/$"), rootPageResolver);
|
||||
@ -105,10 +105,6 @@ public class ResponseResolver {
|
||||
resolverService.registerResolver(plugin, "/v1", rootJSONResolver.getResolver());
|
||||
}
|
||||
|
||||
public NoAuthResolver noAuthResolverFor(Response response) {
|
||||
return request -> Optional.of(response);
|
||||
}
|
||||
|
||||
public Response getResponse(RequestInternal request) {
|
||||
try {
|
||||
return tryToGetResponse(request);
|
||||
|
@ -44,6 +44,7 @@ public class PlanConfig extends Config {
|
||||
|
||||
private final PlanFiles files;
|
||||
private final ExtensionSettings extensionSettings;
|
||||
private final ResourceSettings resourceSettings;
|
||||
private final WorldAliasSettings worldAliasSettings;
|
||||
private final PluginLogger logger;
|
||||
|
||||
@ -53,12 +54,7 @@ public class PlanConfig extends Config {
|
||||
WorldAliasSettings worldAliasSettings,
|
||||
PluginLogger logger
|
||||
) {
|
||||
super(files.getConfigFile());
|
||||
|
||||
this.files = files;
|
||||
this.extensionSettings = new ExtensionSettings(this);
|
||||
this.worldAliasSettings = worldAliasSettings;
|
||||
this.logger = logger;
|
||||
this(files.getConfigFile(), files, worldAliasSettings, logger);
|
||||
}
|
||||
|
||||
// For testing
|
||||
@ -72,6 +68,7 @@ public class PlanConfig extends Config {
|
||||
|
||||
this.files = files;
|
||||
this.extensionSettings = new ExtensionSettings(this);
|
||||
this.resourceSettings = new ResourceSettings(this);
|
||||
this.worldAliasSettings = worldAliasSettings;
|
||||
this.logger = logger;
|
||||
}
|
||||
@ -142,6 +139,10 @@ public class PlanConfig extends Config {
|
||||
return extensionSettings;
|
||||
}
|
||||
|
||||
public ResourceSettings getResourceSettings() {
|
||||
return resourceSettings;
|
||||
}
|
||||
|
||||
public WorldAliasSettings getWorldAliasSettings() {
|
||||
return worldAliasSettings;
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.settings.config;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
|
||||
public class ResourceSettings {
|
||||
|
||||
private final PlanConfig config;
|
||||
|
||||
public ResourceSettings(
|
||||
PlanConfig config
|
||||
) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public boolean shouldBeCustomized(String plugin, String fileName) {
|
||||
ConfigNode fileCustomization = config.getNode("Customized_files").orElseGet(() -> config.addNode("Customized_files"));
|
||||
ConfigNode pluginCustomization = fileCustomization.getNode(plugin).orElseGet(() -> fileCustomization.addNode(plugin));
|
||||
if (pluginCustomization.contains(fileName)) {
|
||||
return pluginCustomization.getBoolean(fileName);
|
||||
} else {
|
||||
pluginCustomization.set(fileName, false);
|
||||
try {
|
||||
pluginCustomization.save();
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Could not save config.yml: " + e.getMessage(), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -46,7 +46,7 @@ public class DisplaySettings {
|
||||
public static final Setting<ConfigNode> WORLD_ALIASES = new Setting<ConfigNode>("World_aliases", ConfigNode.class) {
|
||||
@Override
|
||||
public ConfigNode getValueFrom(ConfigNode node) {
|
||||
return node.getNode(path).orElse(node.addNode(path));
|
||||
return node.getNode(path).orElseGet(() -> node.addNode(path));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -57,6 +57,10 @@ public class PlanFiles implements SubSystem {
|
||||
return dataFolder.toPath();
|
||||
}
|
||||
|
||||
public Path getCustomizationDirectory() {
|
||||
return dataFolder.toPath().resolve("web");
|
||||
}
|
||||
|
||||
public File getLogsFolder() {
|
||||
File folder = getFileFromPluginFolder("logs");
|
||||
folder.mkdirs();
|
||||
@ -119,7 +123,9 @@ public class PlanFiles implements SubSystem {
|
||||
*
|
||||
* @param resourceName Path to the file inside the plugin folder.
|
||||
* @return a {@link Resource} for accessing the resource, either from the plugin folder or jar.
|
||||
* @deprecated Use {@link PlanFiles#getCustomizableResource(String)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public Resource getCustomizableResourceOrDefault(String resourceName) {
|
||||
return ResourceCache.getOrCache(resourceName, () ->
|
||||
attemptToFind(resourceName).map(file -> (Resource) new FileResource(resourceName, file))
|
||||
@ -144,4 +150,8 @@ public class PlanFiles implements SubSystem {
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public Optional<Resource> getCustomizableResource(String resourceName) {
|
||||
return attemptToFind(resourceName).map(found -> new FileResource(resourceName, found));
|
||||
}
|
||||
}
|
||||
|
@ -16,10 +16,12 @@
|
||||
*/
|
||||
package com.djrapitops.plan.storage.file;
|
||||
|
||||
import com.djrapitops.plan.delivery.web.resource.WebResource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -62,6 +64,17 @@ public interface Resource {
|
||||
*/
|
||||
String asString() throws IOException;
|
||||
|
||||
/**
|
||||
* @throws UncheckedIOException if fails to read the file
|
||||
*/
|
||||
default WebResource asWebResource() {
|
||||
try {
|
||||
return WebResource.create(asInputStream());
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to read '" + getResourceName() + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a resource is a text based file.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user