X-Git-Url: https://code.wpia.club/?a=blobdiff_plain;f=src%2Forg%2Fcacert%2Fgigi%2Foutput%2Ftemplate%2FTemplate.java;h=8c633c422934d415b7da3b813bc5d44512f00753;hb=6d1b746247f6e1eab7d1da17112beb9cf5abb089;hp=d49df9ae2c5a4c8600a0f48e631b1ed9caf91f0b;hpb=98024a6c871785aa7966f55c174715fec317fb94;p=gigi.git diff --git a/src/org/cacert/gigi/output/template/Template.java b/src/org/cacert/gigi/output/template/Template.java index d49df9ae..8c633c42 100644 --- a/src/org/cacert/gigi/output/template/Template.java +++ b/src/org/cacert/gigi/output/template/Template.java @@ -9,17 +9,25 @@ import java.io.PrintWriter; import java.io.Reader; import java.net.URISyntaxException; import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Date; import java.util.LinkedList; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.cacert.gigi.localisation.Language; +import org.cacert.gigi.output.DateSelector; +import org.cacert.gigi.util.DayDate; import org.cacert.gigi.util.HTMLEncoder; +/** + * Represents a loaded template file. + */ public class Template implements Outputable { - class ParseResult { + protected static class ParseResult { TemplateBlock block; @@ -54,13 +62,20 @@ public class Template implements Outputable { private File source; - private static final Pattern CONTROL_PATTERN = Pattern.compile(" ?([a-z]+)\\(\\$([^)]+)\\) ?\\{ ?"); + private static final Pattern CONTROL_PATTERN = Pattern.compile(" ?([a-zA-Z]+)\\(\\$([^)]+)\\) ?\\{ ?"); private static final Pattern ELSE_PATTERN = Pattern.compile(" ?\\} ?else ?\\{ ?"); + /** + * Creates a new template by parsing the contents from the given URL. This + * constructor will fail on syntax error. When the URL points to a file, + * {@link File#lastModified()} is monitored for changes of the template. + * + * @param u + * the URL to load the template from. UTF-8 is chosen as charset. + */ public Template(URL u) { - try { - Reader r = new InputStreamReader(u.openStream(), "UTF-8"); + try (Reader r = new InputStreamReader(u.openStream(), "UTF-8")) { try { if (u.getProtocol().equals("file")) { source = new File(u.toURI()); @@ -70,12 +85,18 @@ public class Template implements Outputable { e.printStackTrace(); } data = parse(r).getBlock(null); - r.close(); } catch (IOException e) { throw new Error(e); } } + /** + * Creates a new template by parsing the contents from the given reader. + * This constructor will fail on syntax error. + * + * @param r + * the Reader containing the data. + */ public Template(Reader r) { try { data = parse(r).getBlock(null); @@ -85,9 +106,13 @@ public class Template implements Outputable { } } - private ParseResult parse(Reader r) throws IOException { + protected ParseResult parse(Reader r) throws IOException { + return parseContent(r); + } + + protected ParseResult parseContent(Reader r) throws IOException { LinkedList splitted = new LinkedList(); - LinkedList commands = new LinkedList(); + LinkedList commands = new LinkedList(); StringBuffer buf = new StringBuffer(); String blockType = null; outer: @@ -98,6 +123,9 @@ public class Template implements Outputable { break outer; } buf.append((char) ch); + if (endsWith(buf, "\\\n")) { + buf.delete(buf.length() - 2, buf.length()); + } } buf.delete(buf.length() - 2, buf.length()); splitted.add(buf.toString()); @@ -116,10 +144,10 @@ public class Template implements Outputable { if (m.matches()) { String type = m.group(1); String variable = m.group(2); - ParseResult body = parse(r); + ParseResult body = parseContent(r); if (type.equals("if")) { if ("else".equals(body.getEndType())) { - commands.add(new IfStatement(variable, body.getBlock("else"), parse(r).getBlock("}"))); + commands.add(new IfStatement(variable, body.getBlock("else"), parseContent(r).getBlock("}"))); } else { commands.add(new IfStatement(variable, body.getBlock("}"))); } @@ -140,14 +168,14 @@ public class Template implements Outputable { } } splitted.add(buf.toString()); - return new ParseResult(new TemplateBlock(splitted.toArray(new String[splitted.size()]), commands.toArray(new Outputable[commands.size()])), blockType); + return new ParseResult(new TemplateBlock(splitted.toArray(new String[splitted.size()]), commands.toArray(new Translatable[commands.size()])), blockType); } private boolean endsWith(StringBuffer buf, String string) { return buf.length() >= string.length() && buf.substring(buf.length() - string.length(), buf.length()).equals(string); } - private Outputable parseCommand(String s2) { + private Translatable parseCommand(String s2) { if (s2.startsWith("=_")) { final String raw = s2.substring(2); if ( !s2.contains("$") && !s2.contains("!'")) { @@ -165,6 +193,11 @@ public class Template implements Outputable { @Override public void output(PrintWriter out, Language l, Map vars) { + tryReload(); + data.output(out, l, vars); + } + + protected void tryReload() { if (source != null && lastLoaded < source.lastModified()) { try { System.out.println("Reloading template.... " + source); @@ -176,10 +209,12 @@ public class Template implements Outputable { e.printStackTrace(); } } - data.output(out, l, vars); } protected static void outputVar(PrintWriter out, Language l, Map vars, String varname, boolean unescaped) { + if (vars.containsKey(Outputable.OUT_KEY_PLAIN)) { + unescaped = true; + } Object s = vars.get(varname); if (s == null) { @@ -187,8 +222,22 @@ public class Template implements Outputable { } if (s instanceof Outputable) { ((Outputable) s).output(out, l, vars); + } else if (s instanceof DayDate) { + out.print(DateSelector.getDateFormat().format(((DayDate) s).toDate())); + } else if (s instanceof Boolean) { + out.print(((Boolean) s) ? l.getTranslation("yes") : l.getTranslation("no")); + } else if (s instanceof Date) { + SimpleDateFormat sdfUI = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + out.print(""); } else { out.print(s == null ? "null" : (unescaped ? s.toString() : HTMLEncoder.encodeHTML(s.toString()))); } } + + public void addTranslations(Collection s) { + data.addTranslations(s); + } }