+ * Returns all {@link Core#isLocalSone(Sone) local Sone}s that are
+ * referenced by {@link SonePart}s in the given text (after parsing it using
+ * {@link SoneTextParser}).
+ *
+ * @param text
+ * The text to parse
+ * @return All mentioned local Sones
+ */
+ private Set<Sone> getMentionedSones(String text) {
+ /* we need no context to find mentioned Sones. */
+ Set<Sone> mentionedSones = new HashSet<Sone>();
+ try {
+ for (Part part : soneTextParser.parse(null, new StringReader(text))) {
+ if (part instanceof SonePart) {
+ mentionedSones.add(((SonePart) part).getSone());
+ }
+ }
+ } catch (IOException ioe1) {
+ logger.log(Level.WARNING, "Could not parse post text: " + text, ioe1);
+ }
+ return Filters.filteredSet(mentionedSones, Sone.LOCAL_SONE_FILTER);
+ }
+
+ /**
+ * Returns the Sone insert notification for the given Sone. If no
+ * notification for the given Sone exists, a new notification is created and
+ * cached.
+ *
+ * @param sone
+ * The Sone to get the insert notification for
+ * @return The Sone insert notification
+ */
+ private TemplateNotification getSoneInsertNotification(Sone sone) {
+ synchronized (soneInsertNotifications) {
+ TemplateNotification templateNotification = soneInsertNotifications.get(sone);
+ if (templateNotification == null) {
+ templateNotification = new TemplateNotification(TemplateParser.parse(createReader("/templates/notify/soneInsertNotification.html")));
+ templateNotification.set("insertSone", sone);
+ soneInsertNotifications.put(sone, templateNotification);
+ }
+ return templateNotification;
+ }
+ }
+
+ //
+ // CORELISTENER METHODS
+ //
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void newSoneFound(Sone sone) {
+ newSoneNotification.add(sone);
+ if (!hasFirstStartNotification()) {
+ notificationManager.addNotification(newSoneNotification);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void newPostFound(Post post) {
+ boolean isLocal = getCore().isLocalSone(post.getSone());
+ if (isLocal) {
+ localPostNotification.add(post);
+ } else {
+ newPostNotification.add(post);
+ }
+ if (!hasFirstStartNotification()) {
+ notificationManager.addNotification(isLocal ? localPostNotification : newPostNotification);
+ if (!getMentionedSones(post.getText()).isEmpty() && !isLocal) {
+ mentionNotification.add(post);
+ notificationManager.addNotification(mentionNotification);
+ }
+ } else {
+ getCore().markPostKnown(post);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void newReplyFound(PostReply reply) {
+ boolean isLocal = getCore().isLocalSone(reply.getSone());
+ if (isLocal) {
+ localReplyNotification.add(reply);
+ } else {
+ newReplyNotification.add(reply);
+ }
+ if (!hasFirstStartNotification()) {
+ notificationManager.addNotification(isLocal ? localReplyNotification : newReplyNotification);
+ if (!getMentionedSones(reply.getText()).isEmpty() && !isLocal && (reply.getPost().getSone() != null) && (reply.getTime() <= System.currentTimeMillis())) {
+ mentionNotification.add(reply.getPost());
+ notificationManager.addNotification(mentionNotification);
+ }
+ } else {
+ getCore().markReplyKnown(reply);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void markSoneKnown(Sone sone) {
+ newSoneNotification.remove(sone);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void markPostKnown(Post post) {
+ newPostNotification.remove(post);
+ localPostNotification.remove(post);
+ mentionNotification.remove(post);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void markReplyKnown(PostReply reply) {
+ newReplyNotification.remove(reply);
+ localReplyNotification.remove(reply);
+ mentionNotification.remove(reply.getPost());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void soneRemoved(Sone sone) {
+ newSoneNotification.remove(sone);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void postRemoved(Post post) {
+ newPostNotification.remove(post);
+ localPostNotification.remove(post);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void replyRemoved(PostReply reply) {
+ newReplyNotification.remove(reply);
+ localReplyNotification.remove(reply);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void soneLocked(final Sone sone) {
+ Object tickerObject = Ticker.getInstance().registerEvent(System.currentTimeMillis() + (5 * 60) * 1000, new Runnable() {
+
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() {
+ lockedSonesNotification.add(sone);
+ lockedSonesTickerObjects.remove(sone);
+ notificationManager.addNotification(lockedSonesNotification);
+ }
+ }, "Sone Locked Notification");
+ lockedSonesTickerObjects.put(sone, tickerObject);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void soneUnlocked(Sone sone) {
+ lockedSonesNotification.remove(sone);
+ Ticker.getInstance().deregisterEvent(lockedSonesTickerObjects.remove(sone));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void soneInserting(Sone sone) {
+ TemplateNotification soneInsertNotification = getSoneInsertNotification(sone);
+ soneInsertNotification.set("soneStatus", "inserting");
+ if (sone.getOptions().getBooleanOption("EnableSoneInsertNotifications").get()) {
+ notificationManager.addNotification(soneInsertNotification);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void soneInserted(Sone sone, long insertDuration) {
+ TemplateNotification soneInsertNotification = getSoneInsertNotification(sone);
+ soneInsertNotification.set("soneStatus", "inserted");
+ soneInsertNotification.set("insertDuration", insertDuration / 1000);
+ if (sone.getOptions().getBooleanOption("EnableSoneInsertNotifications").get()) {
+ notificationManager.addNotification(soneInsertNotification);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void soneInsertAborted(Sone sone, Throwable cause) {
+ TemplateNotification soneInsertNotification = getSoneInsertNotification(sone);
+ soneInsertNotification.set("soneStatus", "insert-aborted");
+ soneInsertNotification.set("insert-error", cause);
+ if (sone.getOptions().getBooleanOption("EnableSoneInsertNotifications").get()) {
+ notificationManager.addNotification(soneInsertNotification);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void updateFound(Version version, long releaseTime, long latestEdition) {
+ newVersionNotification.getTemplateContext().set("latestVersion", version);
+ newVersionNotification.getTemplateContext().set("latestEdition", latestEdition);
+ newVersionNotification.getTemplateContext().set("releaseTime", releaseTime);
+ notificationManager.addNotification(newVersionNotification);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void imageInsertStarted(Image image) {
+ insertingImagesNotification.add(image);
+ notificationManager.addNotification(insertingImagesNotification);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void imageInsertAborted(Image image) {
+ insertingImagesNotification.remove(image);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void imageInsertFinished(Image image) {
+ insertingImagesNotification.remove(image);
+ insertedImagesNotification.add(image);
+ notificationManager.addNotification(insertedImagesNotification);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void imageInsertFailed(Image image, Throwable cause) {
+ insertingImagesNotification.remove(image);
+ imageInsertFailedNotification.add(image);
+ notificationManager.addNotification(imageInsertFailedNotification);
+ }
+
+ /**