/* * 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 . */ 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.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; 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.Path; 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 snippets; private final PlanFiles files; private final ResourceSettings resourceSettings; private final Locale locale; private final PluginLogger logger; private final ErrorLogger errorLogger; @Inject public ResourceSvc( PlanFiles files, PlanConfig config, Locale locale, PluginLogger logger, ErrorLogger errorLogger ) { this.files = files; this.resourceSettings = config.getResourceSettings(); this.locale = locale; this.logger = logger; this.errorLogger = errorLogger; this.snippets = new HashSet<>(); } public void register() { Holder.set(this); } @Override public WebResource getResource(String pluginName, String fileName, Supplier source) { checkParams(pluginName, fileName, source); return applySnippets(pluginName, fileName, getTheResource(pluginName, fileName, source)); } public void checkParams(String pluginName, String fileName, Supplier 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 byPosition = calculateSnippets(fileName); if (byPosition.isEmpty()) return resource; String html = applySnippets(resource, byPosition); return WebResource.create(html); } private String applySnippets(WebResource resource, Map 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.PRE_CONTENT); if (toHead != null) { html = StringUtils.replaceOnce(html, "", toHead.append("").toString()); } StringBuilder toBody = byPosition.get(Position.PRE_MAIN_SCRIPT); if (toBody != null) { if (StringUtils.contains(html, "").build(); snippets.add(new Snippet(pluginName, fileName, position, snippet)); if (!"Plan".equals(pluginName)) { 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) { checkParams(pluginName, fileName, position, cssSrcs); String snippet = new TextStringBuilder("").build(); snippets.add(new Snippet(pluginName, fileName, position, snippet)); if (!"Plan".equals(pluginName)) { logger.info(locale.getString(PluginLang.API_ADD_RESOURCE_CSS, pluginName, fileName, position.cleanName())); } } 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 fileName) { return 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); } } }