From: David ‘Bombe’ Roden Date: Wed, 19 Jan 2011 18:12:40 +0000 (+0100) Subject: Merge branch 'mark-as-read' into next X-Git-Tag: 0.4.2^2~27 X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=commitdiff_plain;h=ecf753a31601e558b681daab0598009fe9eec99a;hp=92e44c7068d88f23a29a4f82da3b91135c3ef2f2 Merge branch 'mark-as-read' into next Conflicts: src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java --- diff --git a/src/main/java/net/pterodactylus/sone/core/Core.java b/src/main/java/net/pterodactylus/sone/core/Core.java index 27e8db8..c8d500e 100644 --- a/src/main/java/net/pterodactylus/sone/core/Core.java +++ b/src/main/java/net/pterodactylus/sone/core/Core.java @@ -415,6 +415,7 @@ public class Core implements IdentityListener, UpdateListener { if ((sone == null) && create) { sone = new Sone(id); localSones.put(id, sone); + setSoneStatus(sone, SoneStatus.unknown); } return sone; } @@ -458,6 +459,7 @@ public class Core implements IdentityListener, UpdateListener { if ((sone == null) && create) { sone = new Sone(id); remoteSones.put(id, sone); + setSoneStatus(sone, SoneStatus.unknown); } return sone; } @@ -492,20 +494,38 @@ public class Core implements IdentityListener, UpdateListener { } /** - * Returns whether the given Sone is a new Sone. After this check, the Sone - * is marked as known, i.e. a second call with the same parameters will - * always yield {@code false}. + * Returns whether the Sone with the given ID is a new Sone. After this + * check, the Sone is marked as known, i.e. a second call with the same + * parameters will always yield {@code false}. * - * @param sone - * The sone to check for + * @param soneId + * The ID of the sone to check for * @return {@code true} if the given Sone is new, false otherwise */ - public boolean isNewSone(Sone sone) { + public boolean isNewSone(String soneId) { + return isNewSone(soneId, true); + } + + /** + * Returns whether the Sone with the given ID is a new Sone. The Sone will + * be marked as known if {@code markAsKnown} is {@code true}, otherwise the + * Sone will keep its current “new” state. + * + * @param soneId + * The ID of the sone to check for + * @param markAsKnown + * {@code true} to mark the Sone as known in any case, + * {@code false} to not mark it as known + * @return {@code true} if the given Sone is new, false otherwise + */ + public boolean isNewSone(String soneId, boolean markAsKnown) { synchronized (newSones) { - boolean isNew = !knownSones.contains(sone.getId()) && newSones.remove(sone.getId()); - knownSones.add(sone.getId()); - if (isNew) { - coreListenerManager.fireMarkSoneKnown(sone); + boolean isNew = !knownSones.contains(soneId) && newSones.contains(soneId); + if (markAsKnown) { + Sone sone = getSone(soneId, false); + if (sone != null) { + markSoneKnown(sone); + } } return isNew; } @@ -1123,6 +1143,23 @@ public class Core implements IdentityListener, UpdateListener { } /** + * Marks the given Sone as known. If the Sone was {@link #isNewPost(String) + * new} before, a {@link CoreListener#markSoneKnown(Sone)} event is fired. + * + * @param sone + * The Sone to mark as known + */ + public void markSoneKnown(Sone sone) { + synchronized (newSones) { + if (newSones.remove(sone.getId())) { + knownSones.add(sone.getId()); + coreListenerManager.fireMarkSoneKnown(sone); + saveConfiguration(); + } + } + } + + /** * Loads and updates the given Sone from the configuration. If any error is * encountered, loading is aborted and the given Sone is not changed. * diff --git a/src/main/java/net/pterodactylus/sone/core/SoneInserter.java b/src/main/java/net/pterodactylus/sone/core/SoneInserter.java index c15b1d0..3115877 100644 --- a/src/main/java/net/pterodactylus/sone/core/SoneInserter.java +++ b/src/main/java/net/pterodactylus/sone/core/SoneInserter.java @@ -36,10 +36,12 @@ import net.pterodactylus.sone.main.SonePlugin; import net.pterodactylus.util.io.Closer; import net.pterodactylus.util.logging.Logging; import net.pterodactylus.util.service.AbstractService; -import net.pterodactylus.util.template.DefaultTemplateFactory; import net.pterodactylus.util.template.ReflectionAccessor; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; +import net.pterodactylus.util.template.TemplateContextFactory; import net.pterodactylus.util.template.TemplateException; +import net.pterodactylus.util.template.TemplateParser; import net.pterodactylus.util.template.XmlFilter; import freenet.client.async.ManifestElement; import freenet.keys.FreenetURI; @@ -58,11 +60,11 @@ public class SoneInserter extends AbstractService { private static volatile int insertionDelay = 60; /** The template factory used to create the templates. */ - private static final DefaultTemplateFactory templateFactory = new DefaultTemplateFactory(); + private static final TemplateContextFactory templateContextFactory = new TemplateContextFactory(); static { - templateFactory.addAccessor(Object.class, new ReflectionAccessor()); - templateFactory.addFilter("xml", new XmlFilter()); + templateContextFactory.addAccessor(Object.class, new ReflectionAccessor()); + templateContextFactory.addFilter("xml", new XmlFilter()); } /** The UTF-8 charset. */ @@ -326,10 +328,11 @@ public class SoneInserter extends AbstractService { */ @SuppressWarnings("synthetic-access") private ManifestElement createManifestElement(String name, String contentType, String templateName) { - InputStreamReader templateInputStreamReader; - Template template = templateFactory.createTemplate(templateInputStreamReader = new InputStreamReader(getClass().getResourceAsStream(templateName), utf8Charset)); + InputStreamReader templateInputStreamReader = null; + Template template; try { - template.parse(); + templateInputStreamReader = new InputStreamReader(getClass().getResourceAsStream(templateName), utf8Charset); + template = TemplateParser.parse(templateInputStreamReader); } catch (TemplateException te1) { logger.log(Level.SEVERE, "Could not parse template “" + templateName + "”!", te1); return null; @@ -337,12 +340,13 @@ public class SoneInserter extends AbstractService { Closer.close(templateInputStreamReader); } - template.set("currentSone", soneProperties); - template.set("version", SonePlugin.VERSION); + TemplateContext templateContext = templateContextFactory.createTemplateContext(); + templateContext.set("currentSone", soneProperties); + templateContext.set("version", SonePlugin.VERSION); StringWriter writer = new StringWriter(); StringBucket bucket = null; try { - template.render(writer); + template.render(templateContext, writer); bucket = new StringBucket(writer.toString(), utf8Charset); return new ManifestElement(name, bucket, contentType, bucket.size()); } catch (TemplateException te1) { diff --git a/src/main/java/net/pterodactylus/sone/freenet/L10nFilter.java b/src/main/java/net/pterodactylus/sone/freenet/L10nFilter.java index 4d6a744..ef1a183 100644 --- a/src/main/java/net/pterodactylus/sone/freenet/L10nFilter.java +++ b/src/main/java/net/pterodactylus/sone/freenet/L10nFilter.java @@ -19,8 +19,8 @@ package net.pterodactylus.sone.freenet; import java.util.Map; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Filter; +import net.pterodactylus.util.template.TemplateContext; import freenet.l10n.BaseL10n; /** @@ -48,7 +48,7 @@ public class L10nFilter implements Filter { * {@inheritDoc} */ @Override - public String format(DataProvider dataProvider, Object data, Map parameters) { + public String format(TemplateContext templateContext, Object data, Map parameters) { return l10n.getString(String.valueOf(data)); } diff --git a/src/main/java/net/pterodactylus/sone/notify/ListNotification.java b/src/main/java/net/pterodactylus/sone/notify/ListNotification.java index 7d3e3c7..c7e5b7c 100644 --- a/src/main/java/net/pterodactylus/sone/notify/ListNotification.java +++ b/src/main/java/net/pterodactylus/sone/notify/ListNotification.java @@ -48,8 +48,7 @@ public class ListNotification extends TemplateNotification { */ public ListNotification(String id, String key, Template template) { super(id, template); - template.set(key, elements); - template.set("notification", this); + template.getInitialContext().set(key, elements); } // diff --git a/src/main/java/net/pterodactylus/sone/template/CollectionAccessor.java b/src/main/java/net/pterodactylus/sone/template/CollectionAccessor.java index 10e3ea3..0fa9129 100644 --- a/src/main/java/net/pterodactylus/sone/template/CollectionAccessor.java +++ b/src/main/java/net/pterodactylus/sone/template/CollectionAccessor.java @@ -24,8 +24,8 @@ import java.util.List; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.util.template.Accessor; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.ReflectionAccessor; +import net.pterodactylus.util.template.TemplateContext; /** * {@link Accessor} for {@link Collection}s that adds a couple of specialized @@ -44,7 +44,7 @@ public class CollectionAccessor extends ReflectionAccessor { * {@inheritDoc} */ @Override - public Object get(DataProvider dataProvider, Object object, String member) { + public Object get(TemplateContext templateContext, Object object, String member) { if (object == null) { return null; } @@ -67,7 +67,7 @@ public class CollectionAccessor extends ReflectionAccessor { } return soneNames.toString(); } - return super.get(dataProvider, object, member); + return super.get(templateContext, object, member); } } diff --git a/src/main/java/net/pterodactylus/sone/template/CssClassNameFilter.java b/src/main/java/net/pterodactylus/sone/template/CssClassNameFilter.java index 6ba5d6b..611c6d1 100644 --- a/src/main/java/net/pterodactylus/sone/template/CssClassNameFilter.java +++ b/src/main/java/net/pterodactylus/sone/template/CssClassNameFilter.java @@ -19,8 +19,8 @@ package net.pterodactylus.sone.template; import java.util.Map; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Filter; +import net.pterodactylus.util.template.TemplateContext; /** * Converts the {@link String} {@link String#valueOf(Object) representation} of @@ -35,7 +35,7 @@ public class CssClassNameFilter implements Filter { * {@inheritDoc} */ @Override - public Object format(DataProvider dataProvider, Object data, Map parameters) { + public Object format(TemplateContext templateContext, Object data, Map parameters) { return String.valueOf(data).replaceAll("[^a-zA-Z0-9-]", "_"); } diff --git a/src/main/java/net/pterodactylus/sone/template/GetPagePlugin.java b/src/main/java/net/pterodactylus/sone/template/GetPagePlugin.java index 1b36c05..a25d619 100644 --- a/src/main/java/net/pterodactylus/sone/template/GetPagePlugin.java +++ b/src/main/java/net/pterodactylus/sone/template/GetPagePlugin.java @@ -20,12 +20,12 @@ package net.pterodactylus.sone.template; import java.util.Map; import net.pterodactylus.sone.web.page.Page.Request; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Plugin; +import net.pterodactylus.util.template.TemplateContext; /** - * Extracts a page number from a {@link Request}’s parameters and stores it in a - * {@link DataProvider}. + * Extracts a page number from a {@link Request}’s parameters and stores it in + * the {@link TemplateContext}. * * @author David ‘Bombe’ Roden */ @@ -35,7 +35,7 @@ public class GetPagePlugin implements Plugin { * {@inheritDoc} */ @Override - public void execute(DataProvider dataProvider, Map parameters) { + public void execute(TemplateContext templateContext, Map parameters) { String requestKey = parameters.get("request"); String parameter = parameters.get("parameter"); String pageKey = parameters.get("key"); @@ -50,7 +50,7 @@ public class GetPagePlugin implements Plugin { pageKey = "page"; } - Request request = (Request) dataProvider.get(requestKey); + Request request = (Request) templateContext.get(requestKey); String pageString = request.getHttpRequest().getParam(parameter); int page = 0; try { @@ -58,7 +58,7 @@ public class GetPagePlugin implements Plugin { } catch (NumberFormatException nfe1) { /* ignore. */ } - dataProvider.set(pageKey, page); + templateContext.set(pageKey, page); } } diff --git a/src/main/java/net/pterodactylus/sone/template/IdentityAccessor.java b/src/main/java/net/pterodactylus/sone/template/IdentityAccessor.java index 84989b3..eec9347 100644 --- a/src/main/java/net/pterodactylus/sone/template/IdentityAccessor.java +++ b/src/main/java/net/pterodactylus/sone/template/IdentityAccessor.java @@ -23,8 +23,8 @@ import net.pterodactylus.sone.core.Core; import net.pterodactylus.sone.freenet.wot.Identity; import net.pterodactylus.sone.freenet.wot.OwnIdentity; import net.pterodactylus.util.template.Accessor; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.ReflectionAccessor; +import net.pterodactylus.util.template.TemplateContext; /** * {@link Accessor} implementation that adds a “uniqueNickname” member to an @@ -51,7 +51,7 @@ public class IdentityAccessor extends ReflectionAccessor { * {@inheritDoc} */ @Override - public Object get(DataProvider dataProvider, Object object, String member) { + public Object get(TemplateContext templateContext, Object object, String member) { Identity identity = (Identity) object; if ("uniqueNickname".equals(member)) { int minLength = -1; @@ -75,7 +75,7 @@ public class IdentityAccessor extends ReflectionAccessor { } while (!found && (minLength < 43)); return getAbbreviatedNickname(identity, minLength); } - return super.get(dataProvider, object, member); + return super.get(templateContext, object, member); } // diff --git a/src/main/java/net/pterodactylus/sone/template/JavascriptFilter.java b/src/main/java/net/pterodactylus/sone/template/JavascriptFilter.java index 0cd55de..f852202 100644 --- a/src/main/java/net/pterodactylus/sone/template/JavascriptFilter.java +++ b/src/main/java/net/pterodactylus/sone/template/JavascriptFilter.java @@ -20,8 +20,8 @@ package net.pterodactylus.sone.template; import java.util.Map; import net.pterodactylus.util.number.Hex; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Filter; +import net.pterodactylus.util.template.TemplateContext; /** * Escapes double quotes, backslashes, carriage returns and line feeds, and @@ -36,7 +36,7 @@ public class JavascriptFilter implements Filter { * {@inheritDoc} */ @Override - public Object format(DataProvider dataProvider, Object data, Map parameters) { + public Object format(TemplateContext templateContext, Object data, Map parameters) { StringBuilder javascriptString = new StringBuilder(); javascriptString.append('"'); for (char c : String.valueOf(data).toCharArray()) { diff --git a/src/main/java/net/pterodactylus/sone/template/NotificationManagerAccessor.java b/src/main/java/net/pterodactylus/sone/template/NotificationManagerAccessor.java index 1c27b29..a8f34a8 100644 --- a/src/main/java/net/pterodactylus/sone/template/NotificationManagerAccessor.java +++ b/src/main/java/net/pterodactylus/sone/template/NotificationManagerAccessor.java @@ -23,8 +23,8 @@ import java.util.List; import net.pterodactylus.util.notify.Notification; import net.pterodactylus.util.notify.NotificationManager; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.ReflectionAccessor; +import net.pterodactylus.util.template.TemplateContext; /** * Adds additional properties to a {@link NotificationManager}. @@ -44,7 +44,7 @@ public class NotificationManagerAccessor extends ReflectionAccessor { * {@inheritDoc} */ @Override - public Object get(DataProvider dataProvider, Object object, String member) { + public Object get(TemplateContext templateContext, Object object, String member) { NotificationManager notificationManager = (NotificationManager) object; if ("all".equals(member)) { List notifications = new ArrayList(notificationManager.getNotifications()); @@ -55,7 +55,7 @@ public class NotificationManagerAccessor extends ReflectionAccessor { Collections.sort(notifications, Notification.LAST_UPDATED_TIME_SORTER); return notifications; } - return super.get(dataProvider, object, member); + return super.get(templateContext, object, member); } } diff --git a/src/main/java/net/pterodactylus/sone/template/ParserFilter.java b/src/main/java/net/pterodactylus/sone/template/ParserFilter.java index 6099ee7..f1190e0 100644 --- a/src/main/java/net/pterodactylus/sone/template/ParserFilter.java +++ b/src/main/java/net/pterodactylus/sone/template/ParserFilter.java @@ -24,9 +24,9 @@ import java.util.Map; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.text.FreenetLinkParser; import net.pterodactylus.sone.text.FreenetLinkParserContext; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Filter; -import net.pterodactylus.util.template.TemplateFactory; +import net.pterodactylus.util.template.TemplateContext; +import net.pterodactylus.util.template.TemplateContextFactory; /** * Filter that filters a given text through a {@link FreenetLinkParser}. @@ -39,26 +39,27 @@ public class ParserFilter implements Filter { private final FreenetLinkParser linkParser; /** - * Creates a new parser filter. + * Creates a new filter that runs its input through a + * {@link FreenetLinkParser}. * - * @param templateFactory - * The template factory for the link parser + * @param templateContextFactory + * The context factory for rendering the parts */ - public ParserFilter(TemplateFactory templateFactory) { - this.linkParser = new FreenetLinkParser(templateFactory); + public ParserFilter(TemplateContextFactory templateContextFactory) { + linkParser = new FreenetLinkParser(templateContextFactory); } /** * {@inheritDoc} */ @Override - public Object format(DataProvider dataProvider, Object data, Map parameters) { + public Object format(TemplateContext templateContext, Object data, Map parameters) { String text = String.valueOf(data); String soneKey = parameters.get("sone"); if (soneKey == null) { soneKey = "sone"; } - Sone sone = (Sone) dataProvider.get(soneKey); + Sone sone = (Sone) templateContext.get(soneKey); FreenetLinkParserContext context = new FreenetLinkParserContext(sone); try { return linkParser.parse(context, new StringReader(text)); diff --git a/src/main/java/net/pterodactylus/sone/template/PostAccessor.java b/src/main/java/net/pterodactylus/sone/template/PostAccessor.java index d3af897..abdc4c8 100644 --- a/src/main/java/net/pterodactylus/sone/template/PostAccessor.java +++ b/src/main/java/net/pterodactylus/sone/template/PostAccessor.java @@ -20,8 +20,8 @@ package net.pterodactylus.sone.template; import net.pterodactylus.sone.core.Core; import net.pterodactylus.sone.data.Post; import net.pterodactylus.sone.data.Sone; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.ReflectionAccessor; +import net.pterodactylus.util.template.TemplateContext; /** * Accessor for {@link Post} objects that adds additional properties: @@ -51,19 +51,19 @@ public class PostAccessor extends ReflectionAccessor { * {@inheritDoc} */ @Override - public Object get(DataProvider dataProvider, Object object, String member) { + public Object get(TemplateContext templateContext, Object object, String member) { Post post = (Post) object; if ("replies".equals(member)) { return core.getReplies(post); } else if (member.equals("likes")) { return core.getLikes(post); } else if (member.equals("liked")) { - Sone currentSone = (Sone) dataProvider.get("currentSone"); + Sone currentSone = (Sone) templateContext.get("currentSone"); return (currentSone != null) && (currentSone.isLikedPostId(post.getId())); } else if (member.equals("new")) { return core.isNewPost(post.getId(), false); } - return super.get(dataProvider, object, member); + return super.get(templateContext, object, member); } } diff --git a/src/main/java/net/pterodactylus/sone/template/ReplyAccessor.java b/src/main/java/net/pterodactylus/sone/template/ReplyAccessor.java index 41fbf4e..efba587 100644 --- a/src/main/java/net/pterodactylus/sone/template/ReplyAccessor.java +++ b/src/main/java/net/pterodactylus/sone/template/ReplyAccessor.java @@ -21,8 +21,8 @@ import net.pterodactylus.sone.core.Core; import net.pterodactylus.sone.data.Reply; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.util.template.Accessor; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.ReflectionAccessor; +import net.pterodactylus.util.template.TemplateContext; /** * {@link Accessor} implementation that adds a couple of properties to @@ -49,17 +49,17 @@ public class ReplyAccessor extends ReflectionAccessor { * {@inheritDoc} */ @Override - public Object get(DataProvider dataProvider, Object object, String member) { + public Object get(TemplateContext templateContext, Object object, String member) { Reply reply = (Reply) object; if ("likes".equals(member)) { return core.getLikes(reply); } else if (member.equals("liked")) { - Sone currentSone = (Sone) dataProvider.get("currentSone"); + Sone currentSone = (Sone) templateContext.get("currentSone"); return (currentSone != null) && (currentSone.isLikedReplyId(reply.getId())); } else if (member.equals("new")) { return core.isNewReply(reply.getId(), false); } - return super.get(dataProvider, object, member); + return super.get(templateContext, object, member); } } diff --git a/src/main/java/net/pterodactylus/sone/template/RequestChangeFilter.java b/src/main/java/net/pterodactylus/sone/template/RequestChangeFilter.java index c4c2277..fb31719 100644 --- a/src/main/java/net/pterodactylus/sone/template/RequestChangeFilter.java +++ b/src/main/java/net/pterodactylus/sone/template/RequestChangeFilter.java @@ -27,8 +27,8 @@ import java.util.Map; import java.util.Map.Entry; import net.pterodactylus.sone.web.page.Page.Request; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Filter; +import net.pterodactylus.util.template.TemplateContext; /** * This filter expects a {@link Request} as input and outputs a {@link URI} that @@ -44,17 +44,17 @@ public class RequestChangeFilter implements Filter { * {@inheritDoc} */ @Override - public Object format(DataProvider dataProvider, Object data, Map parameters) { + public Object format(TemplateContext templateContext, Object data, Map parameters) { Request request = (Request) data; String name = parameters.get("name"); String nameKey = parameters.get("nameKey"); if (nameKey != null) { - name = String.valueOf(dataProvider.get(nameKey)); + name = String.valueOf(templateContext.get(nameKey)); } String key = parameters.get("key"); String value = null; if (key != null) { - value = String.valueOf(dataProvider.get(key)); + value = String.valueOf(templateContext.get(key)); } if (value == null) { value = parameters.get("value"); diff --git a/src/main/java/net/pterodactylus/sone/template/SoneAccessor.java b/src/main/java/net/pterodactylus/sone/template/SoneAccessor.java index 119a28e..27b4c24 100644 --- a/src/main/java/net/pterodactylus/sone/template/SoneAccessor.java +++ b/src/main/java/net/pterodactylus/sone/template/SoneAccessor.java @@ -27,8 +27,8 @@ import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.freenet.wot.Trust; import net.pterodactylus.util.logging.Logging; import net.pterodactylus.util.template.Accessor; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.ReflectionAccessor; +import net.pterodactylus.util.template.TemplateContext; /** * {@link Accessor} for {@link Sone}s that adds a couple of properties to Sones. @@ -39,7 +39,7 @@ import net.pterodactylus.util.template.ReflectionAccessor; *
friend
*
Will return {@code true} if the sone in question is a friend of the * currently logged in Sone (as determined by accessing the “currentSone” - * variable of the given {@link DataProvider}).
+ * variable of the given {@link TemplateContext}). *
current
*
Will return {@code true} if the sone in question is the currently logged * in Sone.
@@ -69,17 +69,17 @@ public class SoneAccessor extends ReflectionAccessor { * {@inheritDoc} */ @Override - public Object get(DataProvider dataProvider, Object object, String member) { + public Object get(TemplateContext templateContext, Object object, String member) { Sone sone = (Sone) object; if (member.equals("niceName")) { return getNiceName(sone); } else if (member.equals("local")) { return core.isLocalSone(sone); } else if (member.equals("friend")) { - Sone currentSone = (Sone) dataProvider.get("currentSone"); + Sone currentSone = (Sone) templateContext.get("currentSone"); return (currentSone != null) && currentSone.hasFriend(sone.getId()); } else if (member.equals("current")) { - Sone currentSone = (Sone) dataProvider.get("currentSone"); + Sone currentSone = (Sone) templateContext.get("currentSone"); return (currentSone != null) && currentSone.equals(sone); } else if (member.equals("modified")) { return core.isModifiedSone(sone); @@ -94,11 +94,11 @@ public class SoneAccessor extends ReflectionAccessor { } else if (member.equals("downloading")) { return core.getSoneStatus(sone) == SoneStatus.downloading; } else if (member.equals("new")) { - return core.isNewSone(sone); + return core.isNewSone(sone.getId(), false); } else if (member.equals("locked")) { return core.isLocked(sone); } else if (member.equals("trust")) { - Sone currentSone = (Sone) dataProvider.get("currentSone"); + Sone currentSone = (Sone) templateContext.get("currentSone"); if (currentSone == null) { return null; } @@ -109,7 +109,7 @@ public class SoneAccessor extends ReflectionAccessor { } return trust; } - return super.get(dataProvider, object, member); + return super.get(templateContext, object, member); } // diff --git a/src/main/java/net/pterodactylus/sone/template/SubstringFilter.java b/src/main/java/net/pterodactylus/sone/template/SubstringFilter.java index f0075e4..857017c 100644 --- a/src/main/java/net/pterodactylus/sone/template/SubstringFilter.java +++ b/src/main/java/net/pterodactylus/sone/template/SubstringFilter.java @@ -19,8 +19,8 @@ package net.pterodactylus.sone.template; import java.util.Map; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Filter; +import net.pterodactylus.util.template.TemplateContext; /** * {@link Filter} implementation that executes @@ -37,7 +37,7 @@ public class SubstringFilter implements Filter { * {@inheritDoc} */ @Override - public Object format(DataProvider dataProvider, Object data, Map parameters) { + public Object format(TemplateContext templateContext, Object data, Map parameters) { String startString = parameters.get("start"); String lengthString = parameters.get("length"); int start = 0; diff --git a/src/main/java/net/pterodactylus/sone/template/TrustAccessor.java b/src/main/java/net/pterodactylus/sone/template/TrustAccessor.java index 4dfd81e..4aad3c9 100644 --- a/src/main/java/net/pterodactylus/sone/template/TrustAccessor.java +++ b/src/main/java/net/pterodactylus/sone/template/TrustAccessor.java @@ -19,8 +19,8 @@ package net.pterodactylus.sone.template; import net.pterodactylus.sone.freenet.wot.Trust; import net.pterodactylus.util.template.Accessor; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.ReflectionAccessor; +import net.pterodactylus.util.template.TemplateContext; /** * {@link Accessor} implementation for {@link Trust} values, adding the @@ -39,7 +39,7 @@ public class TrustAccessor extends ReflectionAccessor { * {@inheritDoc} */ @Override - public Object get(DataProvider dataProvider, Object object, String member) { + public Object get(TemplateContext templateContext, Object object, String member) { Trust trust = (Trust) object; if ("assigned".equals(member)) { return trust.getExplicit() != null; @@ -48,7 +48,7 @@ public class TrustAccessor extends ReflectionAccessor { } else if ("hasDistance".equals(member)) { return (trust.getDistance() != null) && (trust.getDistance() != Integer.MAX_VALUE); } - return super.get(dataProvider, object, member); + return super.get(templateContext, object, member); } } diff --git a/src/main/java/net/pterodactylus/sone/template/UnknownDateFilter.java b/src/main/java/net/pterodactylus/sone/template/UnknownDateFilter.java index 4fc95f7..586e90c 100644 --- a/src/main/java/net/pterodactylus/sone/template/UnknownDateFilter.java +++ b/src/main/java/net/pterodactylus/sone/template/UnknownDateFilter.java @@ -19,8 +19,8 @@ package net.pterodactylus.sone.template; import java.util.Map; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Filter; +import net.pterodactylus.util.template.TemplateContext; import freenet.l10n.BaseL10n; /** @@ -54,7 +54,7 @@ public class UnknownDateFilter implements Filter { * {@inheritDoc} */ @Override - public Object format(DataProvider dataProvider, Object data, Map parameters) { + public Object format(TemplateContext templateContext, Object data, Map parameters) { if (data instanceof Long) { if ((Long) data == 0) { return l10nHandler.getString(unknownKey); diff --git a/src/main/java/net/pterodactylus/sone/text/FreenetLinkParser.java b/src/main/java/net/pterodactylus/sone/text/FreenetLinkParser.java index 1ef77d2..704792c 100644 --- a/src/main/java/net/pterodactylus/sone/text/FreenetLinkParser.java +++ b/src/main/java/net/pterodactylus/sone/text/FreenetLinkParser.java @@ -28,7 +28,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import net.pterodactylus.util.logging.Logging; -import net.pterodactylus.util.template.TemplateFactory; +import net.pterodactylus.util.template.TemplateContextFactory; +import net.pterodactylus.util.template.TemplateParser; import freenet.keys.FreenetURI; /** @@ -72,16 +73,16 @@ public class FreenetLinkParser implements Parser { } /** The template factory. */ - private final TemplateFactory templateFactory; + private final TemplateContextFactory templateContextFactory; /** * Creates a new freenet link parser. * - * @param templateFactory - * The template factory + * @param templateContextFactory + * The template context factory */ - public FreenetLinkParser(TemplateFactory templateFactory) { - this.templateFactory = templateFactory; + public FreenetLinkParser(TemplateContextFactory templateContextFactory) { + this.templateContextFactory = templateContextFactory; } // @@ -218,7 +219,7 @@ public class FreenetLinkParser implements Parser { * @return The part that displays the given text */ private Part createPlainTextPart(String text) { - return new TemplatePart(templateFactory.createTemplate(new StringReader("<% text|html>"))).set("text", text); + return new TemplatePart(templateContextFactory, TemplateParser.parse(new StringReader("<% text|html>"))).set("text", text); } /** @@ -232,7 +233,7 @@ public class FreenetLinkParser implements Parser { * @return The part that displays the link */ private Part createInternetLinkPart(String link, String name) { - return new TemplatePart(templateFactory.createTemplate(new StringReader("\" title=\"<% link|html>\"><% name|html>"))).set("link", link).set("name", name); + return new TemplatePart(templateContextFactory, TemplateParser.parse(new StringReader("\" title=\"<% link|html>\"><% name|html>"))).set("link", link).set("name", name); } /** @@ -246,7 +247,7 @@ public class FreenetLinkParser implements Parser { * @return The part that displays the link */ private Part createFreenetLinkPart(String link, String name) { - return new TemplatePart(templateFactory.createTemplate(new StringReader("\" title=\"<% link|html>\"><% name|html>"))).set("link", link).set("name", name); + return new TemplatePart(templateContextFactory, TemplateParser.parse(new StringReader("\" title=\"<% link|html>\"><% name|html>"))).set("link", link).set("name", name); } /** @@ -260,7 +261,7 @@ public class FreenetLinkParser implements Parser { * @return The part that displays the link */ private Part createTrustedFreenetLinkPart(String link, String name) { - return new TemplatePart(templateFactory.createTemplate(new StringReader("\" title=\"<% link|html>\"><% name|html>"))).set("link", link).set("name", name); + return new TemplatePart(templateContextFactory, TemplateParser.parse(new StringReader("\" title=\"<% link|html>\"><% name|html>"))).set("link", link).set("name", name); } } diff --git a/src/main/java/net/pterodactylus/sone/text/TemplatePart.java b/src/main/java/net/pterodactylus/sone/text/TemplatePart.java index 1663e08..1ac1fdd 100644 --- a/src/main/java/net/pterodactylus/sone/text/TemplatePart.java +++ b/src/main/java/net/pterodactylus/sone/text/TemplatePart.java @@ -21,13 +21,19 @@ import java.io.IOException; import java.io.Writer; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; +import net.pterodactylus.util.template.TemplateContextFactory; +import net.pterodactylus.util.template.TemplateException; /** * {@link Part} implementation that is rendered using a {@link Template}. * * @author David ‘Bombe’ Roden */ -public class TemplatePart implements Part { +public class TemplatePart implements Part, net.pterodactylus.util.template.Part { + + /** The template context factory. */ + private final TemplateContextFactory templateContextFactory; /** The template to render for this part. */ private final Template template; @@ -35,10 +41,13 @@ public class TemplatePart implements Part { /** * Creates a new template part. * + * @param templateContextFactory + * The template context factory * @param template * The template to render */ - public TemplatePart(Template template) { + public TemplatePart(TemplateContextFactory templateContextFactory, Template template) { + this.templateContextFactory = templateContextFactory; this.template = template; } @@ -56,7 +65,7 @@ public class TemplatePart implements Part { * @return This template part (for method chaining) */ public TemplatePart set(String key, Object value) { - template.set(key, value); + template.getInitialContext().set(key, value); return this; } @@ -69,7 +78,15 @@ public class TemplatePart implements Part { */ @Override public void render(Writer writer) throws IOException { - template.render(writer); + template.render(templateContextFactory.createTemplateContext().mergeContext(template.getInitialContext()), writer); + } + + /** + * {@inheritDoc} + */ + @Override + public void render(TemplateContext templateContext, Writer writer) throws TemplateException { + template.render(templateContext.mergeContext(template.getInitialContext()), writer); } } diff --git a/src/main/java/net/pterodactylus/sone/web/AboutPage.java b/src/main/java/net/pterodactylus/sone/web/AboutPage.java index 4a0dd22..4c14457 100644 --- a/src/main/java/net/pterodactylus/sone/web/AboutPage.java +++ b/src/main/java/net/pterodactylus/sone/web/AboutPage.java @@ -17,8 +17,8 @@ package net.pterodactylus.sone.web; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; import net.pterodactylus.util.version.Version; /** @@ -54,9 +54,9 @@ public class AboutPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); - dataProvider.set("version", version); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); + templateContext.set("version", version); } } diff --git a/src/main/java/net/pterodactylus/sone/web/CreatePostPage.java b/src/main/java/net/pterodactylus/sone/web/CreatePostPage.java index ef88fd6..57eb18a 100644 --- a/src/main/java/net/pterodactylus/sone/web/CreatePostPage.java +++ b/src/main/java/net/pterodactylus/sone/web/CreatePostPage.java @@ -20,8 +20,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.data.Post; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.web.page.Page.Request.Method; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * This page lets the user create a new {@link Post}. @@ -50,8 +50,8 @@ public class CreatePostPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); if (request.getMethod() == Method.POST) { String text = request.getHttpRequest().getPartAsStringFailsafe("text", 65536).trim(); @@ -67,9 +67,9 @@ public class CreatePostPage extends SoneTemplatePage { webInterface.getCore().createPost(sender, recipient, System.currentTimeMillis(), text); throw new RedirectException(returnPage); } - dataProvider.set("errorTextEmpty", true); + templateContext.set("errorTextEmpty", true); } - dataProvider.set("returnPage", returnPage); + templateContext.set("returnPage", returnPage); } } diff --git a/src/main/java/net/pterodactylus/sone/web/CreateReplyPage.java b/src/main/java/net/pterodactylus/sone/web/CreateReplyPage.java index d3b7c35..aae5e83 100644 --- a/src/main/java/net/pterodactylus/sone/web/CreateReplyPage.java +++ b/src/main/java/net/pterodactylus/sone/web/CreateReplyPage.java @@ -20,8 +20,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.data.Post; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.web.page.Page.Request.Method; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * This page lets the user post a reply to a post. @@ -50,8 +50,8 @@ public class CreateReplyPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); String postId = request.getHttpRequest().getPartAsStringFailsafe("post", 36); String text = request.getHttpRequest().getPartAsStringFailsafe("text", 65536).trim(); String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); @@ -66,11 +66,11 @@ public class CreateReplyPage extends SoneTemplatePage { webInterface.getCore().createReply(sender, post, text); throw new RedirectException(returnPage); } - dataProvider.set("errorTextEmpty", true); + templateContext.set("errorTextEmpty", true); } - dataProvider.set("postId", postId); - dataProvider.set("text", text); - dataProvider.set("returnPage", returnPage); + templateContext.set("postId", postId); + templateContext.set("text", text); + templateContext.set("returnPage", returnPage); } } diff --git a/src/main/java/net/pterodactylus/sone/web/CreateSonePage.java b/src/main/java/net/pterodactylus/sone/web/CreateSonePage.java index 46302b0..719f4c6 100644 --- a/src/main/java/net/pterodactylus/sone/web/CreateSonePage.java +++ b/src/main/java/net/pterodactylus/sone/web/CreateSonePage.java @@ -30,8 +30,8 @@ import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.freenet.wot.OwnIdentity; import net.pterodactylus.sone.web.page.Page.Request.Method; import net.pterodactylus.util.logging.Logging; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; import freenet.clients.http.ToadletContext; /** @@ -94,10 +94,10 @@ public class CreateSonePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); List ownIdentitiesWithoutSone = getOwnIdentitiesWithoutSone(webInterface.getCore()); - dataProvider.set("identitiesWithoutSone", ownIdentitiesWithoutSone); + templateContext.set("identitiesWithoutSone", ownIdentitiesWithoutSone); if (request.getMethod() == Method.POST) { String id = request.getHttpRequest().getPartAsStringFailsafe("identity", 44); OwnIdentity selectedIdentity = null; @@ -108,7 +108,7 @@ public class CreateSonePage extends SoneTemplatePage { } } if (selectedIdentity == null) { - dataProvider.set("errorNoIdentity", true); + templateContext.set("errorNoIdentity", true); return; } /* create Sone. */ diff --git a/src/main/java/net/pterodactylus/sone/web/DeletePostPage.java b/src/main/java/net/pterodactylus/sone/web/DeletePostPage.java index 78c9f22..7a36d02 100644 --- a/src/main/java/net/pterodactylus/sone/web/DeletePostPage.java +++ b/src/main/java/net/pterodactylus/sone/web/DeletePostPage.java @@ -19,8 +19,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.data.Post; import net.pterodactylus.sone.web.page.Page.Request.Method; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * Lets the user delete a post they made. @@ -49,14 +49,14 @@ public class DeletePostPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); if (request.getMethod() == Method.GET) { String postId = request.getHttpRequest().getParam("post"); String returnPage = request.getHttpRequest().getParam("returnPage"); Post post = webInterface.getCore().getPost(postId); - dataProvider.set("post", post); - dataProvider.set("returnPage", returnPage); + templateContext.set("post", post); + templateContext.set("returnPage", returnPage); return; } else if (request.getMethod() == Method.POST) { String postId = request.getHttpRequest().getPartAsStringFailsafe("post", 36); @@ -71,8 +71,8 @@ public class DeletePostPage extends SoneTemplatePage { } else if (request.getHttpRequest().isPartSet("abortDelete")) { throw new RedirectException(returnPage); } - dataProvider.set("post", post); - dataProvider.set("returnPage", returnPage); + templateContext.set("post", post); + templateContext.set("returnPage", returnPage); } } diff --git a/src/main/java/net/pterodactylus/sone/web/DeleteProfileFieldPage.java b/src/main/java/net/pterodactylus/sone/web/DeleteProfileFieldPage.java index 9b52b04..82f2ace 100644 --- a/src/main/java/net/pterodactylus/sone/web/DeleteProfileFieldPage.java +++ b/src/main/java/net/pterodactylus/sone/web/DeleteProfileFieldPage.java @@ -21,8 +21,8 @@ import net.pterodactylus.sone.data.Profile; import net.pterodactylus.sone.data.Profile.Field; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.web.page.Page.Request.Method; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * Page that lets the user confirm the deletion of a profile field. @@ -51,8 +51,8 @@ public class DeleteProfileFieldPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); Sone currentSone = getCurrentSone(request.getToadletContext()); Profile profile = currentSone.getProfile(); @@ -78,7 +78,7 @@ public class DeleteProfileFieldPage extends SoneTemplatePage { } /* set current values in template. */ - dataProvider.set("field", field); + templateContext.set("field", field); } } diff --git a/src/main/java/net/pterodactylus/sone/web/DeleteReplyPage.java b/src/main/java/net/pterodactylus/sone/web/DeleteReplyPage.java index e10036b..782589f 100644 --- a/src/main/java/net/pterodactylus/sone/web/DeleteReplyPage.java +++ b/src/main/java/net/pterodactylus/sone/web/DeleteReplyPage.java @@ -19,8 +19,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.data.Reply; import net.pterodactylus.sone.web.page.Page.Request.Method; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * This page lets the user delete a reply. @@ -49,8 +49,8 @@ public class DeleteReplyPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); String replyId = request.getHttpRequest().getPartAsStringFailsafe("reply", 36); Reply reply = webInterface.getCore().getReply(replyId); String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); @@ -65,8 +65,8 @@ public class DeleteReplyPage extends SoneTemplatePage { throw new RedirectException(returnPage); } } - dataProvider.set("reply", reply); - dataProvider.set("returnPage", returnPage); + templateContext.set("reply", reply); + templateContext.set("returnPage", returnPage); } } diff --git a/src/main/java/net/pterodactylus/sone/web/DeleteSonePage.java b/src/main/java/net/pterodactylus/sone/web/DeleteSonePage.java index abe26ea..54d77b8 100644 --- a/src/main/java/net/pterodactylus/sone/web/DeleteSonePage.java +++ b/src/main/java/net/pterodactylus/sone/web/DeleteSonePage.java @@ -19,8 +19,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.web.page.Page.Request.Method; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * Lets the user delete a Sone. Of course the Sone is not really deleted from @@ -51,8 +51,8 @@ public class DeleteSonePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); if (request.getMethod() == Method.POST) { if (request.getHttpRequest().isPartSet("deleteSone")) { Sone currentSone = getCurrentSone(request.getToadletContext()); diff --git a/src/main/java/net/pterodactylus/sone/web/DismissNotificationPage.java b/src/main/java/net/pterodactylus/sone/web/DismissNotificationPage.java index 2d61a95..15c5675 100644 --- a/src/main/java/net/pterodactylus/sone/web/DismissNotificationPage.java +++ b/src/main/java/net/pterodactylus/sone/web/DismissNotificationPage.java @@ -18,8 +18,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.util.notify.Notification; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * Page that lets the user dismiss a notification. @@ -48,8 +48,8 @@ public class DismissNotificationPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); String notificationId = request.getHttpRequest().getPartAsStringFailsafe("notification", 36); Notification notification = webInterface.getNotifications().getNotification(notificationId); if ((notification != null) && notification.isDismissable()) { diff --git a/src/main/java/net/pterodactylus/sone/web/DistrustPage.java b/src/main/java/net/pterodactylus/sone/web/DistrustPage.java index 9cbbb55..c055545 100644 --- a/src/main/java/net/pterodactylus/sone/web/DistrustPage.java +++ b/src/main/java/net/pterodactylus/sone/web/DistrustPage.java @@ -20,8 +20,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.core.Core; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.web.page.Page.Request.Method; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * Page that lets the user distrust another Sone. This will assign a @@ -52,17 +52,17 @@ public class DistrustPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); if (request.getMethod() == Method.POST) { - String returnPath = request.getHttpRequest().getPartAsStringFailsafe("returnPath", 256); + String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); String identity = request.getHttpRequest().getPartAsStringFailsafe("sone", 44); Sone currentSone = getCurrentSone(request.getToadletContext()); Sone sone = webInterface.getCore().getSone(identity, false); if (sone != null) { webInterface.getCore().distrustSone(currentSone, sone); } - throw new RedirectException(returnPath); + throw new RedirectException(returnPage); } } diff --git a/src/main/java/net/pterodactylus/sone/web/EditProfileFieldPage.java b/src/main/java/net/pterodactylus/sone/web/EditProfileFieldPage.java index 1b64b08..219bdc5 100644 --- a/src/main/java/net/pterodactylus/sone/web/EditProfileFieldPage.java +++ b/src/main/java/net/pterodactylus/sone/web/EditProfileFieldPage.java @@ -21,8 +21,8 @@ import net.pterodactylus.sone.data.Profile; import net.pterodactylus.sone.data.Profile.Field; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.web.page.Page.Request.Method; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * Page that lets the user edit the name of a profile field. @@ -51,8 +51,8 @@ public class EditProfileFieldPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); Sone currentSone = getCurrentSone(request.getToadletContext()); Profile profile = currentSone.getProfile(); @@ -80,11 +80,11 @@ public class EditProfileFieldPage extends SoneTemplatePage { currentSone.setProfile(profile); throw new RedirectException("editProfile.html#profile-fields"); } - dataProvider.set("duplicateFieldName", true); + templateContext.set("duplicateFieldName", true); } /* store current values in template. */ - dataProvider.set("field", field); + templateContext.set("field", field); } } diff --git a/src/main/java/net/pterodactylus/sone/web/EditProfilePage.java b/src/main/java/net/pterodactylus/sone/web/EditProfilePage.java index 380e054..52468a3 100644 --- a/src/main/java/net/pterodactylus/sone/web/EditProfilePage.java +++ b/src/main/java/net/pterodactylus/sone/web/EditProfilePage.java @@ -24,8 +24,8 @@ import net.pterodactylus.sone.data.Profile.Field; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.web.page.Page.Request.Method; import net.pterodactylus.util.number.Numbers; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; import freenet.clients.http.ToadletContext; /** @@ -55,8 +55,8 @@ public class EditProfilePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); ToadletContext toadletContenxt = request.getToadletContext(); Sone currentSone = getCurrentSone(toadletContenxt); Profile profile = currentSone.getProfile(); @@ -95,8 +95,8 @@ public class EditProfilePage extends SoneTemplatePage { webInterface.getCore().saveSone(currentSone); throw new RedirectException("editProfile.html#profile-fields"); } catch (IllegalArgumentException iae1) { - dataProvider.set("fieldName", fieldName); - dataProvider.set("duplicateFieldName", true); + templateContext.set("fieldName", fieldName); + templateContext.set("duplicateFieldName", true); } } else { String id = getFieldId(request, "delete-field-"); @@ -129,13 +129,13 @@ public class EditProfilePage extends SoneTemplatePage { } } } - dataProvider.set("firstName", firstName); - dataProvider.set("middleName", middleName); - dataProvider.set("lastName", lastName); - dataProvider.set("birthDay", birthDay); - dataProvider.set("birthMonth", birthMonth); - dataProvider.set("birthYear", birthYear); - dataProvider.set("fields", fields); + templateContext.set("firstName", firstName); + templateContext.set("middleName", middleName); + templateContext.set("lastName", lastName); + templateContext.set("birthDay", birthDay); + templateContext.set("birthMonth", birthMonth); + templateContext.set("birthYear", birthYear); + templateContext.set("fields", fields); } // diff --git a/src/main/java/net/pterodactylus/sone/web/FollowSonePage.java b/src/main/java/net/pterodactylus/sone/web/FollowSonePage.java index 864480a..9cd1f2a 100644 --- a/src/main/java/net/pterodactylus/sone/web/FollowSonePage.java +++ b/src/main/java/net/pterodactylus/sone/web/FollowSonePage.java @@ -19,8 +19,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.web.page.Page.Request.Method; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * This page lets the user follow another Sone. @@ -47,8 +47,8 @@ public class FollowSonePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); if (request.getMethod() == Method.POST) { String soneId = request.getHttpRequest().getPartAsStringFailsafe("sone", 44); String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); diff --git a/src/main/java/net/pterodactylus/sone/web/IndexPage.java b/src/main/java/net/pterodactylus/sone/web/IndexPage.java index b0a27f7..2d85e02 100644 --- a/src/main/java/net/pterodactylus/sone/web/IndexPage.java +++ b/src/main/java/net/pterodactylus/sone/web/IndexPage.java @@ -26,8 +26,8 @@ import net.pterodactylus.sone.data.Reply; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.util.collection.Pagination; import net.pterodactylus.util.number.Numbers; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * The index page shows the main page of Sone. This page will contain the posts @@ -55,8 +55,8 @@ public class IndexPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); Sone currentSone = getCurrentSone(request.getToadletContext()); List allPosts = new ArrayList(); allPosts.addAll(currentSone.getPosts()); @@ -75,17 +75,17 @@ public class IndexPage extends SoneTemplatePage { } Collections.sort(allPosts, Post.TIME_COMPARATOR); Pagination pagination = new Pagination(allPosts, 25).setPage(Numbers.safeParseInteger(request.getHttpRequest().getParam("page"), 0)); - dataProvider.set("pagination", pagination); - dataProvider.set("posts", pagination.getItems()); + templateContext.set("pagination", pagination); + templateContext.set("posts", pagination.getItems()); } /** * {@inheritDoc} */ @Override - protected void postProcess(Request request, DataProvider dataProvider) { + protected void postProcess(Request request, TemplateContext templateContext) { @SuppressWarnings("unchecked") - List posts = (List) dataProvider.get("posts"); + List posts = (List) templateContext.get("posts"); for (Post post : posts) { webInterface.getCore().markPostKnown(post); for (Reply reply : webInterface.getCore().getReplies(post)) { diff --git a/src/main/java/net/pterodactylus/sone/web/KnownSonesPage.java b/src/main/java/net/pterodactylus/sone/web/KnownSonesPage.java index 774f410..b08b6e3 100644 --- a/src/main/java/net/pterodactylus/sone/web/KnownSonesPage.java +++ b/src/main/java/net/pterodactylus/sone/web/KnownSonesPage.java @@ -22,8 +22,10 @@ import java.util.Collections; import java.util.List; import net.pterodactylus.sone.data.Sone; -import net.pterodactylus.util.template.DataProvider; +import net.pterodactylus.util.collection.Pagination; +import net.pterodactylus.util.number.Numbers; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * This page shows all known Sones. @@ -52,11 +54,26 @@ public class KnownSonesPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); List knownSones = new ArrayList(webInterface.getCore().getSones()); Collections.sort(knownSones, Sone.NICE_NAME_COMPARATOR); - dataProvider.set("knownSones", knownSones); + Pagination sonePagination = new Pagination(knownSones, 25).setPage(Numbers.safeParseInteger(request.getHttpRequest().getParam("page"), 0)); + templateContext.set("pagination", sonePagination); + templateContext.set("knownSones", sonePagination.getItems()); + } + + /** + * {@inheritDoc} + */ + @Override + protected void postProcess(Request request, TemplateContext templateContext) { + super.postProcess(request, templateContext); + @SuppressWarnings("unchecked") + List sones = (List) templateContext.get("knownSones"); + for (Sone sone : sones) { + webInterface.getCore().markSoneKnown(sone); + } } } diff --git a/src/main/java/net/pterodactylus/sone/web/LikePage.java b/src/main/java/net/pterodactylus/sone/web/LikePage.java index c84ea57..73fdd3c 100644 --- a/src/main/java/net/pterodactylus/sone/web/LikePage.java +++ b/src/main/java/net/pterodactylus/sone/web/LikePage.java @@ -20,8 +20,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.data.Post; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.web.page.Page.Request.Method; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * Page that lets the user like a {@link Post}. @@ -50,8 +50,8 @@ public class LikePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); if (request.getMethod() == Method.POST) { String type=request.getHttpRequest().getPartAsStringFailsafe("type", 16); String id = request.getHttpRequest().getPartAsStringFailsafe(type, 36); diff --git a/src/main/java/net/pterodactylus/sone/web/LockSonePage.java b/src/main/java/net/pterodactylus/sone/web/LockSonePage.java index 7888659..d09de66 100644 --- a/src/main/java/net/pterodactylus/sone/web/LockSonePage.java +++ b/src/main/java/net/pterodactylus/sone/web/LockSonePage.java @@ -18,8 +18,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.data.Sone; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * This page lets the user lock a {@link Sone} to prevent it from being @@ -49,8 +49,8 @@ public class LockSonePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); String soneId = request.getHttpRequest().getPartAsStringFailsafe("sone", 44); Sone sone = webInterface.getCore().getLocalSone(soneId, false); if (sone != null) { diff --git a/src/main/java/net/pterodactylus/sone/web/LoginPage.java b/src/main/java/net/pterodactylus/sone/web/LoginPage.java index ff81562..10f1f9f 100644 --- a/src/main/java/net/pterodactylus/sone/web/LoginPage.java +++ b/src/main/java/net/pterodactylus/sone/web/LoginPage.java @@ -26,8 +26,8 @@ import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.freenet.wot.OwnIdentity; import net.pterodactylus.sone.web.page.Page.Request.Method; import net.pterodactylus.util.logging.Logging; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; import freenet.clients.http.ToadletContext; /** @@ -61,12 +61,12 @@ public class LoginPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); /* get all own identities. */ List localSones = new ArrayList(webInterface.getCore().getLocalSones()); Collections.sort(localSones, Sone.NICE_NAME_COMPARATOR); - dataProvider.set("sones", localSones); + templateContext.set("sones", localSones); if (request.getMethod() == Method.POST) { String soneId = request.getHttpRequest().getPartAsStringFailsafe("sone-id", 100); Sone selectedSone = webInterface.getCore().getLocalSone(soneId, false); @@ -76,7 +76,7 @@ public class LoginPage extends SoneTemplatePage { } } List ownIdentitiesWithoutSone = CreateSonePage.getOwnIdentitiesWithoutSone(webInterface.getCore()); - dataProvider.set("identitiesWithoutSone", ownIdentitiesWithoutSone); + templateContext.set("identitiesWithoutSone", ownIdentitiesWithoutSone); } /** diff --git a/src/main/java/net/pterodactylus/sone/web/LogoutPage.java b/src/main/java/net/pterodactylus/sone/web/LogoutPage.java index 0b6e6e7..50266bd 100644 --- a/src/main/java/net/pterodactylus/sone/web/LogoutPage.java +++ b/src/main/java/net/pterodactylus/sone/web/LogoutPage.java @@ -17,8 +17,8 @@ package net.pterodactylus.sone.web; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; import freenet.clients.http.ToadletContext; /** @@ -46,9 +46,9 @@ public class LogoutPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { setCurrentSone(request.getToadletContext(), null); - super.processTemplate(request, dataProvider); + super.processTemplate(request, templateContext); throw new RedirectException("index.html"); } diff --git a/src/main/java/net/pterodactylus/sone/web/MarkAsKnownPage.java b/src/main/java/net/pterodactylus/sone/web/MarkAsKnownPage.java new file mode 100644 index 0000000..4ecf6e0 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/web/MarkAsKnownPage.java @@ -0,0 +1,89 @@ +/* + * Sone - MarkReadPage.java - Copyright © 2011 David Roden + * + * 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 . + */ + +package net.pterodactylus.sone.web; + +import java.util.StringTokenizer; + +import net.pterodactylus.sone.data.Post; +import net.pterodactylus.sone.data.Reply; +import net.pterodactylus.sone.data.Sone; +import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; + +/** + * Page that lets the user mark a number of {@link Sone}s, {@link Post}s, or + * {@link Reply Replie}s as known. + * + * @author David ‘Bombe’ Roden + */ +public class MarkAsKnownPage extends SoneTemplatePage { + + /** + * Creates a new “mark as known” page. + * + * @param template + * The template to render + * @param webInterface + * The Sone web interface + */ + public MarkAsKnownPage(Template template, WebInterface webInterface) { + super("markAsKnown.html", template, "Page.MarkAsKnown.Title", webInterface); + } + + // + // SONETEMPLATEPAGE METHODS + // + + /** + * {@inheritDoc} + */ + @Override + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); + String type = request.getHttpRequest().getPartAsStringFailsafe("type", 5); + if (!type.equals("sone") && !type.equals("post") && !type.equals("reply")) { + throw new RedirectException("invalid.html"); + } + String ids = request.getHttpRequest().getPartAsStringFailsafe("id", 65536); + for (StringTokenizer idTokenizer = new StringTokenizer(ids); idTokenizer.hasMoreTokens();) { + String id = idTokenizer.nextToken(); + if (type.equals("post")) { + Post post = webInterface.getCore().getPost(id, false); + if (post == null) { + continue; + } + webInterface.getCore().markPostKnown(post); + } else if (type.equals("reply")) { + Reply reply = webInterface.getCore().getReply(id, false); + if (reply == null) { + continue; + } + webInterface.getCore().markReplyKnown(reply); + } else if (type.equals("sone")) { + Sone sone = webInterface.getCore().getSone(id, false); + if (sone == null) { + continue; + } + webInterface.getCore().markSoneKnown(sone); + } + } + String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); + throw new RedirectException(returnPage); + } + +} diff --git a/src/main/java/net/pterodactylus/sone/web/OptionsPage.java b/src/main/java/net/pterodactylus/sone/web/OptionsPage.java index 0739ae7..421b2a2 100644 --- a/src/main/java/net/pterodactylus/sone/web/OptionsPage.java +++ b/src/main/java/net/pterodactylus/sone/web/OptionsPage.java @@ -20,8 +20,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.core.Options; import net.pterodactylus.sone.web.page.Page.Request.Method; import net.pterodactylus.util.number.Numbers; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * This page lets the user edit the options of the Sone plugin. @@ -50,8 +50,8 @@ public class OptionsPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); Options options = webInterface.getCore().getOptions(); if (request.getMethod() == Method.POST) { Integer insertionDelay = Numbers.safeParseInteger(request.getHttpRequest().getPartAsStringFailsafe("insertion-delay", 16)); @@ -74,13 +74,13 @@ public class OptionsPage extends SoneTemplatePage { webInterface.getCore().saveConfiguration(); throw new RedirectException(getPath()); } - dataProvider.set("insertion-delay", options.getIntegerOption("InsertionDelay").get()); - dataProvider.set("positive-trust", options.getIntegerOption("PositiveTrust").get()); - dataProvider.set("negative-trust", options.getIntegerOption("NegativeTrust").get()); - dataProvider.set("trust-comment", options.getStringOption("TrustComment").get()); - dataProvider.set("sone-rescue-mode", options.getBooleanOption("SoneRescueMode").get()); - dataProvider.set("clear-on-next-restart", options.getBooleanOption("ClearOnNextRestart").get()); - dataProvider.set("really-clear-on-next-restart", options.getBooleanOption("ReallyClearOnNextRestart").get()); + templateContext.set("insertion-delay", options.getIntegerOption("InsertionDelay").get()); + templateContext.set("positive-trust", options.getIntegerOption("PositiveTrust").get()); + templateContext.set("negative-trust", options.getIntegerOption("NegativeTrust").get()); + templateContext.set("trust-comment", options.getStringOption("TrustComment").get()); + templateContext.set("sone-rescue-mode", options.getBooleanOption("SoneRescueMode").get()); + templateContext.set("clear-on-next-restart", options.getBooleanOption("ClearOnNextRestart").get()); + templateContext.set("really-clear-on-next-restart", options.getBooleanOption("ReallyClearOnNextRestart").get()); } } diff --git a/src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java b/src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java index 9619531..fa43945 100644 --- a/src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java +++ b/src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java @@ -24,8 +24,8 @@ import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.main.SonePlugin; import net.pterodactylus.sone.web.page.Page; import net.pterodactylus.sone.web.page.TemplatePage; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; import freenet.clients.http.SessionManager.Session; import freenet.clients.http.ToadletContext; @@ -74,10 +74,10 @@ public class SoneTemplatePage extends TemplatePage { * Whether this page requires a login */ public SoneTemplatePage(String path, Template template, String pageTitleKey, WebInterface webInterface, boolean requireLogin) { - super(path, template, webInterface.getL10n(), pageTitleKey, "noPermission.html"); + super(path, webInterface.getTemplateContextFactory(), template, webInterface.getL10n(), pageTitleKey, "noPermission.html"); this.webInterface = webInterface; this.requireLogin = requireLogin; - template.set("webInterface", webInterface); + template.getInitialContext().set("webInterface", webInterface); } // @@ -186,15 +186,15 @@ public class SoneTemplatePage extends TemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); - dataProvider.set("currentSone", getCurrentSone(request.getToadletContext(), false)); - dataProvider.set("localSones", webInterface.getCore().getLocalSones()); - dataProvider.set("request", request); - dataProvider.set("currentVersion", SonePlugin.VERSION); - dataProvider.set("hasLatestVersion", webInterface.getCore().getUpdateChecker().hasLatestVersion()); - dataProvider.set("latestVersion", webInterface.getCore().getUpdateChecker().getLatestVersion()); - dataProvider.set("latestVersionTime", webInterface.getCore().getUpdateChecker().getLatestVersionDate()); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); + templateContext.set("currentSone", getCurrentSone(request.getToadletContext(), false)); + templateContext.set("localSones", webInterface.getCore().getLocalSones()); + templateContext.set("request", request); + templateContext.set("currentVersion", SonePlugin.VERSION); + templateContext.set("hasLatestVersion", webInterface.getCore().getUpdateChecker().hasLatestVersion()); + templateContext.set("latestVersion", webInterface.getCore().getUpdateChecker().getLatestVersion()); + templateContext.set("latestVersionTime", webInterface.getCore().getUpdateChecker().getLatestVersionDate()); } /** diff --git a/src/main/java/net/pterodactylus/sone/web/TrustPage.java b/src/main/java/net/pterodactylus/sone/web/TrustPage.java index 85341ad..b0dadef 100644 --- a/src/main/java/net/pterodactylus/sone/web/TrustPage.java +++ b/src/main/java/net/pterodactylus/sone/web/TrustPage.java @@ -20,8 +20,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.core.Core; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.web.page.Page.Request.Method; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * Page that lets the user trust another Sone. This will assign a configurable @@ -52,17 +52,17 @@ public class TrustPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); if (request.getMethod() == Method.POST) { - String returnPath = request.getHttpRequest().getPartAsStringFailsafe("returnPath", 256); + String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); String identity = request.getHttpRequest().getPartAsStringFailsafe("sone", 44); Sone currentSone = getCurrentSone(request.getToadletContext()); Sone sone = webInterface.getCore().getSone(identity, false); if (sone != null) { webInterface.getCore().trustSone(currentSone, sone); } - throw new RedirectException(returnPath); + throw new RedirectException(returnPage); } } diff --git a/src/main/java/net/pterodactylus/sone/web/UnfollowSonePage.java b/src/main/java/net/pterodactylus/sone/web/UnfollowSonePage.java index 316e408..e026a9a 100644 --- a/src/main/java/net/pterodactylus/sone/web/UnfollowSonePage.java +++ b/src/main/java/net/pterodactylus/sone/web/UnfollowSonePage.java @@ -19,8 +19,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.web.page.Page.Request.Method; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * This page lets the user unfollow another Sone. @@ -47,8 +47,8 @@ public class UnfollowSonePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); if (request.getMethod() == Method.POST) { String soneId = request.getHttpRequest().getPartAsStringFailsafe("sone", 44); String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); diff --git a/src/main/java/net/pterodactylus/sone/web/UnlikePage.java b/src/main/java/net/pterodactylus/sone/web/UnlikePage.java index d08689f..24ff3ca 100644 --- a/src/main/java/net/pterodactylus/sone/web/UnlikePage.java +++ b/src/main/java/net/pterodactylus/sone/web/UnlikePage.java @@ -20,8 +20,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.data.Post; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.web.page.Page.Request.Method; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * Page that lets the user unlike a {@link Post}. @@ -50,8 +50,8 @@ public class UnlikePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); if (request.getMethod() == Method.POST) { String type = request.getHttpRequest().getPartAsStringFailsafe("type", 16); String id = request.getHttpRequest().getPartAsStringFailsafe(type, 36); diff --git a/src/main/java/net/pterodactylus/sone/web/UnlockSonePage.java b/src/main/java/net/pterodactylus/sone/web/UnlockSonePage.java index 35d69ff..5408f20 100644 --- a/src/main/java/net/pterodactylus/sone/web/UnlockSonePage.java +++ b/src/main/java/net/pterodactylus/sone/web/UnlockSonePage.java @@ -18,8 +18,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.data.Sone; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * This page lets the user unlock a {@link Sone} to allow its insertion. @@ -48,8 +48,8 @@ public class UnlockSonePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); String soneId = request.getHttpRequest().getPartAsStringFailsafe("sone", 44); Sone sone = webInterface.getCore().getLocalSone(soneId, false); if (sone != null) { diff --git a/src/main/java/net/pterodactylus/sone/web/UntrustPage.java b/src/main/java/net/pterodactylus/sone/web/UntrustPage.java index cc9e26d..0e7e198 100644 --- a/src/main/java/net/pterodactylus/sone/web/UntrustPage.java +++ b/src/main/java/net/pterodactylus/sone/web/UntrustPage.java @@ -20,8 +20,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.core.Core; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.web.page.Page.Request.Method; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * Page that lets the user untrust another Sone. This will remove all trust @@ -52,17 +52,17 @@ public class UntrustPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); if (request.getMethod() == Method.POST) { - String returnPath = request.getHttpRequest().getPartAsStringFailsafe("returnPath", 256); + String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); String identity = request.getHttpRequest().getPartAsStringFailsafe("sone", 44); Sone currentSone = getCurrentSone(request.getToadletContext()); Sone sone = webInterface.getCore().getSone(identity, false); if (sone != null) { webInterface.getCore().untrustSone(currentSone, sone); } - throw new RedirectException(returnPath); + throw new RedirectException(returnPage); } } diff --git a/src/main/java/net/pterodactylus/sone/web/ViewPostPage.java b/src/main/java/net/pterodactylus/sone/web/ViewPostPage.java index 3c4eddf..cdbc6da 100644 --- a/src/main/java/net/pterodactylus/sone/web/ViewPostPage.java +++ b/src/main/java/net/pterodactylus/sone/web/ViewPostPage.java @@ -19,8 +19,8 @@ package net.pterodactylus.sone.web; import net.pterodactylus.sone.data.Post; import net.pterodactylus.sone.data.Reply; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * This page lets the user view a post and all its replies. @@ -49,19 +49,19 @@ public class ViewPostPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); String postId = request.getHttpRequest().getParam("post"); Post post = webInterface.getCore().getPost(postId); - dataProvider.set("post", post); + templateContext.set("post", post); } /** * {@inheritDoc} */ @Override - protected void postProcess(Request request, DataProvider dataProvider) { - Post post = (Post) dataProvider.get("post"); + protected void postProcess(Request request, TemplateContext templateContext) { + Post post = (Post) templateContext.get("post"); webInterface.getCore().markPostKnown(post); for (Reply reply : webInterface.getCore().getReplies(post)) { webInterface.getCore().markReplyKnown(reply); diff --git a/src/main/java/net/pterodactylus/sone/web/ViewSonePage.java b/src/main/java/net/pterodactylus/sone/web/ViewSonePage.java index 9746afd..0792a6f 100644 --- a/src/main/java/net/pterodactylus/sone/web/ViewSonePage.java +++ b/src/main/java/net/pterodactylus/sone/web/ViewSonePage.java @@ -22,8 +22,8 @@ import java.util.List; import net.pterodactylus.sone.data.Post; import net.pterodactylus.sone.data.Reply; import net.pterodactylus.sone.data.Sone; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; /** * Lets the user browser another Sone. @@ -52,22 +52,23 @@ public class ViewSonePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { - super.processTemplate(request, dataProvider); + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { + super.processTemplate(request, templateContext); String soneId = request.getHttpRequest().getParam("sone"); Sone sone = webInterface.getCore().getSone(soneId, false); - dataProvider.set("sone", sone); + templateContext.set("sone", sone); } /** * {@inheritDoc} */ @Override - protected void postProcess(Request request, DataProvider dataProvider) { - Sone sone = (Sone) dataProvider.get("sone"); + protected void postProcess(Request request, TemplateContext templateContext) { + Sone sone = (Sone) templateContext.get("sone"); if (sone == null) { return; } + webInterface.getCore().markSoneKnown(sone); List posts = sone.getPosts(); for (Post post : posts) { webInterface.getCore().markPostKnown(post); diff --git a/src/main/java/net/pterodactylus/sone/web/WebInterface.java b/src/main/java/net/pterodactylus/sone/web/WebInterface.java index d08cc17..14c2c09 100644 --- a/src/main/java/net/pterodactylus/sone/web/WebInterface.java +++ b/src/main/java/net/pterodactylus/sone/web/WebInterface.java @@ -74,8 +74,7 @@ import net.pterodactylus.sone.web.ajax.GetStatusAjaxPage; import net.pterodactylus.sone.web.ajax.GetTranslationPage; import net.pterodactylus.sone.web.ajax.LikeAjaxPage; import net.pterodactylus.sone.web.ajax.LockSoneAjaxPage; -import net.pterodactylus.sone.web.ajax.MarkPostAsKnownPage; -import net.pterodactylus.sone.web.ajax.MarkReplyAsKnownPage; +import net.pterodactylus.sone.web.ajax.MarkAsKnownAjaxPage; import net.pterodactylus.sone.web.ajax.MoveProfileFieldAjaxPage; import net.pterodactylus.sone.web.ajax.TrustAjaxPage; import net.pterodactylus.sone.web.ajax.UnfollowSoneAjaxPage; @@ -90,14 +89,18 @@ import net.pterodactylus.util.notify.Notification; import net.pterodactylus.util.notify.NotificationManager; import net.pterodactylus.util.notify.TemplateNotification; import net.pterodactylus.util.template.DateFilter; -import net.pterodactylus.util.template.DefaultTemplateFactory; +import net.pterodactylus.util.template.HtmlFilter; import net.pterodactylus.util.template.MatchFilter; import net.pterodactylus.util.template.PaginationPlugin; +import net.pterodactylus.util.template.Provider; import net.pterodactylus.util.template.ReflectionAccessor; +import net.pterodactylus.util.template.ReplaceFilter; +import net.pterodactylus.util.template.StoreFilter; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; +import net.pterodactylus.util.template.TemplateContextFactory; import net.pterodactylus.util.template.TemplateException; -import net.pterodactylus.util.template.TemplateFactory; -import net.pterodactylus.util.template.TemplateProvider; +import net.pterodactylus.util.template.TemplateParser; import net.pterodactylus.util.template.XmlFilter; import net.pterodactylus.util.thread.Ticker; import net.pterodactylus.util.version.Version; @@ -130,8 +133,8 @@ public class WebInterface implements CoreListener { /** The form password. */ private final String formPassword; - /** The template factory. */ - private DefaultTemplateFactory templateFactory; + /** The template context factory. */ + private final TemplateContextFactory templateContextFactory; /** The “new Sone” notification. */ private final ListNotification newSoneNotification; @@ -163,54 +166,59 @@ public class WebInterface implements CoreListener { * @param sonePlugin * The Sone plugin */ + @SuppressWarnings("synthetic-access") public WebInterface(SonePlugin sonePlugin) { this.sonePlugin = sonePlugin; formPassword = sonePlugin.pluginRespirator().getToadletContainer().getFormPassword(); - templateFactory = new DefaultTemplateFactory(); - templateFactory.addAccessor(Object.class, new ReflectionAccessor()); - templateFactory.addAccessor(Collection.class, new CollectionAccessor()); - templateFactory.addAccessor(Sone.class, new SoneAccessor(getCore())); - templateFactory.addAccessor(Post.class, new PostAccessor(getCore())); - templateFactory.addAccessor(Reply.class, new ReplyAccessor(getCore())); - templateFactory.addAccessor(Identity.class, new IdentityAccessor(getCore())); - templateFactory.addAccessor(NotificationManager.class, new NotificationManagerAccessor()); - templateFactory.addAccessor(Trust.class, new TrustAccessor()); - templateFactory.addFilter("date", new DateFilter()); - templateFactory.addFilter("l10n", new L10nFilter(getL10n())); - templateFactory.addFilter("substring", new SubstringFilter()); - templateFactory.addFilter("xml", new XmlFilter()); - templateFactory.addFilter("change", new RequestChangeFilter()); - templateFactory.addFilter("match", new MatchFilter()); - templateFactory.addFilter("css", new CssClassNameFilter()); - templateFactory.addFilter("js", new JavascriptFilter()); - templateFactory.addFilter("parse", new ParserFilter(templateFactory)); - templateFactory.addFilter("unknown", new UnknownDateFilter(getL10n(), "View.Sone.Text.UnknownDate")); - templateFactory.addPlugin("getpage", new GetPagePlugin()); - templateFactory.addPlugin("paginate", new PaginationPlugin()); - templateFactory.setTemplateProvider(new ClassPathTemplateProvider(templateFactory)); - templateFactory.addTemplateObject("formPassword", formPassword); + templateContextFactory = new TemplateContextFactory(); + templateContextFactory.addAccessor(Object.class, new ReflectionAccessor()); + templateContextFactory.addAccessor(Collection.class, new CollectionAccessor()); + templateContextFactory.addAccessor(Sone.class, new SoneAccessor(getCore())); + templateContextFactory.addAccessor(Post.class, new PostAccessor(getCore())); + templateContextFactory.addAccessor(Reply.class, new ReplyAccessor(getCore())); + templateContextFactory.addAccessor(Identity.class, new IdentityAccessor(getCore())); + templateContextFactory.addAccessor(NotificationManager.class, new NotificationManagerAccessor()); + templateContextFactory.addAccessor(Trust.class, new TrustAccessor()); + templateContextFactory.addFilter("date", new DateFilter()); + templateContextFactory.addFilter("html", new HtmlFilter()); + templateContextFactory.addFilter("replace", new ReplaceFilter()); + templateContextFactory.addFilter("store", new StoreFilter()); + templateContextFactory.addFilter("l10n", new L10nFilter(getL10n())); + templateContextFactory.addFilter("substring", new SubstringFilter()); + templateContextFactory.addFilter("xml", new XmlFilter()); + templateContextFactory.addFilter("change", new RequestChangeFilter()); + templateContextFactory.addFilter("match", new MatchFilter()); + templateContextFactory.addFilter("css", new CssClassNameFilter()); + templateContextFactory.addFilter("js", new JavascriptFilter()); + templateContextFactory.addFilter("parse", new ParserFilter(templateContextFactory)); + templateContextFactory.addFilter("unknown", new UnknownDateFilter(getL10n(), "View.Sone.Text.UnknownDate")); + templateContextFactory.addPlugin("getpage", new GetPagePlugin()); + templateContextFactory.addPlugin("paginate", new PaginationPlugin()); + templateContextFactory.addProvider(Provider.TEMPLATE_CONTEXT_PROVIDER); + templateContextFactory.addProvider(new ClassPathTemplateProvider()); + templateContextFactory.addTemplateObject("formPassword", formPassword); /* create notifications. */ - Template newSoneNotificationTemplate = templateFactory.createTemplate(createReader("/templates/notify/newSoneNotification.html")); + Template newSoneNotificationTemplate = TemplateParser.parse(createReader("/templates/notify/newSoneNotification.html")); newSoneNotification = new ListNotification("new-sone-notification", "sones", newSoneNotificationTemplate); - Template newPostNotificationTemplate = templateFactory.createTemplate(createReader("/templates/notify/newPostNotification.html")); + Template newPostNotificationTemplate = TemplateParser.parse(createReader("/templates/notify/newPostNotification.html")); newPostNotification = new ListNotification("new-post-notification", "posts", newPostNotificationTemplate); - Template newReplyNotificationTemplate = templateFactory.createTemplate(createReader("/templates/notify/newReplyNotification.html")); + Template newReplyNotificationTemplate = TemplateParser.parse(createReader("/templates/notify/newReplyNotification.html")); newReplyNotification = new ListNotification("new-replies-notification", "replies", newReplyNotificationTemplate); - Template rescuingSonesTemplate = templateFactory.createTemplate(createReader("/templates/notify/rescuingSonesNotification.html")); + Template rescuingSonesTemplate = TemplateParser.parse(createReader("/templates/notify/rescuingSonesNotification.html")); rescuingSonesNotification = new ListNotification("sones-being-rescued-notification", "sones", rescuingSonesTemplate); - Template sonesRescuedTemplate = templateFactory.createTemplate(createReader("/templates/notify/sonesRescuedNotification.html")); + Template sonesRescuedTemplate = TemplateParser.parse(createReader("/templates/notify/sonesRescuedNotification.html")); sonesRescuedNotification = new ListNotification("sones-rescued-notification", "sones", sonesRescuedTemplate); - Template lockedSonesTemplate = templateFactory.createTemplate(createReader("/templates/notify/lockedSonesNotification.html")); + Template lockedSonesTemplate = TemplateParser.parse(createReader("/templates/notify/lockedSonesNotification.html")); lockedSonesNotification = new ListNotification("sones-locked-notification", "sones", lockedSonesTemplate); - Template newVersionTemplate = templateFactory.createTemplate(createReader("/templates/notify/newVersionNotification.html")); + Template newVersionTemplate = TemplateParser.parse(createReader("/templates/notify/newVersionNotification.html")); newVersionNotification = new TemplateNotification("new-version-notification", newVersionTemplate); } @@ -228,6 +236,15 @@ public class WebInterface implements CoreListener { } /** + * Returns the template context factory of the web interface. + * + * @return The template context factory + */ + public TemplateContextFactory getTemplateContextFactory() { + return templateContextFactory; + } + + /** * Returns the current session, creating a new session if there is no * current session. * @@ -389,7 +406,7 @@ public class WebInterface implements CoreListener { */ public void setFirstStart(boolean firstStart) { if (firstStart) { - Template firstStartNotificationTemplate = templateFactory.createTemplate(createReader("/templates/notify/firstStartNotification.html")); + Template firstStartNotificationTemplate = TemplateParser.parse(createReader("/templates/notify/firstStartNotification.html")); Notification firstStartNotification = new TemplateNotification("first-start-notification", firstStartNotificationTemplate); notificationManager.addNotification(firstStartNotification); } @@ -404,7 +421,7 @@ public class WebInterface implements CoreListener { */ public void setNewConfig(boolean newConfig) { if (newConfig && !hasFirstStartNotification()) { - Template configNotReadNotificationTemplate = templateFactory.createTemplate(createReader("/templates/notify/configNotReadNotification.html")); + Template configNotReadNotificationTemplate = TemplateParser.parse(createReader("/templates/notify/configNotReadNotification.html")); Notification configNotReadNotification = new TemplateNotification("config-not-read-notification", configNotReadNotificationTemplate); notificationManager.addNotification(configNotReadNotification); } @@ -435,7 +452,7 @@ public class WebInterface implements CoreListener { registerToadlets(); /* notification templates. */ - Template startupNotificationTemplate = templateFactory.createTemplate(createReader("/templates/notify/startupNotification.html")); + Template startupNotificationTemplate = TemplateParser.parse(createReader("/templates/notify/startupNotification.html")); final TemplateNotification startupNotification = new TemplateNotification("startup-notification", startupNotificationTemplate); notificationManager.addNotification(startupNotification); @@ -448,7 +465,7 @@ public class WebInterface implements CoreListener { } }, "Sone Startup Notification Remover"); - Template wotMissingNotificationTemplate = templateFactory.createTemplate(createReader("/templates/notify/wotMissingNotification.html")); + Template wotMissingNotificationTemplate = TemplateParser.parse(createReader("/templates/notify/wotMissingNotification.html")); final TemplateNotification wotMissingNotification = new TemplateNotification("wot-missing-notification", wotMissingNotificationTemplate); Ticker.getInstance().registerEvent(System.currentTimeMillis() + (15 * 1000), new Runnable() { @@ -482,27 +499,27 @@ public class WebInterface implements CoreListener { * Register all toadlets. */ private void registerToadlets() { - Template emptyTemplate = templateFactory.createTemplate(new StringReader("")); - Template loginTemplate = templateFactory.createTemplate(createReader("/templates/login.html")); - Template indexTemplate = templateFactory.createTemplate(createReader("/templates/index.html")); - Template knownSonesTemplate = templateFactory.createTemplate(createReader("/templates/knownSones.html")); - Template createSoneTemplate = templateFactory.createTemplate(createReader("/templates/createSone.html")); - Template createPostTemplate = templateFactory.createTemplate(createReader("/templates/createPost.html")); - Template createReplyTemplate = templateFactory.createTemplate(createReader("/templates/createReply.html")); - Template editProfileTemplate = templateFactory.createTemplate(createReader("/templates/editProfile.html")); - Template editProfileFieldTemplate = templateFactory.createTemplate(createReader("/templates/editProfileField.html")); - Template deleteProfileFieldTemplate = templateFactory.createTemplate(createReader("/templates/deleteProfileField.html")); - Template viewSoneTemplate = templateFactory.createTemplate(createReader("/templates/viewSone.html")); - Template viewPostTemplate = templateFactory.createTemplate(createReader("/templates/viewPost.html")); - Template deletePostTemplate = templateFactory.createTemplate(createReader("/templates/deletePost.html")); - Template deleteReplyTemplate = templateFactory.createTemplate(createReader("/templates/deleteReply.html")); - Template deleteSoneTemplate = templateFactory.createTemplate(createReader("/templates/deleteSone.html")); - Template noPermissionTemplate = templateFactory.createTemplate(createReader("/templates/noPermission.html")); - Template optionsTemplate = templateFactory.createTemplate(createReader("/templates/options.html")); - Template aboutTemplate = templateFactory.createTemplate(createReader("/templates/about.html")); - Template invalidTemplate = templateFactory.createTemplate(createReader("/templates/invalid.html")); - Template postTemplate = templateFactory.createTemplate(createReader("/templates/include/viewPost.html")); - Template replyTemplate = templateFactory.createTemplate(createReader("/templates/include/viewReply.html")); + Template emptyTemplate = TemplateParser.parse(new StringReader("")); + Template loginTemplate = TemplateParser.parse(createReader("/templates/login.html")); + Template indexTemplate = TemplateParser.parse(createReader("/templates/index.html")); + Template knownSonesTemplate = TemplateParser.parse(createReader("/templates/knownSones.html")); + Template createSoneTemplate = TemplateParser.parse(createReader("/templates/createSone.html")); + Template createPostTemplate = TemplateParser.parse(createReader("/templates/createPost.html")); + Template createReplyTemplate = TemplateParser.parse(createReader("/templates/createReply.html")); + Template editProfileTemplate = TemplateParser.parse(createReader("/templates/editProfile.html")); + Template editProfileFieldTemplate = TemplateParser.parse(createReader("/templates/editProfileField.html")); + Template deleteProfileFieldTemplate = TemplateParser.parse(createReader("/templates/deleteProfileField.html")); + Template viewSoneTemplate = TemplateParser.parse(createReader("/templates/viewSone.html")); + Template viewPostTemplate = TemplateParser.parse(createReader("/templates/viewPost.html")); + Template deletePostTemplate = TemplateParser.parse(createReader("/templates/deletePost.html")); + Template deleteReplyTemplate = TemplateParser.parse(createReader("/templates/deleteReply.html")); + Template deleteSoneTemplate = TemplateParser.parse(createReader("/templates/deleteSone.html")); + Template noPermissionTemplate = TemplateParser.parse(createReader("/templates/noPermission.html")); + Template optionsTemplate = TemplateParser.parse(createReader("/templates/options.html")); + Template aboutTemplate = TemplateParser.parse(createReader("/templates/about.html")); + Template invalidTemplate = TemplateParser.parse(createReader("/templates/invalid.html")); + Template postTemplate = TemplateParser.parse(createReader("/templates/include/viewPost.html")); + Template replyTemplate = TemplateParser.parse(createReader("/templates/include/viewReply.html")); PageToadletFactory pageToadletFactory = new PageToadletFactory(sonePlugin.pluginRespirator().getHLSimpleClient(), "/Sone/"); pageToadlets.add(pageToadletFactory.createPageToadlet(new IndexPage(indexTemplate, this), "Index")); @@ -526,6 +543,7 @@ public class WebInterface implements CoreListener { pageToadlets.add(pageToadletFactory.createPageToadlet(new TrustPage(emptyTemplate, this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new DistrustPage(emptyTemplate, this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new UntrustPage(emptyTemplate, this))); + pageToadlets.add(pageToadletFactory.createPageToadlet(new MarkAsKnownPage(emptyTemplate, this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new DeleteSonePage(deleteSoneTemplate, this), "DeleteSone")); pageToadlets.add(pageToadletFactory.createPageToadlet(new LoginPage(loginTemplate, this), "Login")); pageToadlets.add(pageToadletFactory.createPageToadlet(new LogoutPage(emptyTemplate, this), "Logout")); @@ -544,8 +562,7 @@ public class WebInterface implements CoreListener { pageToadlets.add(pageToadletFactory.createPageToadlet(new CreateReplyAjaxPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new GetReplyAjaxPage(this, replyTemplate))); pageToadlets.add(pageToadletFactory.createPageToadlet(new GetPostAjaxPage(this, postTemplate))); - pageToadlets.add(pageToadletFactory.createPageToadlet(new MarkPostAsKnownPage(this))); - pageToadlets.add(pageToadletFactory.createPageToadlet(new MarkReplyAsKnownPage(this))); + pageToadlets.add(pageToadletFactory.createPageToadlet(new MarkAsKnownAjaxPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new DeletePostAjaxPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new DeleteReplyAjaxPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new LockSoneAjaxPage(this))); @@ -597,6 +614,7 @@ public class WebInterface implements CoreListener { try { return new InputStreamReader(getClass().getResourceAsStream(resourceName), "UTF-8"); } catch (UnsupportedEncodingException uee1) { + System.out.println(" fail."); return null; } } @@ -736,8 +754,8 @@ public class WebInterface implements CoreListener { */ @Override public void updateFound(Version version, long releaseTime) { - newVersionNotification.set("version", version); - newVersionNotification.set("releaseTime", releaseTime); + newVersionNotification.getTemplateContext().set("version", version); + newVersionNotification.getTemplateContext().set("releaseTime", releaseTime); notificationManager.addNotification(newVersionNotification); } @@ -748,36 +766,21 @@ public class WebInterface implements CoreListener { * * @author David ‘Bombe’ Roden */ - private class ClassPathTemplateProvider implements TemplateProvider { - - /** The template factory. */ - @SuppressWarnings("hiding") - private final TemplateFactory templateFactory; - - /** - * Creates a new template provider that locates templates on the - * classpath. - * - * @param templateFactory - * The template factory to create the templates - */ - public ClassPathTemplateProvider(TemplateFactory templateFactory) { - this.templateFactory = templateFactory; - } + private class ClassPathTemplateProvider implements Provider { /** * {@inheritDoc} */ @Override @SuppressWarnings("synthetic-access") - public Template getTemplate(String templateName) { + public Template getTemplate(TemplateContext templateContext, String templateName) { Reader templateReader = createReader("/templates/" + templateName); if (templateReader == null) { return null; } - Template template = templateFactory.createTemplate(templateReader); + Template template = null; try { - template.parse(); + template = TemplateParser.parse(templateReader); } catch (TemplateException te1) { logger.log(Level.WARNING, "Could not parse template “" + templateName + "” for inclusion!", te1); } diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/GetPostAjaxPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/GetPostAjaxPage.java index a0aa6e2..127834b 100644 --- a/src/main/java/net/pterodactylus/sone/web/ajax/GetPostAjaxPage.java +++ b/src/main/java/net/pterodactylus/sone/web/ajax/GetPostAjaxPage.java @@ -24,8 +24,8 @@ import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.web.WebInterface; import net.pterodactylus.util.io.Closer; import net.pterodactylus.util.json.JsonObject; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; import net.pterodactylus.util.template.TemplateException; /** @@ -94,11 +94,11 @@ public class GetPostAjaxPage extends JsonPage { jsonPost.put("recipient", (post.getRecipient() == null) ? null : post.getRecipient().getId()); jsonPost.put("time", post.getTime()); StringWriter stringWriter = new StringWriter(); - DataProvider dataProvider = postTemplate.createDataProvider(); - dataProvider.set("post", post); - dataProvider.set("currentSone", currentSone); + TemplateContext templateContext = webInterface.getTemplateContextFactory().createTemplateContext(); + templateContext.set("post", post); + templateContext.set("currentSone", currentSone); try { - postTemplate.render(dataProvider, stringWriter); + postTemplate.render(templateContext, stringWriter); } catch (TemplateException te1) { /* TODO - shouldn’t happen. */ } finally { diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/GetReplyAjaxPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/GetReplyAjaxPage.java index 15e4ef5..c19bcba 100644 --- a/src/main/java/net/pterodactylus/sone/web/ajax/GetReplyAjaxPage.java +++ b/src/main/java/net/pterodactylus/sone/web/ajax/GetReplyAjaxPage.java @@ -24,8 +24,8 @@ import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.web.WebInterface; import net.pterodactylus.util.io.Closer; import net.pterodactylus.util.json.JsonObject; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; import net.pterodactylus.util.template.TemplateException; /** @@ -96,11 +96,11 @@ public class GetReplyAjaxPage extends JsonPage { jsonReply.put("soneId", reply.getSone().getId()); jsonReply.put("time", reply.getTime()); StringWriter stringWriter = new StringWriter(); - DataProvider dataProvider = replyTemplate.createDataProvider(); - dataProvider.set("reply", reply); - dataProvider.set("currentSone", currentSone); + TemplateContext templateContext = webInterface.getTemplateContextFactory().createTemplateContext(); + templateContext.set("reply", reply); + templateContext.set("currentSone", currentSone); try { - replyTemplate.render(dataProvider, stringWriter); + replyTemplate.render(templateContext, stringWriter); } catch (TemplateException te1) { /* TODO - shouldn’t happen. */ } finally { diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/GetStatusAjaxPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/GetStatusAjaxPage.java index 28da894..71cc156 100644 --- a/src/main/java/net/pterodactylus/sone/web/ajax/GetStatusAjaxPage.java +++ b/src/main/java/net/pterodactylus/sone/web/ajax/GetStatusAjaxPage.java @@ -17,6 +17,8 @@ package net.pterodactylus.sone.web.ajax; +import java.io.IOException; +import java.io.StringWriter; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -34,6 +36,7 @@ import net.pterodactylus.sone.web.WebInterface; import net.pterodactylus.util.json.JsonArray; import net.pterodactylus.util.json.JsonObject; import net.pterodactylus.util.notify.Notification; +import net.pterodactylus.util.notify.TemplateNotification; /** * The “get status” AJAX handler returns all information that is necessary to @@ -162,10 +165,20 @@ public class GetStatusAjaxPage extends JsonPage { * The notification to create a JSON object * @return The JSON object */ - private static JsonObject createJsonNotification(Notification notification) { + private JsonObject createJsonNotification(Notification notification) { JsonObject jsonNotification = new JsonObject(); jsonNotification.put("id", notification.getId()); - jsonNotification.put("text", notification.toString()); + StringWriter notificationWriter = new StringWriter(); + try { + if (notification instanceof TemplateNotification) { + ((TemplateNotification) notification).render(webInterface.getTemplateContextFactory().createTemplateContext().mergeContext(((TemplateNotification) notification).getTemplateContext()), notificationWriter); + } else { + notification.render(notificationWriter); + } + } catch (IOException ioe1) { + /* StringWriter never throws, ignore. */ + } + jsonNotification.put("text", notificationWriter.toString()); jsonNotification.put("createdTime", notification.getCreatedTime()); jsonNotification.put("lastUpdatedTime", notification.getLastUpdatedTime()); jsonNotification.put("dismissable", notification.isDismissable()); diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/MarkAsKnownAjaxPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/MarkAsKnownAjaxPage.java new file mode 100644 index 0000000..b641ea0 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/web/ajax/MarkAsKnownAjaxPage.java @@ -0,0 +1,88 @@ +/* + * Sone - MarkAsKnownAjaxPage.java - Copyright © 2011 David Roden + * + * 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 . + */ + +package net.pterodactylus.sone.web.ajax; + +import net.pterodactylus.sone.core.Core; +import net.pterodactylus.sone.data.Post; +import net.pterodactylus.sone.data.Reply; +import net.pterodactylus.sone.data.Sone; +import net.pterodactylus.sone.web.WebInterface; +import net.pterodactylus.util.json.JsonObject; + +/** + * AJAX page that lets the user mark a number of {@link Sone}s, {@link Post}s, + * or {@link Reply}s as known. + * + * @author David ‘Bombe’ Roden + */ +public class MarkAsKnownAjaxPage extends JsonPage { + + /** + * Creates a new “mark as known” AJAX page. + * + * @param webInterface + * The Sone web interface + */ + public MarkAsKnownAjaxPage(WebInterface webInterface) { + super("markAsKnown.ajax", webInterface); + } + + /** + * {@inheritDoc} + */ + @Override + protected JsonObject createJsonObject(Request request) { + String type = request.getHttpRequest().getParam("type"); + if (!type.equals("sone") && !type.equals("post") && !type.equals("reply")) { + return createErrorJsonObject("invalid-type"); + } + String[] ids = request.getHttpRequest().getParam("id").split(" "); + Core core = webInterface.getCore(); + for (String id : ids) { + if (type.equals("post")) { + Post post = core.getPost(id, false); + if (post == null) { + continue; + } + core.markPostKnown(post); + } else if (type.equals("reply")) { + Reply reply = core.getReply(id, false); + if (reply == null) { + continue; + } + core.markReplyKnown(reply); + } else if (type.equals("sone")) { + Sone sone = core.getSone(id, false); + if (sone == null) { + continue; + } + core.markSoneKnown(sone); + } + } + return createSuccessJsonObject(); + } + + /** + * {@inheritDoc} + */ + @Override + protected boolean requiresLogin() { + return false; + } + +} diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/MarkPostAsKnownPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/MarkPostAsKnownPage.java deleted file mode 100644 index c2b0ca3..0000000 --- a/src/main/java/net/pterodactylus/sone/web/ajax/MarkPostAsKnownPage.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Sone - MarkPostAsKnownPage.java - Copyright © 2010 David Roden - * - * 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 . - */ - -package net.pterodactylus.sone.web.ajax; - -import net.pterodactylus.sone.data.Post; -import net.pterodactylus.sone.web.WebInterface; -import net.pterodactylus.util.json.JsonObject; - -/** - * AJAX handler that marks a {@link Post} as known. - * - * @author David ‘Bombe’ Roden - */ -public class MarkPostAsKnownPage extends JsonPage { - - /** - * Creates a new “mark post as known” AJAX handler. - * - * @param webInterface - * The Sone web interface - */ - public MarkPostAsKnownPage(WebInterface webInterface) { - super("markPostAsKnown.ajax", webInterface); - } - - /** - * {@inheritDoc} - */ - @Override - protected JsonObject createJsonObject(Request request) { - String postId = request.getHttpRequest().getParam("post"); - Post post = webInterface.getCore().getPost(postId, false); - if (post == null) { - return createErrorJsonObject("invalid-post-id"); - } - webInterface.getCore().markPostKnown(post); - return createSuccessJsonObject(); - } - -} diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/MarkReplyAsKnownPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/MarkReplyAsKnownPage.java deleted file mode 100644 index 6a4f72b..0000000 --- a/src/main/java/net/pterodactylus/sone/web/ajax/MarkReplyAsKnownPage.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Sone - MarkPostAsKnownPage.java - Copyright © 2010 David Roden - * - * 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 . - */ - -package net.pterodactylus.sone.web.ajax; - -import net.pterodactylus.sone.data.Reply; -import net.pterodactylus.sone.web.WebInterface; -import net.pterodactylus.util.json.JsonObject; - -/** - * AJAX handler that marks a {@link Reply} as known. - * - * @author David ‘Bombe’ Roden - */ -public class MarkReplyAsKnownPage extends JsonPage { - - /** - * Creates a new “mark reply as known” AJAX handler. - * - * @param webInterface - * The Sone web interface - */ - public MarkReplyAsKnownPage(WebInterface webInterface) { - super("markReplyAsKnown.ajax", webInterface); - } - - /** - * {@inheritDoc} - */ - @Override - protected JsonObject createJsonObject(Request request) { - String replyId = request.getHttpRequest().getParam("reply"); - Reply reply = webInterface.getCore().getReply(replyId, false); - if (reply == null) { - return createErrorJsonObject("invalid-reply-id"); - } - webInterface.getCore().markReplyKnown(reply); - return createSuccessJsonObject(); - } - -} diff --git a/src/main/java/net/pterodactylus/sone/web/page/TemplatePage.java b/src/main/java/net/pterodactylus/sone/web/page/TemplatePage.java index e6ee539..08e026d 100644 --- a/src/main/java/net/pterodactylus/sone/web/page/TemplatePage.java +++ b/src/main/java/net/pterodactylus/sone/web/page/TemplatePage.java @@ -25,8 +25,9 @@ import java.util.logging.Logger; import net.pterodactylus.sone.web.page.Page.Request.Method; import net.pterodactylus.util.logging.Logging; -import net.pterodactylus.util.template.DataProvider; import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; +import net.pterodactylus.util.template.TemplateContextFactory; import freenet.clients.http.LinkEnabledCallback; import freenet.clients.http.PageMaker; import freenet.clients.http.PageNode; @@ -46,6 +47,9 @@ public class TemplatePage implements Page, LinkEnabledCallback { /** The path of the page. */ private final String path; + /** The template context factory. */ + private final TemplateContextFactory templateContextFactory; + /** The template to render. */ private final Template template; @@ -63,6 +67,8 @@ public class TemplatePage implements Page, LinkEnabledCallback { * * @param path * The path of the page + * @param templateContextFactory + * The template context factory * @param template * The template to render * @param l10n @@ -73,8 +79,9 @@ public class TemplatePage implements Page, LinkEnabledCallback { * The target to redirect to if a POST request does not contain * the correct form password */ - public TemplatePage(String path, Template template, BaseL10n l10n, String pageTitleKey, String invalidFormPasswordRedirectTarget) { + public TemplatePage(String path, TemplateContextFactory templateContextFactory, Template template, BaseL10n l10n, String pageTitleKey, String invalidFormPasswordRedirectTarget) { this.path = path; + this.templateContextFactory = templateContextFactory; this.template = template; this.l10n = l10n; this.pageTitleKey = pageTitleKey; @@ -117,10 +124,11 @@ public class TemplatePage implements Page, LinkEnabledCallback { pageNode.addForwardLink("icon", shortcutIcon); } - DataProvider dataProvider = template.createDataProvider(); + TemplateContext templateContext = templateContextFactory.createTemplateContext(); + templateContext.mergeContext(template.getInitialContext()); try { long start = System.nanoTime(); - processTemplate(request, dataProvider); + processTemplate(request, templateContext); long finish = System.nanoTime(); logger.log(Level.FINEST, "Template was rendered in " + ((finish - start) / 1000) / 1000.0 + "ms."); } catch (RedirectException re1) { @@ -128,10 +136,10 @@ public class TemplatePage implements Page, LinkEnabledCallback { } StringWriter stringWriter = new StringWriter(); - template.render(dataProvider, stringWriter); + template.render(templateContext, stringWriter); pageNode.content.addChild("%", stringWriter.toString()); - postProcess(request, dataProvider); + postProcess(request, templateContext); return new Response(200, "OK", "text/html", pageNode.outer.generate()); } @@ -161,12 +169,12 @@ public class TemplatePage implements Page, LinkEnabledCallback { * * @param request * The request that is rendered - * @param dataProvider - * The data provider to set variables in + * @param templateContext + * The template context to set variables in * @throws RedirectException * if the processing page wants to redirect after processing */ - protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException { + protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { /* do nothing. */ } @@ -180,10 +188,10 @@ public class TemplatePage implements Page, LinkEnabledCallback { * * @param request * The request being processed - * @param dataProvider - * The data provider that supplied the rendered data + * @param templateContext + * The template context that supplied the rendered data */ - protected void postProcess(Request request, DataProvider dataProvider) { + protected void postProcess(Request request, TemplateContext templateContext) { /* do nothing. */ } @@ -214,7 +222,7 @@ public class TemplatePage implements Page, LinkEnabledCallback { /** * Exception that can be thrown to signal that a subclassed {@link Page} * wants to redirect the user during the - * {@link TemplatePage#processTemplate(net.pterodactylus.sone.web.page.Page.Request, DataProvider)} + * {@link TemplatePage#processTemplate(net.pterodactylus.sone.web.page.Page.Request, TemplateContext)} * method call. * * @author David ‘Bombe’ Roden diff --git a/src/main/resources/i18n/sone.en.properties b/src/main/resources/i18n/sone.en.properties index b5c7e24..50dab27 100644 --- a/src/main/resources/i18n/sone.en.properties +++ b/src/main/resources/i18n/sone.en.properties @@ -158,6 +158,8 @@ Page.Distrust.Title=Distrust Sone - Sone Page.Untrust.Title=Untrust Sone - Sone +Page.MarkAsKnown.Title=Mark as Known - Sone + Page.NoPermission.Title=Unauthorized Access - Sone Page.NoPermission.Page.Title=Unauthorized Access Page.NoPermission.Text.NoPermission=You tried to do something that you do not have sufficient authorization for. Please refrain from such actions in the future or we will be forced to take counter-measures! @@ -236,6 +238,7 @@ Notification.NewSone.ShortText=New Sones have been discovered: Notification.NewSone.Text=New Sones have been discovered: Notification.NewPost.ShortText=New posts have been discovered. Notification.NewPost.Text=New posts have been discovered by the following Sones: +Notification.NewPost.Button.MarkRead=Mark as read Notification.NewReply.ShortText=New replies have been discovered. Notification.NewReply.Text=New replies have been discovered by the following Sones: Notification.SoneIsBeingRescued.Text=The following Sones are currently being rescued: diff --git a/src/main/resources/static/css/sone.css b/src/main/resources/static/css/sone.css index 7895246..c2cbdd1 100644 --- a/src/main/resources/static/css/sone.css +++ b/src/main/resources/static/css/sone.css @@ -113,6 +113,10 @@ textarea { margin-left: 1ex; } +#sone #notification-area .notification .mark-as-read { + float: right; +} + #sone #plugin-warning { border: solid 0.5em red; padding: 0.5em; diff --git a/src/main/resources/static/javascript/jquery.url.js b/src/main/resources/static/javascript/jquery.url.js new file mode 100644 index 0000000..20d8dfc --- /dev/null +++ b/src/main/resources/static/javascript/jquery.url.js @@ -0,0 +1,174 @@ +// JQuery URL Parser +// Written by Mark Perkins, mark@allmarkedup.com +// License: http://unlicense.org/ (i.e. do what you want with it!) + +jQuery.url = function() +{ + var segments = {}; + + var parsed = {}; + + /** + * Options object. Only the URI and strictMode values can be changed via the setters below. + */ + var options = { + + url : window.location, // default URI is the page in which the script is running + + strictMode: false, // 'loose' parsing by default + + key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], // keys available to query + + q: { + name: "queryKey", + parser: /(?:^|&)([^&=]*)=?([^&]*)/g + }, + + parser: { + strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, //less intuitive, more accurate to the specs + loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // more intuitive, fails on relative paths and deviates from specs + } + + }; + + /** + * Deals with the parsing of the URI according to the regex above. + * Written by Steven Levithan - see credits at top. + */ + var parseUri = function() + { + str = decodeURI( options.url ); + + var m = options.parser[ options.strictMode ? "strict" : "loose" ].exec( str ); + var uri = {}; + var i = 14; + + while ( i-- ) { + uri[ options.key[i] ] = m[i] || ""; + } + + uri[ options.q.name ] = {}; + uri[ options.key[12] ].replace( options.q.parser, function ( $0, $1, $2 ) { + if ($1) { + uri[options.q.name][$1] = $2; + } + }); + + return uri; + }; + + /** + * Returns the value of the passed in key from the parsed URI. + * + * @param string key The key whose value is required + */ + var key = function( key ) + { + if ( jQuery.isEmptyObject(parsed) ) + { + setUp(); // if the URI has not been parsed yet then do this first... + } + if ( key == "base" ) + { + if ( parsed.port !== null && parsed.port !== "" ) + { + return parsed.protocol+"://"+parsed.host+":"+parsed.port+"/"; + } + else + { + return parsed.protocol+"://"+parsed.host+"/"; + } + } + + return ( parsed[key] === "" ) ? null : parsed[key]; + }; + + /** + * Returns the value of the required query string parameter. + * + * @param string item The parameter whose value is required + */ + var param = function( item ) + { + if ( jQuery.isEmptyObject(parsed) ) + { + setUp(); // if the URI has not been parsed yet then do this first... + } + return ( parsed.queryKey[item] === null ) ? null : parsed.queryKey[item]; + }; + + /** + * 'Constructor' (not really!) function. + * Called whenever the URI changes to kick off re-parsing of the URI and splitting it up into segments. + */ + var setUp = function() + { + parsed = parseUri(); + + getSegments(); + }; + + /** + * Splits up the body of the URI into segments (i.e. sections delimited by '/') + */ + var getSegments = function() + { + var p = parsed.path; + segments = []; // clear out segments array + segments = parsed.path.length == 1 ? {} : ( p.charAt( p.length - 1 ) == "/" ? p.substring( 1, p.length - 1 ) : path = p.substring( 1 ) ).split("/"); + }; + + return { + + /** + * Sets the parsing mode - either strict or loose. Set to loose by default. + * + * @param string mode The mode to set the parser to. Anything apart from a value of 'strict' will set it to loose! + */ + setMode : function( mode ) + { + options.strictMode = mode == "strict" ? true : false; + return this; + }, + + /** + * Sets URI to parse if you don't want to to parse the current page's URI. + * Calling the function with no value for newUri resets it to the current page's URI. + * + * @param string newUri The URI to parse. + */ + setUrl : function( newUri ) + { + options.url = newUri === undefined ? window.location : newUri; + setUp(); + return this; + }, + + /** + * Returns the value of the specified URI segment. Segments are numbered from 1 to the number of segments. + * For example the URI http://test.com/about/company/ segment(1) would return 'about'. + * + * If no integer is passed into the function it returns the number of segments in the URI. + * + * @param int pos The position of the segment to return. Can be empty. + */ + segment : function( pos ) + { + if ( jQuery.isEmptyObject(parsed) ) + { + setUp(); // if the URI has not been parsed yet then do this first... + } + if ( pos === undefined ) + { + return segments.length; + } + return ( segments[pos] === "" || segments[pos] === undefined ) ? null : segments[pos]; + }, + + attr : key, // provides public access to private 'key' function - see above + + param : param // provides public access to private 'param' function - see above + + }; + +}(); \ No newline at end of file diff --git a/src/main/resources/static/javascript/sone.js b/src/main/resources/static/javascript/sone.js index 35b53e3..a0bbf8a 100644 --- a/src/main/resources/static/javascript/sone.js +++ b/src/main/resources/static/javascript/sone.js @@ -692,9 +692,17 @@ function ajaxifyReply(replyElement) { * jQuery object representing the notification. */ function ajaxifyNotification(notification) { - notification.find("form.dismiss").submit(function() { + notification.find("form").submit(function() { return false; }); + notification.find("input[name=returnPage]").val($.url.attr("relative")); + if (notification.find(".short-text").length > 0) { + notification.find(".short-text").removeClass("hidden"); + notification.find(".text").addClass("hidden"); + } + notification.find("form.mark-as-read button").click(function() { + $.getJSON("markAsKnown.ajax", {"formPassword": getFormPassword(), "type": $(":input[name=type]", this.form).val(), "id": $(":input[name=id]", this.form).val()}); + }); notification.find("form.dismiss button").click(function() { $.getJSON("dismissNotification.ajax", { "formPassword" : getFormPassword(), "notification" : notification.attr("id") }, function(data, textStatus) { /* dismiss in case of error, too. */ @@ -936,7 +944,7 @@ function markPostAsKnown(postElements) { postElement = this; if ($(postElement).hasClass("new")) { (function(postElement) { - $.getJSON("markPostAsKnown.ajax", {"formPassword": getFormPassword(), "post": getPostId(postElement)}, function(data, textStatus) { + $.getJSON("markAsKnown.ajax", {"formPassword": getFormPassword(), "type": "post", "id": getPostId(postElement)}, function(data, textStatus) { $(postElement).removeClass("new"); $(".click-to-show", postElement).removeClass("new"); }); @@ -951,7 +959,7 @@ function markReplyAsKnown(replyElements) { replyElement = this; if ($(replyElement).hasClass("new")) { (function(replyElement) { - $.getJSON("markReplyAsKnown.ajax", {"formPassword": getFormPassword(), "reply": getReplyId(replyElement)}, function(data, textStatus) { + $.getJSON("markAsKnown.ajax", {"formPassword": getFormPassword(), "type": "reply", "id": getReplyId(replyElement)}, function(data, textStatus) { $(replyElement).removeClass("new"); }); })(replyElement); diff --git a/src/main/resources/templates/include/head.html b/src/main/resources/templates/include/head.html index 4e43da4..a6051d0 100644 --- a/src/main/resources/templates/include/head.html +++ b/src/main/resources/templates/include/head.html @@ -4,6 +4,7 @@ +
@@ -27,7 +28,7 @@ <%/if> - <% notification> + <%include notification request=request>
<%/foreach> diff --git a/src/main/resources/templates/knownSones.html b/src/main/resources/templates/knownSones.html index f5907a0..33f0e27 100644 --- a/src/main/resources/templates/knownSones.html +++ b/src/main/resources/templates/knownSones.html @@ -5,8 +5,6 @@

<%= Page.KnownSones.Page.Title|l10n|html>

- <%getpage parameter=page> - <%paginate list=knownSones pagesize=25> <%= page|store key=pageParameter> <%include include/pagination.html> <%foreach pagination.items sone> diff --git a/src/main/resources/templates/notify/newPostNotification.html b/src/main/resources/templates/notify/newPostNotification.html index 94f7a1f..e5d7792 100644 --- a/src/main/resources/templates/notify/newPostNotification.html +++ b/src/main/resources/templates/notify/newPostNotification.html @@ -1,8 +1,15 @@ -
+ -