2 * Sone - WebInterface.java - Copyright © 2010–2019 David Roden
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 package net.pterodactylus.sone.web;
20 import static com.google.common.collect.FluentIterable.from;
21 import static java.util.logging.Logger.getLogger;
23 import java.util.Collection;
24 import java.util.HashMap;
27 import java.util.TimeZone;
28 import java.util.UUID;
29 import java.util.logging.Logger;
30 import javax.annotation.Nonnull;
31 import javax.annotation.Nullable;
32 import javax.inject.Named;
34 import net.pterodactylus.sone.core.Core;
35 import net.pterodactylus.sone.core.ElementLoader;
36 import net.pterodactylus.sone.core.event.*;
37 import net.pterodactylus.sone.data.Post;
38 import net.pterodactylus.sone.data.PostReply;
39 import net.pterodactylus.sone.data.Sone;
40 import net.pterodactylus.sone.freenet.L10nFilter;
41 import net.pterodactylus.sone.freenet.Translation;
42 import net.pterodactylus.sone.main.Loaders;
43 import net.pterodactylus.sone.main.PluginHomepage;
44 import net.pterodactylus.sone.main.PluginVersion;
45 import net.pterodactylus.sone.main.PluginYear;
46 import net.pterodactylus.sone.main.SonePlugin;
47 import net.pterodactylus.sone.notify.ListNotification;
48 import net.pterodactylus.sone.notify.ListNotificationFilter;
49 import net.pterodactylus.sone.notify.PostVisibilityFilter;
50 import net.pterodactylus.sone.notify.ReplyVisibilityFilter;
51 import net.pterodactylus.sone.template.LinkedElementRenderFilter;
52 import net.pterodactylus.sone.template.ParserFilter;
53 import net.pterodactylus.sone.template.RenderFilter;
54 import net.pterodactylus.sone.template.ShortenFilter;
55 import net.pterodactylus.sone.text.TimeTextConverter;
56 import net.pterodactylus.sone.web.ajax.BookmarkAjaxPage;
57 import net.pterodactylus.sone.web.ajax.CreatePostAjaxPage;
58 import net.pterodactylus.sone.web.ajax.CreateReplyAjaxPage;
59 import net.pterodactylus.sone.web.ajax.DeletePostAjaxPage;
60 import net.pterodactylus.sone.web.ajax.DeleteProfileFieldAjaxPage;
61 import net.pterodactylus.sone.web.ajax.DeleteReplyAjaxPage;
62 import net.pterodactylus.sone.web.ajax.DismissNotificationAjaxPage;
63 import net.pterodactylus.sone.web.ajax.EditAlbumAjaxPage;
64 import net.pterodactylus.sone.web.ajax.EditImageAjaxPage;
65 import net.pterodactylus.sone.web.ajax.EditProfileFieldAjaxPage;
66 import net.pterodactylus.sone.web.ajax.FollowSoneAjaxPage;
67 import net.pterodactylus.sone.web.ajax.GetLikesAjaxPage;
68 import net.pterodactylus.sone.web.ajax.GetLinkedElementAjaxPage;
69 import net.pterodactylus.sone.web.ajax.GetNotificationsAjaxPage;
70 import net.pterodactylus.sone.web.ajax.GetPostAjaxPage;
71 import net.pterodactylus.sone.web.ajax.GetReplyAjaxPage;
72 import net.pterodactylus.sone.web.ajax.GetStatusAjaxPage;
73 import net.pterodactylus.sone.web.ajax.GetTimesAjaxPage;
74 import net.pterodactylus.sone.web.ajax.GetTranslationAjaxPage;
75 import net.pterodactylus.sone.web.ajax.LikeAjaxPage;
76 import net.pterodactylus.sone.web.ajax.LockSoneAjaxPage;
77 import net.pterodactylus.sone.web.ajax.MarkAsKnownAjaxPage;
78 import net.pterodactylus.sone.web.ajax.MoveProfileFieldAjaxPage;
79 import net.pterodactylus.sone.web.ajax.UnbookmarkAjaxPage;
80 import net.pterodactylus.sone.web.ajax.UnfollowSoneAjaxPage;
81 import net.pterodactylus.sone.web.ajax.UnlikeAjaxPage;
82 import net.pterodactylus.sone.web.ajax.UnlockSoneAjaxPage;
83 import net.pterodactylus.sone.web.page.FreenetRequest;
84 import net.pterodactylus.sone.web.page.TemplateRenderer;
85 import net.pterodactylus.sone.web.pages.*;
86 import net.pterodactylus.util.notify.Notification;
87 import net.pterodactylus.util.notify.NotificationManager;
88 import net.pterodactylus.util.notify.TemplateNotification;
89 import net.pterodactylus.util.template.Template;
90 import net.pterodactylus.util.template.TemplateContextFactory;
91 import net.pterodactylus.util.web.RedirectPage;
92 import net.pterodactylus.util.web.TemplatePage;
94 import freenet.clients.http.SessionManager;
95 import freenet.clients.http.SessionManager.Session;
96 import freenet.clients.http.ToadletContext;
98 import com.codahale.metrics.*;
99 import com.google.common.base.Optional;
100 import com.google.common.collect.ImmutableSet;
101 import com.google.common.eventbus.Subscribe;
102 import com.google.inject.Inject;
105 * Bundles functionality that a web interface of a Freenet plugin needs, e.g.
106 * references to l10n helpers.
108 public class WebInterface implements SessionProvider {
111 private static final Logger logger = getLogger(WebInterface.class.getName());
113 /** The loaders for templates, pages, and classpath providers. */
114 private final Loaders loaders;
116 /** The notification manager. */
117 private final NotificationManager notificationManager;
119 /** The Sone plugin. */
120 private final SonePlugin sonePlugin;
122 /** The form password. */
123 private final String formPassword;
125 /** The template context factory. */
126 private final TemplateContextFactory templateContextFactory;
127 private final TemplateRenderer templateRenderer;
129 /** The parser filter. */
130 private final ParserFilter parserFilter;
131 private final ShortenFilter shortenFilter;
132 private final RenderFilter renderFilter;
134 private final ListNotificationFilter listNotificationFilter;
135 private final PostVisibilityFilter postVisibilityFilter;
136 private final ReplyVisibilityFilter replyVisibilityFilter;
138 private final ElementLoader elementLoader;
139 private final LinkedElementRenderFilter linkedElementRenderFilter;
140 private final TimeTextConverter timeTextConverter = new TimeTextConverter();
141 private final L10nFilter l10nFilter;
143 private final PageToadletRegistry pageToadletRegistry;
144 private final MetricRegistry metricRegistry;
145 private final Translation translation;
147 /** The “new post” notification. */
148 private final ListNotification<Post> newPostNotification;
150 /** The “new reply” notification. */
151 private final ListNotification<PostReply> newReplyNotification;
153 /** The invisible “local post” notification. */
154 private final ListNotification<Post> localPostNotification;
156 /** The invisible “local reply” notification. */
157 private final ListNotification<PostReply> localReplyNotification;
159 /** Notifications for sone inserts. */
160 private final Map<Sone, TemplateNotification> soneInsertNotifications = new HashMap<>();
163 public WebInterface(SonePlugin sonePlugin, Loaders loaders, ListNotificationFilter listNotificationFilter,
164 PostVisibilityFilter postVisibilityFilter, ReplyVisibilityFilter replyVisibilityFilter,
165 ElementLoader elementLoader, TemplateContextFactory templateContextFactory,
166 TemplateRenderer templateRenderer,
167 ParserFilter parserFilter, ShortenFilter shortenFilter,
168 RenderFilter renderFilter,
169 LinkedElementRenderFilter linkedElementRenderFilter,
170 PageToadletRegistry pageToadletRegistry, MetricRegistry metricRegistry, Translation translation, L10nFilter l10nFilter,
171 NotificationManager notificationManager, @Named("newRemotePost") ListNotification<Post> newPostNotification,
172 @Named("localPost") ListNotification<Post> localPostNotification) {
173 this.sonePlugin = sonePlugin;
174 this.loaders = loaders;
175 this.listNotificationFilter = listNotificationFilter;
176 this.postVisibilityFilter = postVisibilityFilter;
177 this.replyVisibilityFilter = replyVisibilityFilter;
178 this.elementLoader = elementLoader;
179 this.templateRenderer = templateRenderer;
180 this.parserFilter = parserFilter;
181 this.shortenFilter = shortenFilter;
182 this.renderFilter = renderFilter;
183 this.linkedElementRenderFilter = linkedElementRenderFilter;
184 this.pageToadletRegistry = pageToadletRegistry;
185 this.metricRegistry = metricRegistry;
186 this.l10nFilter = l10nFilter;
187 this.translation = translation;
188 this.notificationManager = notificationManager;
189 this.newPostNotification = newPostNotification;
190 this.localPostNotification = localPostNotification;
191 formPassword = sonePlugin.pluginRespirator().getToadletContainer().getFormPassword();
193 this.templateContextFactory = templateContextFactory;
194 templateContextFactory.addTemplateObject("webInterface", this);
195 templateContextFactory.addTemplateObject("formPassword", formPassword);
197 /* create notifications. */
198 Template newReplyNotificationTemplate = loaders.loadTemplate("/templates/notify/newReplyNotification.html");
199 newReplyNotification = new ListNotification<>("new-reply-notification", "replies", newReplyNotificationTemplate, false);
201 Template localReplyNotificationTemplate = loaders.loadTemplate("/templates/notify/newReplyNotification.html");
202 localReplyNotification = new ListNotification<>("local-reply-notification", "replies", localReplyNotificationTemplate, false);
210 * Returns the Sone core used by the Sone plugin.
212 * @return The Sone core
215 public Core getCore() {
216 return sonePlugin.core();
220 * Returns the template context factory of the web interface.
222 * @return The template context factory
224 public TemplateContextFactory getTemplateContextFactory() {
225 return templateContextFactory;
228 private Session getCurrentSessionWithoutCreation(ToadletContext toadletContenxt) {
229 return getSessionManager().useSession(toadletContenxt);
232 private Session getOrCreateCurrentSession(ToadletContext toadletContenxt) {
233 Session session = getCurrentSessionWithoutCreation(toadletContenxt);
234 if (session == null) {
235 session = getSessionManager().createSession(UUID.randomUUID().toString(), toadletContenxt);
240 public Sone getCurrentSoneCreatingSession(ToadletContext toadletContext) {
241 Collection<Sone> localSones = getCore().getLocalSones();
242 if (localSones.size() == 1) {
243 return localSones.iterator().next();
245 return getCurrentSone(getOrCreateCurrentSession(toadletContext));
248 public Sone getCurrentSoneWithoutCreatingSession(ToadletContext toadletContext) {
249 Collection<Sone> localSones = getCore().getLocalSones();
250 if (localSones.size() == 1) {
251 return localSones.iterator().next();
253 return getCurrentSone(getCurrentSessionWithoutCreation(toadletContext));
257 * Returns the currently logged in Sone.
261 * @return The currently logged in Sone, or {@code null} if no Sone is
262 * currently logged in
264 private Sone getCurrentSone(Session session) {
265 if (session == null) {
268 String soneId = (String) session.getAttribute("Sone.CurrentSone");
269 if (soneId == null) {
272 return getCore().getLocalSone(soneId);
277 public Sone getCurrentSone(@Nonnull ToadletContext toadletContext, boolean createSession) {
278 return createSession ? getCurrentSoneCreatingSession(toadletContext) : getCurrentSoneWithoutCreatingSession(toadletContext);
282 * Sets the currently logged in Sone.
284 * @param toadletContext
285 * The toadlet context
287 * The Sone to set as currently logged in
290 public void setCurrentSone(@Nonnull ToadletContext toadletContext, @Nullable Sone sone) {
291 Session session = getOrCreateCurrentSession(toadletContext);
293 session.removeAttribute("Sone.CurrentSone");
295 session.setAttribute("Sone.CurrentSone", sone.getId());
300 * Returns the notification manager.
302 * @return The notification manager
304 public NotificationManager getNotifications() {
305 return notificationManager;
309 public Optional<Notification> getNotification(@Nonnull String notificationId) {
310 return Optional.fromNullable(notificationManager.getNotification(notificationId));
314 public Collection<Notification> getNotifications(@Nullable Sone currentSone) {
315 return listNotificationFilter.filterNotifications(notificationManager.getNotifications(), currentSone);
318 public Translation getTranslation() {
323 * Returns the session manager of the node.
325 * @return The node’s session manager
327 public SessionManager getSessionManager() {
328 return sonePlugin.pluginRespirator().getSessionManager("Sone");
332 * Returns the node’s form password.
334 * @return The form password
336 public String getFormPassword() {
341 public Collection<Post> getNewPosts(@Nullable Sone currentSone) {
342 Set<Post> allNewPosts = ImmutableSet.<Post> builder()
343 .addAll(newPostNotification.getElements())
344 .addAll(localPostNotification.getElements())
346 return from(allNewPosts).filter(postVisibilityFilter.isVisible(currentSone)).toSet();
350 * Returns the replies that have been announced as new in the
351 * {@link #newReplyNotification}.
353 * @return The new replies
355 public Set<PostReply> getNewReplies() {
356 return ImmutableSet.<PostReply> builder().addAll(newReplyNotification.getElements()).addAll(localReplyNotification.getElements()).build();
360 public Collection<PostReply> getNewReplies(@Nullable Sone currentSone) {
361 Set<PostReply> allNewReplies = ImmutableSet.<PostReply>builder()
362 .addAll(newReplyNotification.getElements())
363 .addAll(localReplyNotification.getElements())
365 return from(allNewReplies).filter(replyVisibilityFilter.isVisible(currentSone)).toSet();
373 * Returns whether the first start notification is currently displayed.
375 * @return {@code true} if the first-start notification is currently
376 * displayed, {@code false} otherwise
378 private boolean hasFirstStartNotification() {
379 return notificationManager.getNotification("first-start-notification") != null;
387 * Starts the web interface and registers all toadlets.
389 public void start() {
394 * Stops the web interface and unregisters all toadlets.
397 pageToadletRegistry.unregisterToadlets();
405 * Register all toadlets.
407 private void registerToadlets() {
408 Template postTemplate = loaders.loadTemplate("/templates/include/viewPost.html");
409 Template replyTemplate = loaders.loadTemplate("/templates/include/viewReply.html");
410 Template openSearchTemplate = loaders.loadTemplate("/templates/xml/OpenSearch.xml");
412 pageToadletRegistry.addPage(new RedirectPage<FreenetRequest>("", "index.html"));
413 pageToadletRegistry.addPage(new IndexPage(this, loaders, templateRenderer, postVisibilityFilter));
414 pageToadletRegistry.addPage(new NewPage(this, loaders, templateRenderer));
415 pageToadletRegistry.addPage(new CreateSonePage(this, loaders, templateRenderer));
416 pageToadletRegistry.addPage(new KnownSonesPage(this, loaders, templateRenderer));
417 pageToadletRegistry.addPage(new EditProfilePage(this, loaders, templateRenderer));
418 pageToadletRegistry.addPage(new EditProfileFieldPage(this, loaders, templateRenderer));
419 pageToadletRegistry.addPage(new DeleteProfileFieldPage(this, loaders, templateRenderer));
420 pageToadletRegistry.addPage(new CreatePostPage(this, loaders, templateRenderer));
421 pageToadletRegistry.addPage(new CreateReplyPage(this, loaders, templateRenderer));
422 pageToadletRegistry.addPage(new ViewSonePage(this, loaders, templateRenderer));
423 pageToadletRegistry.addPage(new ViewPostPage(this, loaders, templateRenderer));
424 pageToadletRegistry.addPage(new LikePage(this, loaders, templateRenderer));
425 pageToadletRegistry.addPage(new UnlikePage(this, loaders, templateRenderer));
426 pageToadletRegistry.addPage(new DeletePostPage(this, loaders, templateRenderer));
427 pageToadletRegistry.addPage(new DeleteReplyPage(this, loaders, templateRenderer));
428 pageToadletRegistry.addPage(new LockSonePage(this, loaders, templateRenderer));
429 pageToadletRegistry.addPage(new UnlockSonePage(this, loaders, templateRenderer));
430 pageToadletRegistry.addPage(new FollowSonePage(this, loaders, templateRenderer));
431 pageToadletRegistry.addPage(new UnfollowSonePage(this, loaders, templateRenderer));
432 pageToadletRegistry.addPage(new ImageBrowserPage(this, loaders, templateRenderer));
433 pageToadletRegistry.addPage(new CreateAlbumPage(this, loaders, templateRenderer));
434 pageToadletRegistry.addPage(new EditAlbumPage(this, loaders, templateRenderer));
435 pageToadletRegistry.addPage(new DeleteAlbumPage(this, loaders, templateRenderer));
436 pageToadletRegistry.addPage(new UploadImagePage(this, loaders, templateRenderer));
437 pageToadletRegistry.addPage(new EditImagePage(this, loaders, templateRenderer));
438 pageToadletRegistry.addPage(new DeleteImagePage(this, loaders, templateRenderer));
439 pageToadletRegistry.addPage(new MarkAsKnownPage(this, loaders, templateRenderer));
440 pageToadletRegistry.addPage(new BookmarkPage(this, loaders, templateRenderer));
441 pageToadletRegistry.addPage(new UnbookmarkPage(this, loaders, templateRenderer));
442 pageToadletRegistry.addPage(new BookmarksPage(this, loaders, templateRenderer));
443 pageToadletRegistry.addPage(new SearchPage(this, loaders, templateRenderer));
444 pageToadletRegistry.addPage(new DeleteSonePage(this, loaders, templateRenderer));
445 pageToadletRegistry.addPage(new LoginPage(this, loaders, templateRenderer));
446 pageToadletRegistry.addPage(new LogoutPage(this, loaders, templateRenderer));
447 pageToadletRegistry.addPage(new OptionsPage(this, loaders, templateRenderer));
448 pageToadletRegistry.addPage(new RescuePage(this, loaders, templateRenderer));
449 pageToadletRegistry.addPage(new AboutPage(this, loaders, templateRenderer, new PluginVersion(SonePlugin.getPluginVersion()), new PluginYear(sonePlugin.getYear()), new PluginHomepage(sonePlugin.getHomepage())));
450 pageToadletRegistry.addPage(new InvalidPage(this, loaders, templateRenderer));
451 pageToadletRegistry.addPage(new NoPermissionPage(this, loaders, templateRenderer));
452 pageToadletRegistry.addPage(new EmptyImageTitlePage(this, loaders, templateRenderer));
453 pageToadletRegistry.addPage(new EmptyAlbumTitlePage(this, loaders, templateRenderer));
454 pageToadletRegistry.addPage(new DismissNotificationPage(this, loaders, templateRenderer));
455 pageToadletRegistry.addPage(new DebugPage(this, loaders, templateRenderer));
456 pageToadletRegistry.addDebugPage(new MetricsPage(this, loaders, templateRenderer, metricRegistry));
457 pageToadletRegistry.addPage(loaders.<FreenetRequest>loadStaticPage("css/", "/static/css/", "text/css"));
458 pageToadletRegistry.addPage(loaders.<FreenetRequest>loadStaticPage("javascript/", "/static/javascript/", "text/javascript"));
459 pageToadletRegistry.addPage(loaders.<FreenetRequest>loadStaticPage("images/", "/static/images/", "image/png"));
460 pageToadletRegistry.addPage(new TemplatePage<FreenetRequest>("OpenSearch.xml", "application/opensearchdescription+xml", templateContextFactory, openSearchTemplate));
461 pageToadletRegistry.addPage(new GetImagePage(this));
462 pageToadletRegistry.addPage(new GetTranslationAjaxPage(this));
463 pageToadletRegistry.addPage(new GetStatusAjaxPage(this, elementLoader, timeTextConverter, l10nFilter, TimeZone.getDefault()));
464 pageToadletRegistry.addPage(new GetNotificationsAjaxPage(this));
465 pageToadletRegistry.addPage(new DismissNotificationAjaxPage(this));
466 pageToadletRegistry.addPage(new CreatePostAjaxPage(this));
467 pageToadletRegistry.addPage(new CreateReplyAjaxPage(this));
468 pageToadletRegistry.addPage(new GetReplyAjaxPage(this, replyTemplate));
469 pageToadletRegistry.addPage(new GetPostAjaxPage(this, postTemplate));
470 pageToadletRegistry.addPage(new GetLinkedElementAjaxPage(this, elementLoader, linkedElementRenderFilter));
471 pageToadletRegistry.addPage(new GetTimesAjaxPage(this, timeTextConverter, l10nFilter, TimeZone.getDefault()));
472 pageToadletRegistry.addPage(new MarkAsKnownAjaxPage(this));
473 pageToadletRegistry.addPage(new DeletePostAjaxPage(this));
474 pageToadletRegistry.addPage(new DeleteReplyAjaxPage(this));
475 pageToadletRegistry.addPage(new LockSoneAjaxPage(this));
476 pageToadletRegistry.addPage(new UnlockSoneAjaxPage(this));
477 pageToadletRegistry.addPage(new FollowSoneAjaxPage(this));
478 pageToadletRegistry.addPage(new UnfollowSoneAjaxPage(this));
479 pageToadletRegistry.addPage(new EditAlbumAjaxPage(this));
480 pageToadletRegistry.addPage(new EditImageAjaxPage(this, parserFilter, shortenFilter, renderFilter));
481 pageToadletRegistry.addPage(new LikeAjaxPage(this));
482 pageToadletRegistry.addPage(new UnlikeAjaxPage(this));
483 pageToadletRegistry.addPage(new GetLikesAjaxPage(this));
484 pageToadletRegistry.addPage(new BookmarkAjaxPage(this));
485 pageToadletRegistry.addPage(new UnbookmarkAjaxPage(this));
486 pageToadletRegistry.addPage(new EditProfileFieldAjaxPage(this));
487 pageToadletRegistry.addPage(new DeleteProfileFieldAjaxPage(this));
488 pageToadletRegistry.addPage(new MoveProfileFieldAjaxPage(this));
490 pageToadletRegistry.registerToadlets();
494 * Returns the Sone insert notification for the given Sone. If no
495 * notification for the given Sone exists, a new notification is created and
499 * The Sone to get the insert notification for
500 * @return The Sone insert notification
502 private TemplateNotification getSoneInsertNotification(Sone sone) {
503 synchronized (soneInsertNotifications) {
504 TemplateNotification templateNotification = soneInsertNotifications.get(sone);
505 if (templateNotification == null) {
506 templateNotification = new TemplateNotification(loaders.loadTemplate("/templates/notify/soneInsertNotification.html"));
507 templateNotification.set("insertSone", sone);
508 soneInsertNotifications.put(sone, templateNotification);
510 return templateNotification;
519 * Notifies the web interface that a new {@link PostReply} was found.
521 * @param newPostReplyFoundEvent
525 public void newReplyFound(NewPostReplyFoundEvent newPostReplyFoundEvent) {
526 PostReply reply = newPostReplyFoundEvent.getPostReply();
527 boolean isLocal = reply.getSone().isLocal();
529 localReplyNotification.add(reply);
531 newReplyNotification.add(reply);
533 if (!hasFirstStartNotification()) {
534 notificationManager.addNotification(isLocal ? localReplyNotification : newReplyNotification);
536 getCore().markReplyKnown(reply);
541 public void markPostKnown(MarkPostKnownEvent markPostKnownEvent) {
542 removePost(markPostKnownEvent.getPost());
546 public void markReplyKnown(MarkPostReplyKnownEvent markPostReplyKnownEvent) {
547 removeReply(markPostReplyKnownEvent.getPostReply());
551 public void postRemoved(PostRemovedEvent postRemovedEvent) {
552 removePost(postRemovedEvent.getPost());
555 private void removePost(Post post) {
556 newPostNotification.remove(post);
560 public void replyRemoved(PostReplyRemovedEvent postReplyRemovedEvent) {
561 removeReply(postReplyRemovedEvent.getPostReply());
564 private void removeReply(PostReply reply) {
565 newReplyNotification.remove(reply);
566 localReplyNotification.remove(reply);
570 * Notifies the web interface that a {@link Sone} is being inserted.
572 * @param soneInsertingEvent
576 public void soneInserting(SoneInsertingEvent soneInsertingEvent) {
577 TemplateNotification soneInsertNotification = getSoneInsertNotification(soneInsertingEvent.getSone());
578 soneInsertNotification.set("soneStatus", "inserting");
579 if (soneInsertingEvent.getSone().getOptions().isSoneInsertNotificationEnabled()) {
580 notificationManager.addNotification(soneInsertNotification);
585 * Notifies the web interface that a {@link Sone} was inserted.
587 * @param soneInsertedEvent
591 public void soneInserted(SoneInsertedEvent soneInsertedEvent) {
592 TemplateNotification soneInsertNotification = getSoneInsertNotification(soneInsertedEvent.getSone());
593 soneInsertNotification.set("soneStatus", "inserted");
594 soneInsertNotification.set("insertDuration", soneInsertedEvent.getInsertDuration() / 1000);
595 if (soneInsertedEvent.getSone().getOptions().isSoneInsertNotificationEnabled()) {
596 notificationManager.addNotification(soneInsertNotification);
601 * Notifies the web interface that a {@link Sone} insert was aborted.
603 * @param soneInsertAbortedEvent
607 public void soneInsertAborted(SoneInsertAbortedEvent soneInsertAbortedEvent) {
608 TemplateNotification soneInsertNotification = getSoneInsertNotification(soneInsertAbortedEvent.getSone());
609 soneInsertNotification.set("soneStatus", "insert-aborted");
610 soneInsertNotification.set("insert-error", soneInsertAbortedEvent.getCause());
611 if (soneInsertAbortedEvent.getSone().getOptions().isSoneInsertNotificationEnabled()) {
612 notificationManager.addNotification(soneInsertNotification);
617 public void debugActivated(@Nonnull DebugActivatedEvent debugActivatedEvent) {
618 pageToadletRegistry.activateDebugMode();