/* * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If * not, see <http://www.gnu.org/licenses/>. */ package silentium.gameserver.data.html; import com.google.common.base.Charsets; import com.google.common.base.Strings; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.io.Files; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import silentium.commons.io.filters.CustomFileNameFilter; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; /** * @author Layane * @author Java-man * @author Tatanka */ public final class HtmCache { private static final Logger log = LoggerFactory.getLogger(HtmCache.class); private static final Pattern LFCR_PATTERN = Pattern.compile("\r\n"); private static final int MAX_HTML_LENGTH = 8196; private static final FilenameFilter HTM_FILTER = CustomFileNameFilter.create().setPattern(".htm"); private final LoadingCache<String, String> cache = CacheBuilder.newBuilder().maximumSize(5000L).expireAfterAccess(1L, TimeUnit.HOURS).build(new CacheLoader<String, String>() { @Override public String load(final String key) throws Exception { return loadFile(key); } }); public static HtmCache getInstance() { return SingletonHolder.INSTANCE; } HtmCache() { reload(); } public void reload() { cache.invalidateAll(); log.info("Cache[HTML]: Running lazy cache"); } public void reloadPath(final File file) { parseDir(file); log.info("Cache[HTML]: Reloaded specified path."); } private void parseDir(final File dir) { final File[] files = dir.listFiles(HTM_FILTER); for (final File file : files) { if (file.isDirectory()) parseDir(file); else loadFile(file.getPath()); } } private String loadFile(final String path) { return loadFile(new File(path)); } public String loadFile(final File file) { final StringBuilder stringBuilder = new StringBuilder(MAX_HTML_LENGTH); try { final List<String> lines = Files.readLines(file, Charsets.UTF_8); for (final String line : lines) { stringBuilder.append(line); stringBuilder.append('\n'); } String content = stringBuilder.toString(); content = LFCR_PATTERN.matcher(content).replaceAll("\n"); cache.put(file.getPath(), content); return content; } catch (IOException e) { log.warn("Problem with htm file '{}':{}", file.getName(), e.getLocalizedMessage()); } finally { stringBuilder.setLength(0); } return null; } public String getHtmForce(final String path) { String content = getHtm(path); if (Strings.isNullOrEmpty(content)) { content = "<html><body>My text is missing:<br>" + path + "</body></html>"; log.warn("Cache[HTML]: Missing HTML page: " + path); } return content; } public String getHtm(final String path) { if (Strings.isNullOrEmpty(path)) return ""; // avoid possible NPE String content = ""; try { content = cache.get(path); } catch (ExecutionException e) { log.warn(e.getLocalizedMessage(), e); } return content; } /** * Check if an HTM exists and can be loaded * * @param path The path to the HTM * @return true if the HTM can be loaded. */ public static boolean isLoadable(final String path) { final File file = new File(path); return HTM_FILTER.accept(file, file.getName()); } private static class SingletonHolder { static final HtmCache INSTANCE = new HtmCache(); } }