Use logging method that’s present in Java 1.7
[Sone.git] / src / main / java / net / pterodactylus / sone / core / SoneChangeDetector.java
1 package net.pterodactylus.sone.core;
2
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;
6
7 import java.util.Collection;
8
9 import net.pterodactylus.sone.data.Post;
10 import net.pterodactylus.sone.data.PostReply;
11 import net.pterodactylus.sone.data.Sone;
12
13 import com.google.common.base.Optional;
14 import com.google.common.base.Predicate;
15 import com.google.common.collect.FluentIterable;
16
17 /**
18  * Compares the contents of two {@link Sone}s and fires events for new and
19  * removed elements.
20  */
21 public class SoneChangeDetector {
22
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();
28
29         public SoneChangeDetector(Sone oldSone) {
30                 this.oldSone = oldSone;
31         }
32
33         public void onNewPosts(PostProcessor newPostProcessor) {
34                 this.newPostProcessor = fromNullable(newPostProcessor);
35         }
36
37         public void onRemovedPosts(PostProcessor removedPostProcessor) {
38                 this.removedPostProcessor = fromNullable(removedPostProcessor);
39         }
40
41         public void onNewPostReplies(PostReplyProcessor newPostReplyProcessor) {
42                 this.newPostReplyProcessor = fromNullable(newPostReplyProcessor);
43         }
44
45         public void onRemovedPostReplies(
46                         PostReplyProcessor removedPostReplyProcessor) {
47                 this.removedPostReplyProcessor = fromNullable(removedPostReplyProcessor);
48         }
49
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);
59         }
60
61         private void processPostReplies(FluentIterable<PostReply> postReplies,
62                         Optional<PostReplyProcessor> postReplyProcessor) {
63                 for (PostReply postReply : postReplies) {
64                         notifyPostReplyProcessor(postReplyProcessor, postReply);
65                 }
66         }
67
68         private void notifyPostReplyProcessor(
69                         Optional<PostReplyProcessor> postReplyProcessor,
70                         PostReply postReply) {
71                 if (postReplyProcessor.isPresent()) {
72                         postReplyProcessor.get()
73                                         .processPostReply(postReply);
74                 }
75         }
76
77         private void processPosts(FluentIterable<Post> posts,
78                         Optional<PostProcessor> newPostProcessor) {
79                 for (Post post : posts) {
80                         notifyPostProcessor(newPostProcessor, post);
81                 }
82         }
83
84         private void notifyPostProcessor(Optional<PostProcessor> postProcessor,
85                         Post newPost) {
86                 if (postProcessor.isPresent()) {
87                         postProcessor.get().processPost(newPost);
88                 }
89         }
90
91         private <T> Predicate<T> notContainedIn(final Collection<T> posts) {
92                 return new Predicate<T>() {
93                         @Override
94                         public boolean apply(T element) {
95                                 return !posts.contains(element);
96                         }
97                 };
98         }
99
100         public interface PostProcessor {
101
102                 void processPost(Post post);
103
104         }
105
106         public interface PostReplyProcessor {
107
108                 void processPostReply(PostReply postReply);
109
110         }
111
112 }