package songbook.server;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
/**
* Contains functions that generate a string from a template
* Created by j5r on 01/05/2014.
*/
public class Templates {
private final static Map<String, TemplateCache> cache = new HashMap<>();
private static Path TEMPLATES_PATH = Paths.get("web/templates");
public static void setTemplatesPath(Path templatesPath) {
cache.clear();
TEMPLATES_PATH = templatesPath;
}
public static <A extends Appendable> A header(A out, CharSequence title, CharSequence role) {
return print(out, "header.html", "title", title, "role", role);
}
public static <A extends Appendable> A footer(A out) {
return print(out, "footer.html");
}
public static <A extends Appendable> A search(A out, CharSequence searchResult, CharSequence role) {
return print(out, "search.html", "searchResult", searchResult, "role", role);
}
public static <A extends Appendable> A editSong(A out, CharSequence songId, CharSequence song, CharSequence role) {
return print(out, "editSong.html", "songId", songId, "song", song, "role", role);
}
public static <A extends Appendable> A viewSong(A out, CharSequence songId, CharSequence song, CharSequence role) {
return print(out, "viewSong.html", "songId", songId, "song", song, "role", role);
}
public static <A extends Appendable> A newSong(A out) {
return print(out, "newSong.song");
}
public static <A extends Appendable> A startItems(A out) {
return print(out, "startItems.html");
}
public static <A extends Appendable> A songItem(A out, CharSequence songId, CharSequence songTitle, CharSequence songArtist) {
return print(out, "songItem.html", "songId", songId, "songTitle", songTitle, "songArtist", songArtist);
}
public static <A extends Appendable> A artistItem(A out, CharSequence artist, int songCount) {
return print(out, "artistItem.html", "artist", artist, "songCount", Integer.toString(songCount));
}
public static <A extends Appendable> A endItems(A out) {
return print(out, "endItems.html");
}
public static <A extends Appendable> A signin(A out) {
return print(out, "signin.html");
}
public static <A extends Appendable> A admin(A out) {
return print(out, "admin.html");
}
public static <A extends Appendable> A consoleApi(A out) {
return print(out, "consoleApi.html");
}
public static <A extends Appendable> A alertSongDoesNotExist(A out, CharSequence songId) {
return print(out, "alerts/songDoesNotExist.html", "songId", songId);
}
public static <A extends Appendable> A alertMissingArguments(A out, CharSequence arguments) {
return print(out, "alerts/songDoesNotExist.html", "arguments", arguments);
}
public static <A extends Appendable> A alertKeyCreation(A out, CharSequence adminSessionKey, CharSequence path) {
return print(out, "alerts/keyCreation.html", "adminSessionKey", adminSessionKey, "path", path);
}
public static <A extends Appendable> A alertSongReindexed(A out) {
return print(out, "alerts/songReindexed.html");
}
public static <A extends Appendable> A alertAccessForbidden(A out, CharSequence path) {
return print(out, "alerts/accessForbidden.html", "path", path);
}
public static <A extends Appendable> A alertIndexingError(A out) {
return print(out, "alerts/indexingError.html");
}
public static <A extends Appendable> A alertCommandNotSupported(A out) {
return print(out, "alerts/commandNotSupported.html");
}
public static <A extends Appendable> A alertSongRemovedSuccessfully(A out, CharSequence songTitle) {
return print(out, "alerts/songRemovedSuccessfully.html", "songTitle", songTitle);
}
protected static <A extends Appendable> A print(A out, String templateName, CharSequence... vars) {
try {
String content = getContent(templateName);
for (int i = 0; i < vars.length; i += 2) {
CharSequence value = vars[i+1];
if (value == null) {
value = "";
}
content = content.replace("${" + vars[i] + "}", value);
}
out.append(content);
} catch (IOException e) {
e.printStackTrace();
}
return out;
}
private static class TemplateCache {
long time;
String content;
public TemplateCache(long time, String content) {
this.time = time;
this.content = content;
}
}
private static String getContent(String templateName) throws IOException {
TemplateCache templateCache = cache.get(templateName);
Path templatePath = TEMPLATES_PATH.resolve(templateName);
boolean needLoading;
long lastModified = -1;
if (templateCache == null) {
needLoading = true;
} else {
lastModified = Files.getLastModifiedTime(templatePath).toMillis();
needLoading = lastModified > templateCache.time;
}
if (needLoading) {
cache.remove(templateName);
templateCache = new TemplateCache(lastModified, new String(Files.readAllBytes(templatePath), StandardCharsets.UTF_8));
cache.put(templateName, templateCache);
}
return templateCache.content;
}
}