import net.pterodactylus.util.service.AbstractService;
import net.pterodactylus.util.thread.NamedThreadFactory;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Ordering;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Inject;
* {@inheritDoc}
*/
@Override
- public Post getPost(String postId) {
+ public Optional<Post> getPost(String postId) {
synchronized (posts) {
- return posts.get(postId);
+ return Optional.fromNullable(posts.get(postId));
}
}
* {@inheritDoc}
*/
@Override
- public PostReply getPostReply(String replyId) {
+ public Optional<PostReply> getPostReply(String replyId) {
synchronized (replies) {
- return replies.get(replyId);
+ return Optional.fromNullable(replies.get(replyId));
}
}
* {@inheritDoc}
*/
@Override
- public List<PostReply> getReplies(Post post) {
- Set<Sone> sones = getSones();
- List<PostReply> replies = new ArrayList<PostReply>();
- for (Sone sone : sones) {
- for (PostReply reply : sone.getReplies()) {
- if (reply.getPost().equals(post)) {
- replies.add(reply);
- }
+ public List<PostReply> getReplies(final Post post) {
+ return Ordering.from(Reply.TIME_COMPARATOR).sortedCopy(FluentIterable.from(getSones()).transformAndConcat(new Function<Sone, Iterable<PostReply>>() {
+
+ @Override
+ public Iterable<PostReply> apply(Sone sone) {
+ return sone.getReplies();
}
- }
- Collections.sort(replies, Reply.TIME_COMPARATOR);
- return replies;
+ }).filter(new Predicate<PostReply>() {
+
+ @Override
+ public boolean apply(PostReply reply) {
+ return post.equals(reply.getPost());
+ }
+ }));
}
/**
Set<Post> posts = new HashSet<Post>();
synchronized (bookmarkedPosts) {
for (String bookmarkedPostId : bookmarkedPosts) {
- Post post = getPost(bookmarkedPostId);
- if (post != null) {
- posts.add(post);
+ Optional<Post> post = getPost(bookmarkedPostId);
+ if (!post.isPresent()) {
+ posts.add(post.get());
}
}
}
synchronized (knownPosts) {
for (Post post : sone.getPosts()) {
PostBuilder postBuilder = postBuilderFactory.newPostBuilder();
- postBuilder.copyPost(post).from(storedSone);
+ postBuilder.copyPost(post).from(storedSone.getId());
Post newPost = postBuilder.build().setKnown(knownPosts.contains(post.getId()));
if (!storedPosts.contains(newPost)) {
if (newPost.getTime() < getSoneFollowingTime(sone)) {
Set<PostReply> storedReplies = storedSone.getReplies();
synchronized (knownReplies) {
for (PostReply reply : sone.getReplies()) {
- reply.setSone(storedSone).setKnown(knownReplies.contains(reply.getId()));
+ reply.setKnown(knownReplies.contains(reply.getId()));
if (!storedReplies.contains(reply)) {
if (reply.getTime() < getSoneFollowingTime(sone)) {
knownReplies.add(reply.getId());
logger.log(Level.WARNING, "Invalid post found, aborting load!");
return;
}
- PostBuilder postBuilder = postBuilder().withId(postId).from(sone).withTime(postTime).withText(postText);
- PostBuilder postBuilder = postBuilderFactory.newPostBuilder().withId(postId).from(sone.getId()).withTime(postTime).withText(postText);
++ PostBuilder postBuilder = postBuilder().withId(postId).from(sone.getId()).withTime(postTime).withText(postText);
if ((postRecipientId != null) && (postRecipientId.length() == 43)) {
- postBuilder.to(getSone(postRecipientId));
+ postBuilder.to(postRecipientId);
}
posts.add(postBuilder.build());
}
return;
}
PostReplyBuilder postReplyBuilder = postReplyBuilderFactory.newPostReplyBuilder();
- postReplyBuilder.withId(replyId).from(sone).to(postId).withTime(replyTime).withText(replyText);
+ postReplyBuilder.withId(replyId).from(sone.getId()).to(postId).withTime(replyTime).withText(replyText);
replies.add(postReplyBuilder.build());
}
return null;
}
PostBuilder postBuilder = postBuilderFactory.newPostBuilder();
- postBuilder.from(sone).randomId().withTime(time).withText(text.trim());
+ postBuilder.from(sone.getId()).randomId().withTime(time).withText(text.trim());
if (recipient != null) {
- postBuilder.to(recipient);
+ postBuilder.to(recipient.getId());
}
final Post post = postBuilder.build();
synchronized (posts) {
return null;
}
PostReplyBuilder postReplyBuilder = postReplyBuilderFactory.newPostReplyBuilder();
- postReplyBuilder.randomId().from(sone).to(post.getId()).currentTime().withText(text.trim());
+ postReplyBuilder.randomId().from(sone.getId()).to(post.getId()).currentTime().withText(text.trim());
final PostReply reply = postReplyBuilder.build();
synchronized (replies) {
replies.put(reply.getId(), reply);
webOfTrustUpdater.stop();
updateChecker.stop();
soneDownloader.stop();
+ soneDownloaders.shutdown();
identityManager.stop();
}
for (PostReply reply : sone.getReplies()) {
String replyPrefix = sonePrefix + "/Replies/" + replyCounter++;
configuration.getStringValue(replyPrefix + "/ID").setValue(reply.getId());
- configuration.getStringValue(replyPrefix + "/Post/ID").setValue(reply.getPost().getId());
+ configuration.getStringValue(replyPrefix + "/Post/ID").setValue(reply.getPostId());
configuration.getLongValue(replyPrefix + "/Time").setValue(reply.getTime());
configuration.getStringValue(replyPrefix + "/Text").setValue(reply.getText());
}
package net.pterodactylus.sone.data;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+
/**
* A reply is like a {@link Post} but can never be posted on its own, it always
* refers to another {@link Post}.
public interface PostReply extends Reply<PostReply> {
/**
+ * Filter that selects {@link PostReply}s that have a
+ * {@link Optional#isPresent() present} {@link #getPost() post}.
+ */
+ public static final Predicate<PostReply> HAS_POST_FILTER = new Predicate<PostReply>() {
+
+ @Override
+ public boolean apply(PostReply postReply) {
+ return postReply.getPost().isPresent();
+ }
+ };
+
+ /**
+ * Returns the ID of the post this reply refers to.
+ *
+ * @return The ID of the post this reply refers to
+ */
+ public String getPostId();
+
+ /**
* Returns the post this reply refers to.
*
* @return The post this reply refers to
*/
- public Post getPost();
+ public Optional<Post> getPost();
- /**
- * Sets the post this reply refers to.
- *
- * @param postId
- * The ID of the post to reply to
- * @return This reply
- */
- public PostReply setPost(String postId);
-
}
package net.pterodactylus.sone.data.impl;
import net.pterodactylus.sone.core.PostProvider;
+ import net.pterodactylus.sone.core.SoneProvider;
import net.pterodactylus.sone.data.Post;
import net.pterodactylus.sone.data.PostReply;
+import com.google.common.base.Optional;
+
/**
* Simple {@link PostReply} implementation.
*
private final PostProvider postProvider;
/** The Post this reply refers to. */
- private volatile String postId;
+ private final String postId;
/**
* Creates a new reply.
*
+ * @param soneProvider
+ * The Sone provider
* @param postProvider
* The post provider
* @param id
* The ID of the reply
+ * @param soneId
+ * The ID of the Sone of the reply
+ * @param time
+ * The time of the reply
+ * @param text
+ * The text of the reply
+ * @param postId
+ * The ID of the post this reply refers to
*/
- public PostReplyImpl(PostProvider postProvider, String id) {
- super(id);
+ public PostReplyImpl(SoneProvider soneProvider, PostProvider postProvider, String id, String soneId, long time, String text, String postId) {
+ super(soneProvider, id, soneId, time, text);
this.postProvider = postProvider;
this.postId = postId;
}
//
/**
+ * {@inheritDocs}
+ */
+ @Override
+ public String getPostId() {
+ return postId;
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
- public Post getPost() {
+ public Optional<Post> getPost() {
return postProvider.getPost(postId);
}
- /**
- * Sets the post this reply refers to.
- *
- * @param postId
- * The ID of the post to reply to
- * @return This reply (for method chaining)
- */
- @Override
- public PostReply setPost(String postId) {
- this.postId = postId;
- return this;
- }
-
}