Removed PlanFiles#getCustomizableResourceOrDefault

This commit is contained in:
Risto Lahtela 2020-03-20 10:35:14 +02:00
parent ff6f960a84
commit 4fd19bbc5e
13 changed files with 123 additions and 59 deletions

View File

@ -40,6 +40,9 @@ public interface ResourceService {
* @param fileName Name of the file (for customization)
* @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.
* @throws IllegalArgumentException If pluginName is empty or null
* @throws IllegalArgumentException If fileName is empty or null
* @throws IllegalArgumentException If source is null
*/
WebResource getResource(String pluginName, String fileName, Supplier<WebResource> source);
@ -52,7 +55,10 @@ public interface ResourceService {
* @param fileName Name of the .html file being modified
* @param position Where to place the script tag on the page.
* @param jsSrcs Source URLs.
* @throws IllegalArgumentException If fileName does not end with .html or .htm
* @throws IllegalArgumentException If pluginName is empty or null
* @throws IllegalArgumentException If fileName is null, empty or does not end with .html
* @throws IllegalArgumentException If position null
* @throws IllegalArgumentException If jsSrcs is empty or null
*/
void addScriptsToResource(String pluginName, String fileName, Position position, String... jsSrcs);
@ -65,7 +71,10 @@ public interface ResourceService {
* @param fileName Name of the .html file being modified
* @param position Where to place the link tag on the page.
* @param cssSrcs Source URLs.
* @throws IllegalArgumentException If fileName does not end with .html or .htm
* @throws IllegalArgumentException If pluginName is empty or null
* @throws IllegalArgumentException If fileName is null, empty or does not end with .html
* @throws IllegalArgumentException If position null
* @throws IllegalArgumentException If cssSrcs is empty or null
*/
void addStylesToResource(String pluginName, String fileName, Position position, String... cssSrcs);
@ -85,7 +94,11 @@ public interface ResourceService {
* <p>
* Recommended for loading data to custom structure on the page.
*/
AFTER_MAIN_SCRIPT
AFTER_MAIN_SCRIPT;
public String cleanName() {
return name().toLowerCase().replace('_', ' ');
}
}
class Holder {

View File

@ -17,7 +17,7 @@
package com.djrapitops.plan.delivery.export;
import com.djrapitops.plan.delivery.rendering.html.Html;
import com.djrapitops.plan.storage.file.Resource;
import com.djrapitops.plan.delivery.web.resource.WebResource;
import org.apache.commons.lang3.StringUtils;
import java.io.ByteArrayInputStream;
@ -56,15 +56,14 @@ abstract class FileExporter {
}
void export(Path to, String content) throws IOException {
Files.createDirectories(to.getParent());
Files.write(to, Arrays.asList(StringUtils.split(content, "\r\n")), StandardCharsets.UTF_8, OPEN_OPTIONS);
export(to, Arrays.asList(StringUtils.split(content, "\r\n")));
}
void export(Path to, Resource resource) throws IOException {
void export(Path to, WebResource resource) throws IOException {
Files.createDirectories(to.getParent());
try (
InputStream in = resource.asInputStream();
InputStream in = resource.asStream();
OutputStream out = Files.newOutputStream(to, OPEN_OPTIONS)
) {
copy(in, out);

View File

@ -18,9 +18,11 @@ package com.djrapitops.plan.delivery.export;
import com.djrapitops.plan.delivery.rendering.pages.Page;
import com.djrapitops.plan.delivery.rendering.pages.PageFactory;
import com.djrapitops.plan.delivery.web.ResourceService;
import com.djrapitops.plan.delivery.web.resolver.Response;
import com.djrapitops.plan.delivery.web.resolver.exception.NotFoundException;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import com.djrapitops.plan.delivery.web.resource.WebResource;
import com.djrapitops.plan.delivery.webserver.resolver.json.RootJSONResolver;
import com.djrapitops.plan.exceptions.connection.WebException;
import com.djrapitops.plan.identification.Server;
@ -212,7 +214,8 @@ public class NetworkPageExporter extends FileExporter {
}
private void exportResource(Path toDirectory, String resourceName) throws IOException {
Resource resource = files.getCustomizableResourceOrDefault("web/" + resourceName);
WebResource resource = ResourceService.getInstance().getResource("Plan", resourceName,
() -> files.getResourceFromJar("web/" + resourceName).asWebResource());
Path to = toDirectory.resolve(resourceName);
if (resourceName.endsWith(".css")) {
@ -225,7 +228,7 @@ public class NetworkPageExporter extends FileExporter {
new String[]{relativePlayerLink, relativePlayerLink, relativeServerLink, relativeServerLink}
));
} else if (Resource.isTextResource(resourceName)) {
export(to, resource.asLines());
export(to, resource.asString());
} else {
export(to, resource);
}

View File

@ -18,9 +18,11 @@ package com.djrapitops.plan.delivery.export;
import com.djrapitops.plan.delivery.rendering.pages.Page;
import com.djrapitops.plan.delivery.rendering.pages.PageFactory;
import com.djrapitops.plan.delivery.web.ResourceService;
import com.djrapitops.plan.delivery.web.resolver.Response;
import com.djrapitops.plan.delivery.web.resolver.exception.NotFoundException;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import com.djrapitops.plan.delivery.web.resource.WebResource;
import com.djrapitops.plan.delivery.webserver.resolver.json.RootJSONResolver;
import com.djrapitops.plan.exceptions.connection.WebException;
import com.djrapitops.plan.settings.theme.Theme;
@ -178,19 +180,20 @@ public class PlayerPageExporter extends FileExporter {
private void exportResources(ExportPaths exportPaths, Path toDirectory, String... resourceNames) throws IOException {
for (String resourceName : resourceNames) {
String nonRelativePath = toNonRelativePath(resourceName);
exportResource(exportPaths, toDirectory, nonRelativePath);
exportResource(toDirectory, nonRelativePath);
exportPaths.put(resourceName, toRelativePathFromRoot(nonRelativePath));
}
}
private void exportResource(ExportPaths exportPaths, Path toDirectory, String resourceName) throws IOException {
Resource resource = files.getCustomizableResourceOrDefault("web/" + resourceName);
private void exportResource(Path toDirectory, String resourceName) throws IOException {
WebResource resource = ResourceService.getInstance().getResource("Plan", resourceName,
() -> files.getResourceFromJar("web/" + resourceName).asWebResource());
Path to = toDirectory.resolve(resourceName);
if (resourceName.endsWith(".css")) {
export(to, theme.replaceThemeColors(resource.asString()));
} else if (Resource.isTextResource(resourceName)) {
export(to, resource.asLines());
export(to, resource.asString());
} else {
export(to, resource);
}

View File

@ -18,9 +18,11 @@ package com.djrapitops.plan.delivery.export;
import com.djrapitops.plan.delivery.rendering.pages.Page;
import com.djrapitops.plan.delivery.rendering.pages.PageFactory;
import com.djrapitops.plan.delivery.web.ResourceService;
import com.djrapitops.plan.delivery.web.resolver.Response;
import com.djrapitops.plan.delivery.web.resolver.exception.NotFoundException;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import com.djrapitops.plan.delivery.web.resource.WebResource;
import com.djrapitops.plan.delivery.webserver.resolver.json.RootJSONResolver;
import com.djrapitops.plan.exceptions.connection.WebException;
import com.djrapitops.plan.identification.ServerInfo;
@ -159,13 +161,14 @@ public class PlayersPageExporter extends FileExporter {
}
private void exportResource(Path toDirectory, String resourceName) throws IOException {
Resource resource = files.getCustomizableResourceOrDefault("web/" + resourceName);
WebResource resource = ResourceService.getInstance().getResource("Plan", resourceName,
() -> files.getResourceFromJar("web/" + resourceName).asWebResource());
Path to = toDirectory.resolve(resourceName);
if (resourceName.endsWith(".css")) {
export(to, theme.replaceThemeColors(resource.asString()));
} else if (Resource.isTextResource(resourceName)) {
export(to, resource.asLines());
export(to, resource.asString());
} else {
export(to, resource);
}

View File

@ -18,9 +18,11 @@ package com.djrapitops.plan.delivery.export;
import com.djrapitops.plan.delivery.rendering.pages.Page;
import com.djrapitops.plan.delivery.rendering.pages.PageFactory;
import com.djrapitops.plan.delivery.web.ResourceService;
import com.djrapitops.plan.delivery.web.resolver.Response;
import com.djrapitops.plan.delivery.web.resolver.exception.NotFoundException;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import com.djrapitops.plan.delivery.web.resource.WebResource;
import com.djrapitops.plan.delivery.webserver.resolver.json.RootJSONResolver;
import com.djrapitops.plan.exceptions.connection.WebException;
import com.djrapitops.plan.identification.Server;
@ -224,13 +226,14 @@ public class ServerPageExporter extends FileExporter {
}
private void exportResource(Path toDirectory, String resourceName) throws IOException {
Resource resource = files.getCustomizableResourceOrDefault("web/" + resourceName);
WebResource resource = ResourceService.getInstance().getResource("Plan", resourceName,
() -> files.getResourceFromJar("web/" + resourceName).asWebResource());
Path to = toDirectory.resolve(resourceName);
if (resourceName.endsWith(".css")) {
export(to, theme.replaceThemeColors(resource.asString()));
} else if (Resource.isTextResource(resourceName)) {
export(to, resource.asLines());
export(to, resource.asString());
} else {
export(to, resource);
}

View File

@ -19,9 +19,12 @@ 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.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.lang.PluginLang;
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.console.PluginLogger;
import com.djrapitops.plugin.logging.error.ErrorHandler;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.TextStringBuilder;
@ -47,16 +50,22 @@ public class ResourceSvc implements ResourceService {
public final Set<Snippet> snippets;
private final PlanFiles files;
private final ResourceSettings resourceSettings;
private final Locale locale;
private final PluginLogger logger;
private final ErrorHandler errorHandler;
@Inject
public ResourceSvc(
PlanFiles files,
PlanConfig config,
Locale locale,
PluginLogger logger,
ErrorHandler errorHandler
) {
this.files = files;
this.resourceSettings = config.getResourceSettings();
this.locale = locale;
this.logger = logger;
this.errorHandler = errorHandler;
this.snippets = new HashSet<>();
}
@ -67,9 +76,22 @@ public class ResourceSvc implements ResourceService {
@Override
public WebResource getResource(String pluginName, String fileName, Supplier<WebResource> source) {
checkParams(pluginName, fileName, source);
return applySnippets(pluginName, fileName, getTheResource(pluginName, fileName, source));
}
public void checkParams(String pluginName, String fileName, Supplier<WebResource> source) {
if (pluginName == null || pluginName.isEmpty()) {
throw new IllegalArgumentException("'pluginName' can't be '" + pluginName + "'!");
}
if (fileName == null || fileName.isEmpty()) {
throw new IllegalArgumentException("'fileName' can't be '" + fileName + "'!");
}
if (source == null) {
throw new IllegalArgumentException("'source' can't be null!");
}
}
private WebResource applySnippets(String pluginName, String fileName, WebResource resource) {
Map<Position, StringBuilder> byPosition = calculateSnippets(pluginName, fileName);
if (byPosition.isEmpty()) return resource;
@ -155,24 +177,42 @@ public class ResourceSvc implements ResourceService {
@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.");
}
checkParams(pluginName, fileName, position, jsSrcs);
String snippet = new TextStringBuilder("<script src=\"")
.appendWithSeparators(jsSrcs, "\"></script><script src=\"")
.append("\"></script>").build();
snippets.add(new Snippet(pluginName, fileName, position, snippet));
logger.info(locale.getString(PluginLang.API_ADD_RESOURCE_JS, pluginName, fileName, position.cleanName()));
}
public void checkParams(String pluginName, String fileName, Position position, String[] jsSrcs) {
if (pluginName == null || pluginName.isEmpty()) {
throw new IllegalArgumentException("'pluginName' can't be '" + pluginName + "'!");
}
if (fileName == null || fileName.isEmpty()) {
throw new IllegalArgumentException("'fileName' can't be '" + fileName + "'!");
}
if (!fileName.endsWith(".html")) {
throw new IllegalArgumentException("'" + fileName + "' is not a .html file! Only html files can be added to.");
}
if (position == null) {
throw new IllegalArgumentException("'position' can't be null!");
}
if (jsSrcs == null || jsSrcs.length == 0) {
throw new IllegalArgumentException("Can't add snippets to resource without snippets!");
}
}
@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.");
}
checkParams(pluginName, fileName, position, cssSrcs);
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));
logger.info(locale.getString(PluginLang.API_ADD_RESOURCE_CSS, pluginName, fileName, position.cleanName()));
}
private static class Snippet {

View File

@ -21,9 +21,11 @@ import com.djrapitops.plan.delivery.rendering.html.icon.Family;
import com.djrapitops.plan.delivery.rendering.html.icon.Icon;
import com.djrapitops.plan.delivery.rendering.pages.Page;
import com.djrapitops.plan.delivery.rendering.pages.PageFactory;
import com.djrapitops.plan.delivery.web.ResourceService;
import com.djrapitops.plan.delivery.web.resolver.MimeType;
import com.djrapitops.plan.delivery.web.resolver.Response;
import com.djrapitops.plan.delivery.web.resolver.exception.NotFoundException;
import com.djrapitops.plan.delivery.web.resource.WebResource;
import com.djrapitops.plan.delivery.webserver.auth.FailReason;
import com.djrapitops.plan.exceptions.WebUserAuthException;
import com.djrapitops.plan.settings.locale.Locale;
@ -39,6 +41,7 @@ import com.djrapitops.plan.utilities.java.UnaryChain;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@ -73,6 +76,11 @@ public class ResponseFactory {
this.theme = theme;
}
public WebResource getResource(String resourceName) {
return ResourceService.getInstance().getResource("Plan", resourceName,
() -> files.getResourceFromJar("web/" + resourceName).asWebResource());
}
public Response debugPageResponse() {
try {
return forPage(pageFactory.debugPage());
@ -165,7 +173,7 @@ public class ResponseFactory {
public Response javaScriptResponse(String fileName) {
try {
String content = UnaryChain.of(files.getCustomizableResourceOrDefault(fileName).asString())
String content = UnaryChain.of(getResource(fileName).asString())
.chain(theme::replaceThemeColors)
.chain(locale::replaceLanguageInJavascript)
.apply();
@ -174,20 +182,20 @@ public class ResponseFactory {
.setContent(content)
.setStatus(200)
.build();
} catch (IOException e) {
} catch (UncheckedIOException e) {
return notFound404("JS File not found from jar: " + fileName + ", " + e.toString());
}
}
public Response cssResponse(String fileName) {
try {
String content = theme.replaceThemeColors(files.getCustomizableResourceOrDefault(fileName).asString());
String content = theme.replaceThemeColors(getResource(fileName).asString());
return Response.builder()
.setMimeType(MimeType.CSS)
.setContent(content)
.setStatus(200)
.build();
} catch (IOException e) {
} catch (UncheckedIOException e) {
return notFound404("CSS File not found from jar: " + fileName + ", " + e.toString());
}
}
@ -196,10 +204,10 @@ public class ResponseFactory {
try {
return Response.builder()
.setMimeType(MimeType.IMAGE)
.setContent(files.getCustomizableResourceOrDefault(fileName).asBytes())
.setContent(getResource(fileName).asBytes())
.setStatus(200)
.build();
} catch (IOException e) {
} catch (UncheckedIOException e) {
return notFound404("Image File not found from jar: " + fileName + ", " + e.toString());
}
}
@ -220,9 +228,9 @@ public class ResponseFactory {
try {
return Response.builder()
.setMimeType(type)
.setContent(files.getCustomizableResourceOrDefault(fileName).asBytes())
.setContent(getResource(fileName).asBytes())
.build();
} catch (IOException e) {
} catch (UncheckedIOException e) {
return notFound404("Font File not found from jar: " + fileName + ", " + e.toString());
}
}
@ -235,9 +243,9 @@ public class ResponseFactory {
try {
return Response.builder()
.setMimeType(MimeType.FAVICON)
.setContent(files.getCustomizableResourceOrDefault("web/favicon.ico").asBytes())
.setContent(getResource("favicon.ico").asBytes())
.build();
} catch (IOException e) {
} catch (UncheckedIOException e) {
return forInternalError(e, "Could not read favicon");
}
}

View File

@ -47,19 +47,18 @@ public class StaticResourceResolver implements NoAuthResolver {
}
private Response getResponse(Request request) {
String resource = request.getPath().asString();
String filePath = "web" + resource;
String resource = request.getPath().asString().substring(1);
if (resource.endsWith(".css")) {
return responseFactory.cssResponse(filePath);
return responseFactory.cssResponse(resource);
}
if (resource.endsWith(".js")) {
return responseFactory.javaScriptResponse(filePath);
return responseFactory.javaScriptResponse(resource);
}
if (resource.endsWith(".png")) {
return responseFactory.imageResponse(filePath);
return responseFactory.imageResponse(resource);
}
if (StringUtils.endsWithAny(resource, ".woff", ".woff2", ".eot", ".ttf")) {
return responseFactory.fontResponse(filePath);
return responseFactory.fontResponse(resource);
}
return null;
}

View File

@ -116,9 +116,9 @@ public class PlanConfig extends Config {
public Path getPageExportPath() {
Path exportDirectory = Paths.get(get(ExportSettings.HTML_EXPORT_PATH));
Path webDirectory = files.getDataDirectory().resolve("web");
Path customizationDirectory = files.getCustomizationDirectory();
if (exportDirectory.toAbsolutePath().equals(webDirectory.toAbsolutePath())) {
if (exportDirectory.toAbsolutePath().equals(customizationDirectory.toAbsolutePath())) {
logger.warn("'" + ExportSettings.HTML_EXPORT_PATH.getPath() + "' can not be '/Plan/web/' directory, using '/Plan/Analysis Results' as fallback.");
exportDirectory = files.getDataDirectory().resolve("Analysis Results");
}

View File

@ -25,6 +25,8 @@ public enum PluginLang implements Lang {
ENABLED("Enable", "Player Analytics Enabled."),
ENABLED_WEB_SERVER("Enable - WebServer", "Webserver running on PORT ${0} (${1})"),
ENABLED_DATABASE("Enable - Database", "${0}-database connection established."),
API_ADD_RESOURCE_JS("API - js+", "PageExtension: ${0} added javascript(s) to ${1}, ${2}"),
API_ADD_RESOURCE_CSS("API - css+", "PageExtension: ${0} added stylesheet(s) to ${1}, ${2}"),
ENABLE_NOTIFY_EMPTY_IP("Enable - Notify Empty IP", "IP in server.properties is empty & AlternativeIP is not in use. Incorrect links will be given!"),
ENABLE_NOTIFY_BAD_IP("Enable - Notify Bad IP", "0.0.0.0 is not a valid address, set up AlternativeIP settings. Incorrect links will be given!"),

View File

@ -118,21 +118,6 @@ public class PlanFiles implements SubSystem {
return new FileResource(resourceName, getFileFromPluginFolder(resourceName));
}
/**
* Get a customizable resource from the plugin files or from the jar if one doesn't exist.
*
* @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))
.orElse(getResourceFromJar(resourceName))
);
}
private Optional<File> attemptToFind(String resourceName) {
if (dataFolder.exists() && dataFolder.isDirectory()) {
@ -152,6 +137,10 @@ public class PlanFiles implements SubSystem {
}
public Optional<Resource> getCustomizableResource(String resourceName) {
return attemptToFind(resourceName).map(found -> new FileResource(resourceName, found));
return Optional.ofNullable(ResourceCache.getOrCache(resourceName,
() -> attemptToFind(resourceName)
.map(found -> new FileResource(resourceName, found))
.orElse(null)
));
}
}

View File

@ -43,7 +43,9 @@ public class ResourceCache {
public static Resource getOrCache(String resourceName, Supplier<Resource> resourceSupplier) {
String found = cache.getIfPresent(resourceName);
if (found == null) {
return new StringCachingResource(resourceSupplier.get());
Resource created = resourceSupplier.get();
if (created == null) return null;
return new StringCachingResource(created);
}
return new StringResource(resourceName, found);
}