1 package net.pterodactylus.sone.core;
3 import static com.google.common.base.Optional.absent;
4 import static com.google.common.base.Optional.fromNullable;
5 import static com.google.common.collect.FluentIterable.from;
7 import java.util.Collection;
9 import net.pterodactylus.sone.data.Post;
10 import net.pterodactylus.sone.data.PostReply;
11 import net.pterodactylus.sone.data.Sone;
13 import com.google.common.base.Optional;
14 import com.google.common.base.Predicate;
15 import com.google.common.collect.FluentIterable;
18 * Compares the contents of two {@link Sone}s and fires events for new and
21 public class SoneChangeDetector {
23 private final Sone oldSone;
24 private Optional<PostProcessor> newPostProcessor = absent();
25 private Optional<PostProcessor> removedPostProcessor = absent();
26 private Optional<PostReplyProcessor> newPostReplyProcessor = absent();
27 private Optional<PostReplyProcessor> removedPostReplyProcessor = absent();
29 public SoneChangeDetector(Sone oldSone) {
30 this.oldSone = oldSone;
33 public void onNewPosts(PostProcessor newPostProcessor) {
34 this.newPostProcessor = fromNullable(newPostProcessor);
37 public void onRemovedPosts(PostProcessor removedPostProcessor) {
38 this.removedPostProcessor = fromNullable(removedPostProcessor);
41 public void onNewPostReplies(PostReplyProcessor newPostReplyProcessor) {
42 this.newPostReplyProcessor = fromNullable(newPostReplyProcessor);
45 public void onRemovedPostReplies(
46 PostReplyProcessor removedPostReplyProcessor) {
47 this.removedPostReplyProcessor = fromNullable(removedPostReplyProcessor);
50 public void detectChanges(Sone newSone) {
51 processPosts(from(newSone.getPosts()).filter(
52 notContainedIn(oldSone.getPosts())), newPostProcessor);
53 processPosts(from(oldSone.getPosts()).filter(
54 notContainedIn(newSone.getPosts())), removedPostProcessor);
55 processPostReplies(from(newSone.getReplies()).filter(
56 notContainedIn(oldSone.getReplies())), newPostReplyProcessor);
57 processPostReplies(from(oldSone.getReplies()).filter(
58 notContainedIn(newSone.getReplies())), removedPostReplyProcessor);
61 private void processPostReplies(FluentIterable<PostReply> postReplies,
62 Optional<PostReplyProcessor> postReplyProcessor) {
63 for (PostReply postReply : postReplies) {
64 notifyPostReplyProcessor(postReplyProcessor, postReply);
68 private void notifyPostReplyProcessor(
69 Optional<PostReplyProcessor> postReplyProcessor,
70 PostReply postReply) {
71 if (postReplyProcessor.isPresent()) {
72 postReplyProcessor.get()
73 .processPostReply(postReply);
77 private void processPosts(FluentIterable<Post> posts,
78 Optional<PostProcessor> newPostProcessor) {
79 for (Post post : posts) {
80 notifyPostProcessor(newPostProcessor, post);
84 private void notifyPostProcessor(Optional<PostProcessor> postProcessor,
86 if (postProcessor.isPresent()) {
87 postProcessor.get().processPost(newPost);
91 private <T> Predicate<T> notContainedIn(final Collection<T> posts) {
92 return new Predicate<T>() {
94 public boolean apply(T element) {
95 return !posts.contains(element);
100 public interface PostProcessor {
102 void processPost(Post post);
106 public interface PostReplyProcessor {
108 void processPostReply(PostReply postReply);